購入したばかりの曲を積極的に再生するための確率設定
音楽プレイヤーのランダム再生機能を実装する事を考えます
購入したばかりの曲はたくさん聞きたく、逆に1年以上も前に購入した曲であればたまに再生されれば良いかと思います
そこで購入日に比例して再生確率を決定する仕組みを作ります
素点の作成
確率を決定するために曲毎に素点を作成し、後ほど点数を確率に変換する手段を取ります
その計算式を以下の通りに設定
算出される最小値を 1/曲数 になるようにします
y = 1 - 経過日数 / 曲数
y > 1 / 曲数
1000曲、購入からの経過日数を最大を2000日とした時のプロットです
1000日経過まで徐々に素点が下がり1000日を超えたところで 1/1000 となります
この式で取得した素点を確率に変換し再生時の選択に反映させれば完成です
ソースコード
import matplotlib.pyplot as pyplot
import numpy as np
def coff_function(x, xmax, ymin):
y = 1 - x / xmax
if y < ymin:
y = ymin
return y
def test_plot():
xmax = 1000
ymin = 1 / xmax
x = []
y = []
for ix in range(xmax + 1000):
x.append(ix)
y.append(coff_function(ix, xmax, ymin))
pyplot.plot(x, y)
pyplot.savefig("test_plot.png")
def test1():
# 曲名, 購入日からの経過日数
music_list = [
["bloom", 7],
["ふざけてないぜ", 1],
["優しくなれたなら", 6],
["今日はカレーの日", 5],
["北上のススメ", 0],
["こんがらがった", 6],
["君はいなせなガール", 3],
]
#music_list = music_list * 10
xmax = len(music_list)
ymin = 1 / xmax
names = []
x = []
y = []
for v in music_list:
ix = v[1]
names.append(v[0])
x.append(ix)
y.append(coff_function(ix, xmax, ymin))
names = np.array(names)
x = np.array(x)
y = np.array(y)
idxs = np.argsort(y)
idxs = np.flip(idxs) # 確率の高い順番に並べたいので逆転する
names = names[idxs]
x = x[idxs]
y = y[idxs]
ysum = np.sum(y)
prob = y / ysum
#print(names)
#print(x)
#print(y)
#print(prob)
#print(np.sum(prob))
X = np.c_[names, prob * 100]
for ix in X:
print("{}\t{:.2f}%".format(ix[0], float(ix[1])))
def main():
#test_plot()
test1()
if __name__ == "__main__":
main()
出力
北上のススメ 31.82%
ふざけてないぜ 27.27%
君はいなせなガール 18.18%
今日はカレーの日 9.09%
こんがらがった 4.55%
優しくなれたなら 4.55%
bloom 4.55%
曲数が少ないためすぐに下限に達してしまうため偏りが酷いですが曲数を多くして経過日数のばらつきをもっと作るとそれっぽくなります
この確率に従い曲を選択し続ければ購入からの経過日数に比例してランダム再生が可能です
同じ曲を連続して再生はしないけど確率も考慮するとなると人の好みもありますので確率を良い具合に反映しつつ連続再生を防ぐのが難しいかなと思いました
以上です