杂谈·一个神一般的随机算法

杂谈·一个神一般的随机算法

——TechZone(Harris)


这篇文章,我们从一个经典的面试题开始讲起。这个题目,可能会有很多形式,但是背后的逻辑是一样的:如何写出一个公平的洗牌算法

洗牌嘛,不就是个随机算法吗?直接搞一个数组,把牌全部放进去,然后对调两张牌,随机k次即可。

你要敢这样回答,那面试官肯定会问,k取多少呢?

显然不能是个常量,如果你取10,000,如果只有100张牌,显然太多了,如果有100,000张呢?又太少了。

那你可能会想,让k随着牌的数量变化不就行了?嗯,的确,这个想法已经比刚刚的强很多了,但是你要敢这么回答,面试官多半会坏笑然后问你,你这个算法,公平吗?
再回去看看问题:如何写出一个公平的洗牌算法。

刚刚忙活了那么久,其实连问题的本质都没有触及。这题的关键,在于设计公平


一个面试官面试,往往看的不是你是否答对了问题,因为一道面试题,答案不只一种。如果你有对题目足够强的思维能力,你就是面试官要的人。如果你看到这道题,一开始就是从公平入手,那么你是很优秀的。因为背出一个算法很容易,但是这种探求问题根源的思维角度,绝不是一朝之功。这是一种不断面对问题,不断解决问题而逐渐锻炼出来的能力。


那么我们就来看看,对于这个算法,公平的定义是什么。

如果有n张牌,那么排序的可能性就是n!。我们可以生成所有的可能性,然后随机选一个。这种算法是绝对公平的。但是,复杂度太高。这个复杂度达到了O(n!)。因为我们需要计算n!种排列,那么就至少需要n!的时间。

有的同学可能对这样的复杂度不太感冒。这是一个比2^n还要高的复杂度。2^n是n个2相乘,而n!也是n个数,而这些数除了1比2小以外,其他的数都≥2。而2^n已经是指数爆炸了,在n≥4的时候,n!以极快的速度超越2^n

这个算法的确是公平的,但是时间不能允许


我们再换一种角度去思考公平的问题。公平其实也可以理解为,我们每一张牌出现在每一个位置的概率都相等。这个定义和上面提到的暴力算法其实是等价的,学过概率论的同学可以去证明下。根据这个定义,我们就可以很快写出一个简单的算法:

for (int i = n-1; i >= 0; i--)
    swap(arr[i], arr[rand() % (i +1)]);

说它简单,是因为就一层循环。

小伙伴们可以看看这个循环在干什么。其实就是将下标为i的元素,和一个随机下标的元素交换位置。而为了确保随机的数在[0,i]的范围内,我们用了取余运算除以(i+1)。

这个算法就是大名鼎鼎的 Knuth-Shuffle,即 Knuth 洗牌算法。

原理待会儿再讲,我们先来看看这个传奇般的人物。

中文名:高纳德。算法理论的创始人。我们现在所使用的各种算法复杂度分析的符号,就是他发明的。上世纪60-70年代计算机算法的黄金时期,近乎就是他一手主导的。他的成就实在是太多,一本书估计都写不完。

大家最津津乐道的,就是他所写的《The Art of Computer Programming 》,简称TAOCP 。这套书准备写七卷,然后,到今天还没有写完,但已经被《科学美国人》评为可以媲美相对论的巨著。微软还是IT界老大的时代,盖茨就说过,如果你看完了这套书的第一卷本,那你直接给我发简历

TAOCP

至于这套书为什么写这么慢,因为老头子当时写这本书,写到一半觉得时下的排版工具都太烂了,于是转手就发明了现在流行的LaTeX……

另外,他可能也觉得当时的所有编程语言都无法描述自己的思想,于是自己发明了一套抽象逻辑语言用于展示这套书的逻辑部分……

(感受到了和大佬的差距)

下面这句话,和大家共勉:

A programmer who subconsciously views himself as an artist will enjoy what he does and will do it better.
——Donald E. Knuth 1978


下面就来看看具体是怎么通过这样一个简单的算法来实现绝对公平的。

其实,可怕的地方,就在于太简单……
我们用5个数字来简单模拟下这个算法:

1 2 3 4 5

这个算法,会在5个元素中选出一个元素和最后一个元素交换。假设我们选择3。就变成这样:

1 2 5 4 3

那么这个3出现在最后的概率是多少呢?从5个里面挑嘛,那肯定是\frac{1}{5}嘛。

再选一个,假设选到了1,那么就变成这样:

4 2 5 1 3

这个1出现在这个位置的概率又是多少呢?

上面那一轮,1没被挑走,而这一轮里面挑走了。
\frac{4}{5}\times\frac{1}{4}=\frac{1}{5}
还是等于\frac{1}{5}

继续,假设这次是2。

4 5 2 1 3

概率依旧
\frac{4}{5}\times\frac{3}{4}\times\frac{1}{3}=\frac{1}{5}

假设下一个是4,那么

5 4 2 1 3

概率\frac{4}{5}\times\frac{3}{4}\times\frac{2}{3}\times\frac{1}{2}=\frac{1}{5}

而这样5就只能在第一个位置了,概率还是\frac{4}{5}\times\frac{3}{4}\times\frac{2}{3}\times\frac{1}{2}=\frac{1}{5}

大家看到了,自始至终,所有的位置出现的概率都是相等的,如果数组长度是n,那么每个位置的概率就是\frac{1}{n},而复杂度O(n),比O(n!)少了太多太多……

这个算法不仅仅可以用来洗牌,很多场景下的随机都可以使用。大家可以自己思考下,也可以运用于实际的解题甚至是开发之中。

其实大家应该有感觉了,算法绝对不是枯燥的逻辑堆砌,而是神一般的逻辑创造。这个世界也是如此,尽管极其复杂,变化万千,但又竟是如此简洁,巧妙而优雅……

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343