今天在做一個游戲需求的時候碰到一個問題,問題很簡單,給定75個球,編號1-75,需要保證初始化的時候位置是隨機的。
顯然,我們可以初始化一個數組A,把75個數放進去,然后做一個shuffle函數隨機交換其中的元素,這樣就是隨機的。
我準備這樣做一個shuffle,但同時也想看看golang里面是否有這樣的接口直接得到結果,看了下還真有,這個函數是rand.Perm(n),這個函數會返回一個數組,比如我傳入75,會返回一個0-74的隨機數組。
arr := rand.Perm(75)
好奇心驅使我一探究竟,golang會用什么樣的方式實現Perm函數呢?
打開golang的源代碼,在rand.go文件中找到這個函數:
實現很簡單,然而初一看有點懵,因為沒有用到shuffle,而是一次遍歷就把事情給解決了,到底是怎么回事?
仔細分析發現,這個算法非常精巧,每次遍歷都是將當前的數i和已經在數組中的隨機一個數m[j]進行交換,最終達到了公平隨機整個數組的作用。雖然只有短短3行代碼,卻讓人有種震撼的感覺。
頓時覺得golang很NB,確實很高效。
上面這段代碼寫了4行的注釋,大概意思是說不能省去0那一次,看起來沒啥用處,但是為了照顧r隨機器中的隨機序列,還是要加上,不然可能會造成負作用,這里面和隨機種子以及此后隨機的序列有關,為了對隨機序列不產生影響保證公平性,不能省略0。
網上搜索了一下高效洗牌算法,又發現python里面也有這樣的函數,這樣寫的:
for(int i = N - 1; i 》= 0 ; i -- )
swap(arr[i], arr[rand(0, i)]) // rand(0, i) 生成 [0, i] 之間的隨機整數
而這個算法的出處竟然來自于TAOCP!算法就是大名鼎鼎的 Knuth-Shuffle,即 Knuth 洗牌算法。
看似簡單的問題,竟然又扯出Knuth,大意了。
能把一件小事情做到極致的人,可以稱之為藝術家。Knuth名副其實。
最后以Knuth的一句話共勉:
A programmer who subconsciously views himself as an artist will enjoy what he does and will do it better.
Donald E. Knuth 1978
編輯:lyn
-
算法
+關注
關注
23文章
4630瀏覽量
93365 -
代碼
+關注
關注
30文章
4828瀏覽量
69063 -
Shuffle
+關注
關注
0文章
5瀏覽量
1709
原文標題:Knuth高效洗牌算法
文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數據結構】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
信道分配算法在通信中的應用
常見的加密算法有哪些?它們各自的優勢是什么?
【「從算法到電路—數字芯片算法的電路實現」閱讀體驗】+內容簡介
【「從算法到電路—數字芯片算法的電路實現」閱讀體驗】+介紹基礎硬件算法模塊
華納云:Chord算法如何管理節點間的聯系?
U盤存儲并聯,算法交互輸出
QC快充芯片,因高效而兼容性好而成為手機標配的充電解決方案!
無人機電力巡檢系統的功能淺析
![無人機電力巡檢系統的功能<b class='flag-5'>淺析</b>](https://file1.elecfans.com/web2/M00/FE/58/wKgaomaaKmyAdQRIAAH2eJn_H8M850.png)
充電也要算法?儲能充電芯片中的算法處理器
圖像識別算法的優缺點有哪些
BLDC電機控制算法詳解
常用的電機控制算法有哪些
淺析基于水廠云平臺的用電設備高效運行管理系統
![<b class='flag-5'>淺析</b>基于水廠云平臺的用電設備<b class='flag-5'>高效</b>運行管理系統](https://file1.elecfans.com//web2/M00/C2/39/wKgZomXhPWCAfGo8AAG5zVwYy34524.png)
評論