算法——音乐播发器中考虑已听次数的随机播放算法

背景

绝大多数音乐播放器的随机播放算法都采用洗牌算法(Shuffle),即将歌单中所有歌随机打乱顺序播放。但是考虑到用户在软件的使用过程中会不断往歌单中添加新的歌曲,在洗牌算法中无论新歌旧歌都会无差别地随机打乱,如此生成的随机列表没有照顾到用户想更多听新歌的想法。本文旨在提出能够在随机播放过程中考虑不同歌曲已听次数的随机播放算法。该算法应该有如下几条原则:

  1. 已听次数越低的歌应有越高的几率被播放;
  2. 杜绝某一首歌连续播放的情况(除非只有一首歌);
  3. 尽量避免某一首歌在短期内多次播放;
  4. 长时间没听过的歌应有一定的概率提升;

符号约定

N:歌曲总数,播放N首歌称为一个循环
D:歌单播放次数的方差
i:歌单中第i首歌
p[i]:选中概率,第i首歌下一次被选中的概率
h[i]:增益,第i首歌下一次被选中的概率的增益
H:总增益,P = sum(p[i])
t[i]:播放次数,第i首歌已经播放的次数
t_max:最高播放次数,t_max = max(t)
T:总播放次数,T = sum(t[i])
w[i]:等待次数,第i首歌距离上一次播放之间播放了的歌曲数,初始化w[i] = N
X:次数补偿

算法

1.补次算法

符合原则1。设置一个根据t_max计算的次数补偿X来对所有歌的播放概率进行补偿,高播放次数的歌得到的补偿小、低次数反之。一般令X = t_max + a,其中a >= 1,a越大补偿越小,伪代码如下:

X = max(t) + 1
for i in N:h[i] = X - t[i]
H = sum(h)
for i in N:p[i] = h[i]/H
chosen = random_choice(p)
t[chosen] += 1
play(chosen)
2.概率恢复算法

符合原则2、3、4。所有歌曲基础播放概率为1/N,某一首歌播放后将其播放概率清零,在其他歌播放的同时逐渐恢复其概率甚至提升到更高的水平。规定一个循环使得概率恢复到正常值,伪代码如下:

for i in N:h[i] = (1/N)*(w[i]/N)
H = sum(h)
for i in N:p[i]=h[i]/H
chosen = random_choice(p)
t[chosen] += 1
play(chosen)
for i in N:w[i] += 1
w[chosen] = 0
3.等次比优先算法

符合原则1、2、3、4。称一首歌的等待次数和播放次数之比为等次比r[i] = w[i] / t[i],可见w增大会使其提升、t增大会使其减小,以此作为增益是可以考虑的。伪代码如下:

for i in N:h[i] = w[i]/(t[i]+1)
H = sum(h)
for i in N:p[i]=h[i]/H
chosen = random_choice(p)
t[chosen] += 1
play(chosen)
for i in N:w[i] += 1
w[chosen] = 0
4.补次概率恢复算法

综合了补次和概率恢复算法,符合原则1、2、3、4 。以补次后的概率为基础,加以概率恢复算法,伪代码如下:

X = max(t) + 1
for i in N:h[i] = (X-t[i])*(w[i]/N)
H = sum(h)
for i in N:p[i]=h[i]/H
chosen = random_choice(p)
t[chosen] += 1
play(chosen)
for i in N:w[i] += 1
w[chosen] = 0

性能

以下测试了同一初始状态下播放200首歌的纯随机算法、等次比、补次概率恢复算法的性能。
算法性能可以看见等次比和补次概率恢复算法都能在满足原则1、2、3、4的情况下有效降低方差D。

猜你喜欢

转载自blog.csdn.net/Eyizoha/article/details/89376885
今日推荐