【算法】—— 随机音乐的播放算法

随机播放音乐,这个功能太普通以至于以前从未考虑过其背后实现逻辑。

Random还是shuffle

我们经常使用的随机播放功能,在外国同行口中并不是叫Random播放,而是叫Shuffle,洗牌的意思。

为什么不是Random?来看两个例子。

在Spotify成立之初,他们使用一种叫「Fisher-Yates shuffle」的算法去产生一个完全随机(perfectly random )的播放列表,这个算法据说非常简单,只需3行代码搞定,不过它存在致命弱点。

上图中,每种颜色代表一位歌手,也就是说我的列表里有绿色歌手的4首歌,红色歌手的2首歌,黑色歌手的2首歌。

图中上下两行都是运行Fisher-Yates算法可能产生的播放列表,请问这两个列表出现的概率哪个更大呢?

答案是一样大,完全随机算法下,每一首歌出现在每个位置的概率是一样的。你可能认为这怎么可能,前面已经出现3次绿色歌手的歌了,下一次出现概率应该很小了吧。错了,算法是没有记忆的,除非你告诉它,下一首不允许播放绿色歌手的歌,否则它播放绿色歌手的歌的概率还是50%。

再来看个例子,假设你播放列表里有10首摇滚乐(A),11首乡村乐(B),11首爵士乐(C),下面是我自己用Python的random函数生成的序列:

A A A A C C C B C B B A C B C B B B B A B C B A C A C C A A C B

可以看出,这个列表里前半段和后半段基本上没有B出现,尤其是前面连续4个A和3个B,这样的结果是无法令人满意的,一点均衡性都没有。

回头再想,我们为什么要随机播放?因为我们不知道要听什么,我们想要一个随性的播放列表,我们不想专门听某一位歌手的或某一张专辑的曲目,我们不想按照平常循环的顺序播放,我们想换换口味有点新意,所以我们把这个选择权交给软件本身去做,如果软件接连给你播放同一个歌手或同一张专辑的曲目,那就违背我们随机的目的了。所以好的随机播放列表应该做到均衡分布,同一个流派、同一个歌手、同一种专辑下的音乐彼此之间相距越远越好。

还是上面这个例子,好的播放列表应该是下面这样的:

A B C B C A B A C B A C B C A B C A C B A B C A C B A C B C A B

shuffle播放算法

那么如何生成上面这个均衡的播放列表呢?博主Martin Fiedler给了一个思路。

1)将列表中的歌曲按流派、歌手、专辑等逻辑范式分组,给这个组里的音乐设定一个随机播放顺序;
2)接下来把每个分组的曲目通过合并算法组成一个完整的播放列表。

很简单吧,仅仅两步而已。接下来看看合并算法是怎么一回事。假设在第一步我们得到了下面的分组:

将每个分组扩充到和最大分组相等的长度,比如给绿色分组填充8首「静默」歌曲,让该组长度等于12。填充的时候应尽量让组中的音乐均衡分布列表中。

每个分组都填充完毕后,就开始合并新列表了,从每个分组的第1列按随机顺序取出歌曲放在新列表中。

再取出第2列按随机顺序取出歌曲放在新列表中。

第3列。需要注意的是,假如第2次取出的是黄-红-蓝,第3次取出蓝-黄-红-绿,那么就会有两个蓝色分组的歌曲接连出现的情况,这个时候需要把第3次拿出的歌曲首尾互换,最后得出绿-黄-红-蓝的顺序。

就是shuffle播放背后的大概逻辑了,难的不是合并算法,而是填充分组的算法,个人感觉。

原文地址:https://www.cnblogs.com/bopo/p/9263007.html

时间: 2024-10-11 22:10:59

【算法】—— 随机音乐的播放算法的相关文章

HDU2138 随机素数测试 Miller-Rabin算法

题目描述 Give you a lot of positive integers, just to find out how many prime numbers there are.. In each case, there is an integer N representing the number of integers to find. Each integer won’t exceed 32-bit signed integer, and each of them won’t be

音乐旋律提取算法 附可执行demo

前面提及过,音频指纹算法的思路. 也梳理开源了两个比较经典的算法. https://github.com/cpuimage/shazam https://github.com/cpuimage/AudioFingerprinter 后来一段时间,稍微看了下这两个算法,还有不少可以精简优化的空间. 例如抗噪,特征有效性等优化思路. 音频指纹切片后的hash特征信息还是太多了, 不过作为哼唱搜歌的基本应用,是足够的了. 不过我觉得还是可以再进一步提取歌曲的旋律特征的,在音频指纹的基础上更进一步. 旋

算法面试课程笔记001 算法面试到底是什么鬼

算法面试课程笔记001算法面试到底是什么鬼 =============================================================================== 本文地址 : =============================================================================== 算法面试是什么? 让大家在面对面试中的算法问题时,有一个合理的思考路径: ·不代表能够"正确"回答每一个算法问题

基本算法研究1-冒泡排序算法测试

基本算法研究1-冒泡排序算法测试 1.经典冒泡排序法基本原理 先看一个动态图,感觉比较形象: 冒泡排序(Bubble Sort)是一种简单的排序算法.默认是从小到大排序,即把最大的数据排在最后,相当于每次把最大数据像气泡一样浮到水面一样.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换. 基本步骤: 1.比较相邻的元素.如果第一个比第二个大,就交换他们两个.        2.对每一对相邻元素作同样的工作,从开始第一对

【机器学习算法-python实现】采样算法的简单实现

1.背景 采样算法是机器学习中比较常用,也比较容易实现的(出去分层采样).常用的采样算法有以下几种(来自百度知道): 一.单纯随机抽样(simple random sampling) 将调查总体全部观察单位编号,再用抽签法或随机数字表随机抽取部分观察单位组成样本. 优点:操作简单,均数.率及相应的标准误计算简单. 缺点:总体较大时,难以一一编号. 二.系统抽样(systematic sampling) 又称机械抽样.等距抽样,即先将总体的观察单位按某一顺序号分成n个部分,再从第一部分随机抽取第k

《算法之道》精华 算法设计部分

<算法之道>精华 算法设计部分 本书作者邹恒明,作者另有一本书<数据结构之弦>,以及<操作系统之哲学原理>都是非常好的书 这本书能够算得上是深入浅出.文笔非常好,作者加入了非常多自己的思考 本文仅包含算法设计部分,算法分析略去,并没有严格依照章节顺序来记录 附录 算法随想 有人喜欢遍历,希望踏遍千山万水,人生丰富多彩:有人一生贪婪,眼界不宽,及时行乐:有人注定穷搜,辛辛苦苦,收获有限:有人善用时空均衡,用最少的时间办最多的事情.十分精明:有人会分治,再难的问题也能解决.

分布算法之一致性哈希算法

h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child { margin-top: 0; padding-top: 0; } a:first-child h1, a:first-child h2, a:first-child h3, a:fi

算法9-4:最大流算法复杂度分析

前面一节介绍了Ford-Fulkerson算法.那么这个算法是否一定能够在有限步骤内结束?要多少步骤呢? 这个问题的答案是,该算法确实能够在有限步骤之内结束,但是至于需要多少步骤,就要仔细分析. 为了分析问题,需要假定图中所有边的容量都是整数.但是有个严重的问题,比如下图中,如果使用Ford-Fulkerson算法,需要迭代200次才能结束. 首先将所有边的容量都初始化为0. 第一次迭代和第二次迭代之后,两条边各增加了1. 到最后200次迭代之后整个算法才结束. 这还不算最坏的情况.因为整数最多

scikit-learn学习之K-means聚类算法与 Mini Batch K-Means算法

====================================================================== 本系列博客主要参考 Scikit-Learn 官方网站上的每一个算法进行,并进行部分翻译,如有错误,请大家指正 转载请注明出处 ====================================================================== K-means算法分析与Python代码实现请参考之前的两篇博客: <机器学习实战>k