Knuth高效洗牌算法的示例分析,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
成都創(chuàng)新互聯(lián)專業(yè)成都網(wǎng)站建設(shè)、網(wǎng)站制作,集網(wǎng)站策劃、網(wǎng)站設(shè)計、網(wǎng)站制作于一體,網(wǎng)站seo、網(wǎng)站優(yōu)化、網(wǎng)站營銷、軟文營銷等專業(yè)人才根據(jù)搜索規(guī)律編程設(shè)計,讓網(wǎng)站在運行后,在搜索中有好的表現(xiàn),專業(yè)設(shè)計制作為您帶來效益的網(wǎng)站!讓網(wǎng)站建設(shè)為您創(chuàng)造效益。
今天在做一個游戲需求的時候碰到一個問題,問題很簡單,給定75個球,編號1-75,需要保證初始化的時候位置是隨機的。
顯然,我們可以初始化一個數(shù)組A,把75個數(shù)放進去,然后做一個shuffle函數(shù)隨機交換其中的元素,這樣就是隨機的。
我準備這樣做一個shuffle,但同時也想看看golang里面是否有這樣的接口直接得到結(jié)果,看了下還真有,這個函數(shù)是rand.Perm(n),這個函數(shù)會返回一個數(shù)組,比如我傳入75,會返回一個0-74的隨機數(shù)組。
arr := rand.Perm(75)
好奇心驅(qū)使我一探究竟,golang會用什么樣的方式實現(xiàn)Perm函數(shù)呢?
打開golang的源代碼,在rand.go文件中找到這個函數(shù):
實現(xiàn)很簡單,然而初一看有點懵,因為沒有用到shuffle,而是一次遍歷就把事情給解決了,到底是怎么回事?
仔細分析發(fā)現(xiàn),這個算法非常精巧,每次遍歷都是將當前的數(shù)i和已經(jīng)在數(shù)組中的隨機一個數(shù)m[j]進行交換,最終達到了公平隨機整個數(shù)組的作用。雖然只有短短3行代碼,卻讓人有種震撼的感覺。
頓時覺得golang很NB,確實很高效。
上面這段代碼寫了4行的注釋,大概意思是說不能省去0那一次,看起來沒啥用處,但是為了照顧r隨機器中的隨機序列,還是要加上,不然可能會造成負作用,這里面和隨機種子以及此后隨機的序列有關(guān),為了對隨機序列不產(chǎn)生影響保證公平性,不能省略0。
網(wǎng)上搜索了一下高效洗牌算法,又發(fā)現(xiàn)python里面也有這樣的函數(shù),這樣寫的:
for(int i = N - 1; i >= 0 ; i -- )
swap(arr[i], arr[rand(0, i)]) // rand(0, i) 生成 [0, i] 之間的隨機整數(shù)
而這個算法的出處竟然來自于TAOCP!算法就是大名鼎鼎的 Knuth-Shuffle,即 Knuth 洗牌算法。
看似簡單的問題,竟然又扯出Knuth,大意了。
能把一件小事情做到極致的人,可以稱之為藝術(shù)家。Knuth名副其實。
最后以 Knuth 的一句話共勉:
A programmer who subconsciously views himself as an artist will enjoy what he does and will do it better.
看完上述內(nèi)容,你們掌握Knuth高效洗牌算法的示例分析的方法了嗎?如果還想學到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!