Nim遊戲的概述:算法
還記得這個遊戲嗎?
給出n列珍珠,兩人輪流取珍珠,每次在某一列中取至少1顆珍珠,但不能在兩列中取。最後拿光珍珠的人輸。
後來,在一份資料上看到,這種遊戲稱爲「拈(Nim)」。聽說,它源自中國,經由被販賣到美洲的奴工們外傳。辛苦的工人們,在工做閒暇之餘,用石頭玩遊戲以排遣寂寞。後來流傳到高級人士,則用便士(Pennies),在酒吧櫃檯上玩。
最有名的玩法,是把十二枚便士放成三、四、5三列,拿光銅板的人贏。後來,你們發現,先取的人只要在3那列裏取走2枚,變成了一、四、5,就能穩操勝券了,遊戲也就變得無趣了。因而你們就增長列數,增長銅板的數量,這樣就讓人們有了毫無規律的感受,不易於把握。
直到本世紀初,哈佛大學數學系副教授查理士•理昂納德•包頓(Chales Leonard Bouton)提出一篇極詳盡的分析和證實,利用數的二進制表示法,解答了這個遊戲的通常法則。
通常規則是規定拿光銅板的人贏。
它的變體是規定拿光銅板的人輸,只要注意某種特殊形態(只有1列不爲1),就能夠了!
有不少人把這個方法寫成計算機程序,來和人對抗,不知就理的人被騙得團團轉,無不驚歎計算機的神奇偉大。其實說穿了,只由於它計算比人快,數的轉化爲二進制其速度快得非人能比,如此罷了。
(以上來自K12教育論壇)dom
Nim遊戲的數學理論論述:post
Nim遊戲是博弈論中最經典的模型,它又有着十分簡單的規則和無比優美的結論
Nim遊戲是組合遊戲(Combinatorial Games)的一種,準確來講,屬於「Impartial Combinatorial Games」(如下簡稱ICG)。知足如下條件的遊戲是ICG(可能不太嚴謹):一、有兩名選手;二、兩名選手交替對遊戲進行移動(move),每次一步,選手能夠在(通常而言)有限的合法移動集合中任選一種進行移動;三、對於遊戲的任何一種可能的局面,合法的移動集合只取決於這個局面自己,不取決於輪到哪名選手操做、之前的任何操做、骰子的點數或者其它什麼因素; 四、若是輪到某名選手移動,且這個局面的合法的移動集合爲空(也就是說此時沒法進行移動),則這名選手負。根據這個定義,不少平常的遊戲並不是ICG。例如象棋就不知足條件3,由於紅方只能移動紅子,黑方只能移動黑子,合法的移動集合取決於輪到哪名選手操做。
一般的Nim遊戲的定義是這樣的:有若干堆石子,每堆石子的數量都是有限的,合法的移動是「選擇一堆石子並拿走若干顆(不能不拿)」,若是輪到某我的時全部的石子堆都已經被拿空了,則判負(由於他此刻沒有任何合法的移動)。
這遊戲看上去有點複雜,先從簡單狀況開始研究吧。若是輪到你的時候,只剩下一堆石子,那麼此時的必勝策略確定是把這堆石子所有拿完一顆也不給對手剩,而後對手就輸了。若是剩下兩堆不相等的石子,必勝策略是經過取多的一堆的石子將兩堆石子變得相等,之後若是對手在某一堆裏拿若干顆,你就能夠在另外一堆中拿一樣多的顆數,直至勝利。若是你面對的是兩堆相等的石子,那麼此時你是沒有任何須勝策略的,反而對手能夠遵循上面的策略保證必勝。若是是三堆石子……好像已經很難分析了,看來咱們必需要藉助一些其它好用的(最好是程式化的)分析方法了,或者說,咱們最好可以設計出一種在有必勝策略時就能找到必勝策略的算法。
定義P-position和N-position,其中P表明Previous,N表明Next。直觀的說,上一次move的人有必勝策略的局面是P-position,也就是「後手可保證必勝」或者「先手必敗」,如今輪到move的人有必勝策略的局面是N-position,也就是「先手可保證必勝」。更嚴謹的定義是:1.沒法進行任何移動的局面(也就是terminal position)是P-position;2.能夠移動到P-position的局面是N-position;3.全部移動都致使N-position的局面是P-position。
按照這個定義,若是局面不可能重現,或者說positions的集合能夠進行拓撲排序,那麼每一個position或者是P-position或者是N-position,並且能夠經過定義計算出來。
以Nim遊戲爲例來進行一下計算。好比說我剛纔說當只有兩堆石子且兩堆石子數量相等時後手有必勝策略,也就是這是一個P-position,下面咱們依靠定義證實一下(3,3)是一個P是一個P是一個P-position。首先(3,3)的子局面(也就是經過合法移動能夠致使的局面)有(0,3)(1,3)(2,3)(顯然交換石子堆的位置不影響其性質,因此把(x,y)和(y,x)當作同一種局面),只須要計算出這三種局面的性質就能夠了。 (0,3)的子局面有(0,0)、(0,1)、(0,2),其中(0,0)顯然是P-position,因此(0,3)是N-position(只要找到一個是P-position的子局面就能說明是N-position)。(1,3)的後繼中(1,1)是P-position(由於(1,1)的惟一子局面(0,1)是N-position),因此(1,3)也是N-position。一樣能夠證實(2,3)是N-position。因此(3,3)的全部子局面都是N-position,它就是P-position。經過一點簡單的數學概括,能夠嚴格的證實「有兩堆石子時的局面是P-position當且僅當這兩堆石子的數目相等」。
根據上面這個過程,能夠獲得一個遞歸的算法——對於當前的局面,遞歸計算它的全部子局面的性質,若是存在某個子局面是P-position,那麼向這個子局面的移動就是必勝策略。固然,可能你已經敏銳地看出有大量的重疊子問題,因此能夠用DP或者記憶化搜索的方法以提升效率。但問題是,利用這個算法,對於某個Nim遊戲的局面(a1,a2,...,an)來講,要想判斷它的性質以及找出必勝策略,須要計算O(a1*a2*...*an)個局面的性質,無論怎樣記憶化都沒法下降這個時間複雜度。因此咱們須要更高效的判斷Nim遊戲的局面的性質的方法。
直接說結論好了。spa
(Bouton's Theorem):對於一個Nim遊戲的局面(a1,a2,...,an),它是P-position當且僅當a1^a2^...^an=0,其中^表示異或(xor)運算。設計
怎麼樣,是否是很神奇?我看到它的時候也以爲很神奇,徹底沒有道理的和異或運算扯上了關係。但這個定理的證實卻也不復雜,基本上就是按照兩種position的證實來的。
根據定義,證實一種判斷position的性質的方法的正確性,只需證實三個命題: 一、這個判斷將全部terminal position判爲P-position;二、根據這個判斷被判爲N-position的局面必定能夠移動到某個P-position;三、根據這個判斷被判爲P-position的局面沒法移動到某個P-position。
第一個命題顯然,terminal position只有一個,就是全0,異或仍然是0。
第二個命題,對於某個局面(a1,a2,...,an),若a1^a2^...^an!=0,必定存在某個合法的移動,將ai改變成ai'後知足a1^a2^...^ai'^...^an=0。不妨設a1^a2^...^an=k,則必定存在某個ai,它的二進制表示在k的最高位上是1(不然k的最高位那個1是怎麼獲得的)。這時ai^k<ai必定成立。則咱們能夠將ai改變成ai'=ai^k,此時a1^a2^...^ai'^...^an=a1^a2^...^an^k=0。
第三個命題,對於某個局面(a1,a2,...,an),若a1^a2^...^an=0,必定不存在某個合法的移動,將ai改變成ai'後知足a1^a2^...^ai'^...^an=0。由於異或運算知足消去率,由a1^a2^...^an=a1^a2^...^ai'^...^an能夠獲得ai=ai'。因此將ai改變成ai'不是一個合法的移動。證畢。
根據這個定理,咱們能夠在O(n)的時間內判斷一個Nim的局面的性質,且若是它是N-position,也能夠在O(n)的時間內找到全部的必勝策略。Nim問題就這樣基本上完美的解決了。orm
(以上來自百度百科)blog
Nim遊戲的形象具體論述:排序
as + bs + … + ms 是偶數
a1 + b1 + … + m1 是偶數
a0 + b0 + … + m0是偶數
23 = 8 |
22 = 4 |
21 = 2 |
20 = 1 |
|
大小爲7的堆
|
0
|
1
|
1
|
1
|
大小爲9的堆
|
1
|
0
|
0
|
1
|
大小爲12的堆
|
1
|
1
|
0
|
0
|
大小爲15的堆
|
1
|
1
|
1
|
1
|
23 = 8 |
22 = 4 |
21 = 2 |
20 = 1 |
|
大小爲7的堆
|
0
|
1
|
1
|
1
|
大小爲9的堆
|
1
|
0
|
0
|
1
|
大小爲12的堆
|
0
|
0
|
0
|
1
|
大小爲15的堆
|
1
|
1
|
1
|
1
|
歸根結底,Nim取子游戲的關鍵在於遊戲開始時遊戲處於何種狀態(平衡或非平衡)和第一個遊戲人是否可以按照取子游戲的獲勝策略來進行遊戲。
(以上轉自Rainco_shnu的百度空間)
下面寫點本身的東西:
若是Nim遊戲中的規則稍微變更一下,每次最多隻能取K個,怎麼處理?
方法是將每堆石子數mod (k+1).