如何生成均勻隨機(jī)排列(等概率生成排列)
這個(gè)算法的應(yīng)用,比如洗牌,這個(gè)大家都非常熟悉。很久以前用的是最原始的方法,就是一直rand()未出現(xiàn)的牌,直至生成所有的牌。這當(dāng)然是一個(gè)while(1)循環(huán),很爛的算法吧。后面聽(tīng)說(shuō)直接交換牌,打亂即可了。但是打亂后生成的排列是隨機(jī)的么,是等可能隨機(jī)的么。
其實(shí),這個(gè)問(wèn)題上算法導(dǎo)論上早已經(jīng)有了答案了,看過(guò)算法導(dǎo)論之后覺(jué)得沒(méi)看之前真的是算法修養(yǎng)太差了。
算法的偽代碼如下圖所示:

具體c++實(shí)現(xiàn)如下:
#include <stdio.h>
運(yùn)行效果圖片如下:

根據(jù)運(yùn)行結(jié)果大致就可以感覺(jué)到,生成的排列都是隨機(jī)的。
這里要多說(shuō)一句那就是我注釋的那個(gè)交換函數(shù)其實(shí)是有bug的,也許這才是不提倡使用這個(gè)交換方法的真正原因,而不僅僅是
難以理解。用同一個(gè)變量去調(diào)用該函數(shù),會(huì)將該變量置0,而不是保持原來(lái)的值!!!
至于如何證明這個(gè)算法生成的均勻隨機(jī)的排列,可以參考算法導(dǎo)論5.3節(jié)最后一部分。
證明的大致思路是利用循環(huán)不變式的證明方法:證明i次循環(huán)后得到某個(gè)排列的概論是(n -i)! / n!,那么n次循環(huán)后得到最終那個(gè)排列的
概論就是1/n!,這樣就證明了該算法能夠得到均勻隨機(jī)排列。
這個(gè)算法其實(shí)就是隨機(jī)化算法的一種,其實(shí)快排也有所謂的隨機(jī)化版本,改動(dòng)的地方只是隨機(jī)選擇了中軸元素而已,這個(gè)
在算法導(dǎo)論上也有介紹。
posted on 2012-02-26 16:07 yx 閱讀(3395) 評(píng)論(8) 編輯 收藏 引用 所屬分類(lèi): 隨機(jī)算法