nim 博弈

博弈論(一):Nim遊戲

重點結論:對於一個Nim遊戲的局面(a1,a2,...,an),它是P-position當且僅當a1^a2^...^an=0,其中^表示位異或(xor)運算。

Nim遊戲是博弈論中最經典的模型(之一?),它又有着十分簡單的規則和無比優美的結論,由這個遊戲開始瞭解博弈論恐怕是最合適不過了。

Nim遊戲是組合遊戲(Combinatorial Games)的一種,準確來說,屬於“Impartial Combinatorial Games”(以下簡稱ICG)。滿足以下條件的遊戲是ICG(可能不太嚴謹):1、有兩名選手;2、兩名選手交替對遊戲進行移動(move),每次一步,選手可以在(一般而言)有限的合法移動集合中任選一種進行移動;3、對於遊戲的任何一種可能的局面,合法的移動集合只取決於這個局面本身,不取決於輪到哪名選手操作、以前的任何操作、骰子的點數或者其它什麼因素; 4、如果輪到某名選手移動,且這個局面的合法的移動集合爲空(也就是說此時無法進行移動),則這名選手負。根據這個定義,很多日常的遊戲並非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遊戲的局面的性質的方法。

直接說結論好了。(Bouton's Theorem)對於一個Nim遊戲的局面(a1,a2,...,an),它是P-position當且僅當a1^a2^...^an=0,其中^表示異或(xor)運算。怎麼樣,是不是很神奇?我看到它的時候也覺得很神奇,完全沒有道理的和異或運算扯上了關係。但這個定理的證明卻也不復雜,基本上就是按照兩種position的證明來的。

根據定義,證明一種判斷position的性質的方法的正確性,只需證明三個命題: 1、這個判斷將所有terminal position判爲P-position;2、根據這個判斷被判爲N-position的局面一定可以移動到某個P-position;3、根據這個判斷被判爲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問題就這樣基本上完美的解決了。


博弈論(二):Sprague-Grundy函數

上一期的文章裏我們仔細研究了Nim遊戲,並且瞭解了找出必勝策略的方法。但如果把Nim的規則略加改變,你還能很快找出必勝策略嗎?比如說:有n堆石子,每次可以從第1堆石子裏取1顆、2顆或3顆,可以從第2堆石子裏取奇數顆,可以從第3堆及以後石子裏取任意顆……這時看上去問題複雜了很多,但相信你如果掌握了本節的內容,類似的千變萬化的問題都是不成問題的。

現在我們來研究一個看上去似乎更爲一般的遊戲:給定一個有向無環圖和一個起始頂點上的一枚棋子,兩名選手交替的將這枚棋子沿有向邊進行移動,無法移動者判負。事實上,這個遊戲可以認爲是所有Impartial Combinatorial Games的抽象模型。也就是說,任何一個ICG都可以通過把每個局面看成一個頂點,對每個局面和它的子局面連一條有向邊來抽象成這個“有向圖遊戲”。下面我們就在有向無環圖的頂點上定義Sprague-Garundy函數。

首先定義mex(minimal excludant)運算,這是施加於一個集合的運算,表示最小的不屬於這個集合的非負整數。例如mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。

對於一個給定的有向無環圖,定義關於圖的每個頂點的Sprague-Garundy函數g如下:g(x)=mex{ g(y) | y是x的後繼 }。

來看一下SG函數的性質。首先,所有的terminal position所對應的頂點,也就是沒有出邊的頂點,其SG值爲0,因爲它的後繼集合是空集。然後對於一個g(x)=0的頂點x,它的所有後繼y都滿足g(y)!=0。對於一個g(x)!=0的頂點,必定存在一個後繼y滿足g(y)=0。

以上這三句話表明,頂點x所代表的postion是P-position當且僅當g(x)=0(跟P-positioin/N-position的定義的那三句話是完全對應的)。我們通過計算有向無環圖的每個頂點的SG值,就可以對每種局面找到必勝策略了。但SG函數的用途遠沒有這樣簡單。如果將有向圖遊戲變複雜一點,比如說,有向圖上並不是只有一枚棋子,而是有n枚棋子,每次可以任選一顆進行移動,這時,怎樣找到必勝策略呢?

讓我們再來考慮一下頂點的SG值的意義。當g(x)=k時,表明對於任意一個0<=i<k,都存在x的一個後繼y滿足g(y)=i。也就是說,當某枚棋子的SG值是k時,我們可以把它變成0、變成1、……、變成k-1,但絕對不能保持k不變。不知道你能不能根據這個聯想到Nim遊戲,Nim遊戲的規則就是:每次選擇一堆數量爲k的石子,可以把它變成0、變成1、……、變成k-1,但絕對不能保持k不變。這表明,如果將n枚棋子所在的頂點的SG值看作n堆相應數量的石子,那麼這個Nim遊戲的每個必勝策略都對應於原來這n枚棋子的必勝策略!

對於n個棋子,設它們對應的頂點的SG值分別爲(a1,a2,...,an),再設局面(a1,a2,...,an)時的Nim遊戲的一種必勝策略是把ai變成k,那麼原遊戲的一種必勝策略就是把第i枚棋子移動到一個SG值爲k的頂點。這聽上去有點過於神奇——怎麼繞了一圈又回到Nim遊戲上了。

其實我們還是隻要證明這種多棋子的有向圖遊戲的局面是P-position當且僅當所有棋子所在的位置的SG函數的異或爲0。這個證明與上節的Bouton's Theorem幾乎是完全相同的,只需要適當的改幾個名詞就行了。

剛纔,我爲了使問題看上去更容易一些,認爲n枚棋子是在一個有向圖上移動。但如果不是在一個有向圖上,而是每個棋子在一個有向圖上,每次可以任選一個棋子(也就是任選一個有向圖)進行移動,這樣也不會給結論帶來任何變化。

所以我們可以定義有向圖遊戲的和(Sum of Graph Games):設G1、G2、……、Gn是n個有向圖遊戲,定義遊戲G是G1、G2、……、Gn的和(Sum),遊戲G的移動規則是:任選一個子遊戲Gi並移動上面的棋子。Sprague-Grundy Theorem就是:g(G)=g(G1)^g(G2)^...^g(Gn)。也就是說,遊戲的和的SG函數值是它的所有子游戲的SG函數值的異或。

再考慮在本文一開頭的一句話:任何一個ICG都可以抽象成一個有向圖遊戲。所以“SG函數”和“遊戲的和”的概念就不是侷限於有向圖遊戲。我們給每個ICG的每個position定義SG值,也可以定義n個ICG的和。所以說當我們面對由n個遊戲組合成的一個遊戲時,只需對於每個遊戲找出求它的每個局面的SG值的方法,就可以把這些SG值全部看成Nim的石子堆,然後依照找Nim的必勝策略的方法來找這個遊戲的必勝策略了!

回到本文開頭的問題。有n堆石子,每次可以從第1堆石子裏取1顆、2顆或3顆,可以從第2堆石子裏取奇數顆,可以從第3堆及以後石子裏取任意顆……我們可以把它看作3個子遊戲,第1個子遊戲只有一堆石子,每次可以取1、2、3顆,很容易看出x顆石子的局面的SG值是x%4。第2個子遊戲也是隻有一堆石子,每次可以取奇數顆,經過簡單的畫圖可以知道這個遊戲有x顆石子時的SG值是x%2。第3個遊戲有n-2堆石子,就是一個Nim遊戲。對於原遊戲的每個局面,把三個子游戲的SG值異或一下就得到了整個遊戲的SG值,然後就可以根據這個SG值判斷是否有必勝策略以及做出決策了。其實看作3個子遊戲還是保守了些,乾脆看作n個子遊戲,其中第1、2個子遊戲如上所述,第3個及以後的子游戲都是“1堆石子,每次取幾顆都可以”,稱爲“任取石子游戲”,這個超簡單的遊戲有x顆石子的SG值顯然就是x。其實,n堆石子的Nim遊戲本身不就是n個“任取石子游戲”的和嗎?

所以,對於我們來說,SG函數與“遊戲的和”的概念不是讓我們去組合、製造稀奇古怪的遊戲,而是把遇到的看上去有些複雜的遊戲試圖分成若干個子游戲,對於每個比原遊戲簡化很多的子游戲找出它的SG函數,然後全部異或起來就得到了原遊戲的SG函數,就可以解決原遊戲了。這種“分而治之”的思想在下一節介紹的“翻硬幣遊戲”中將被應用得淋漓盡致。還是敬請期待。


Game theory初步

遊戲1
l    有兩個遊戲者:A和B。
l    有21顆石子。
l    兩人輪流取走石子,每次可取1、2或3顆。
l    A先取。
l    取走最後一顆石子的人獲勝,即沒有石子可取的人算輸。
如果剩下1、2或3顆石子,那麼接下來取的人就能獲勝;如果剩下4顆,那麼無論接下來的人怎麼取,都會出現前面這種情況,所以接下來取的人一定會輸;如果剩下5、6或7顆石子,那麼接下來取的人只要使得剩下4顆石子,他就能獲勝。0,4,8,12,……都是下一個取石子者的必敗狀態。現在有21顆石子,21除以4的餘數是1,所以先走者有必勝的策略,他第一次只要取走1顆石子,以後每一次都保證剩下的石子是4的倍數就行了。

什麼是“平等組合遊戲”?
l    兩人遊戲。
l    有一個狀態集,而且通常是有限的。
l    規定哪些狀態轉移是允許的。
l    所有規定對於兩人來說是一樣的。
l    兩人輪流走步。
l    有一個終止狀態,到達終止狀態後遊戲即告終止。
l    遊戲可以在有限步內終止。

P狀態和N狀態
就像第一個遊戲一樣,狀態0,4,8,……是剛纔走步的人的必勝狀態,我們稱之爲P狀態;而1,2,3,5,6,7,……都是下一個走步的人的必勝狀態,我們稱之爲N狀態。
我們可以從終止狀態出發,推出每一個狀態,指出它是P狀態還是N狀態。就拿第一個遊戲舉例:
步驟一 將所有終止狀態設爲P狀態。
步驟二 將所有一步之內可以到達一個P狀態的狀態設爲N狀態。
步驟三 如果一個狀態,不管怎麼走都只能走到N狀態,那麼就將這個狀態設爲P狀態。
步驟四 返回步驟二。
如果能夠走到P狀態,就能獲勝。因爲安照上面的定義,對手不管如何選擇,只可能走到N狀態。接下來總存在一個P狀態你可以走到。這樣一直走到終止狀態,你獲勝。當然這裏所說得都是指對於最後走步的人獲勝的遊戲。

我們嚴格的來定義P狀態和N狀態
l    所有的終止狀態都是P狀態;
l    對於任何的N狀態,肯定存在一種方式可以一步轉到一個P狀態;
l    對於任何的P狀態,不管怎麼走步,都只能轉到N狀態。
而對於最後走步的人失敗的遊戲,只要將所有終止狀態改成N狀態,然後開始倒推就可以了。當然,必勝狀態是N狀態。也就是說,如果想勝利,就希望面對N狀態,轉移到P狀態。

現在對遊戲1略微擴展一下。
有一個決策集S,S中的元素是正整數。遊戲的規則大致與遊戲1一樣,只是現在每次可以取的石子數必須是S中的元素。如果S={1,2,3},那麼就是遊戲1。
大家分析一下,當S={1,3,4}的時候,哪些狀態是P狀態,哪些是N狀態。
我們發現P狀態是{0,2,7,9,14,16,……},N狀態是{1,3,4,5,6,8,10,……}。
規律是如果n除以7的餘數是0或2,那麼狀態n就是P狀態,否則就是N狀態。
如果遊戲開始時,石子總數是100,那麼這是一個P狀態,也就是說後走的人有必勝策略。


遊戲2 Nim遊戲
有三堆石子,分別含有x1,x2和x3顆石子。兩人輪流取石子,每次可以選擇一堆,從這堆裏取走任意多顆石子,但不能不取。取走最後一顆石子的人獲勝。

我們用三元組來表示狀態,很明顯(0, 0, 0)是唯一的終止狀態,是P狀態。
先考慮只剩一堆有石子的情況(0, 0, x),很明顯這是,這些狀態都是N狀態。
剩兩堆的情況,如果兩堆的石子數相等(0, x, x),那麼這些都是P狀態。因爲下一次走步的人一定會使得兩堆石子不相等,再下一次可以使得兩堆的石子數回到相等的狀態,包括終止狀態。如果兩堆的石子數不相等,那麼就是N狀態。
三堆都非空的情況就複雜得多。我們可以得到(1, 1, 1)、(1, 1, 2)、(1, 1, 3)和(1, 2, 2)都是N狀態,因爲它們可以轉變成(0, 1, 1)或(0, 2, 2),它們都是P狀態。(1, 2, 3)是P狀態,因爲不管怎麼選擇,下一次一定變到N狀態。

“Nim和”就是兩個數二進制表示的不進位加法,也就是兩個整數進行xor位運算。
定義:兩個數(xm…x0)2和(ym…y0)2,是(zm…z0)2,其中zi=(xi+yi) mod 2,0<=i<=m。
例如,22和51的Nim和是37:


整數關於Nim和(以後用“+”表示)滿足交換律和結合律。有單位元0,因爲0+x=x。任何兩個相等的數之和是0,即x+x=0。有削去律,即如果x+y=x+z,那麼y=z。因爲,如果x+y=x+z,兩邊都加上x,得到x+x+y=x+x+z,即y=z。

定理1:Nim遊戲的一個狀態(x1, x2, x3) 是P狀態,當且僅當x1+x2+x3=0。

考慮狀態(13, 12, 8)。Nim和是9,不等於0,所以這是一個N狀態。

那麼接下來應該怎麼走,才能走到一個P狀態呢?你可以從第一堆中取走9顆石子。

或者你也可以從第二堆中取走7顆石子,等等。

如果石子的堆數大於3,只要堆數是有限的,上面的定理仍然成立。即如果有n堆石子,狀態(x1, x2, …, xn)是P狀態的充要條件是x1+x2+…+xn=0。下面就來證明。
我們用ρ表示所有Nim和爲零的狀態組成的集合;用п表示ρ的補集,即所有Nim和爲正整數的狀態組成的集合。讓我們逐一檢驗P狀態和N狀態的定義。
l    所有的終止狀態都在ρ中。由於終止狀態只有一個(0, 0, …, 0),0+0+…+0=0。
l    所有屬於п的狀態,一步之內一定可以走到ρ中的狀態。找出Nim和最左端爲1的那一列,然後任意選擇一個這一列是1的堆,從這堆中取走若干顆石子,使得Nim和爲0。這總是可以做到的,因爲將那一列的1變成0,而它左邊的列不用修改,這個數就肯定變小了。對於其他Nim和是1的列,只要將這個數相對列的0改成1,1改成0就可以了。
l    所有屬於ρ的狀態,一定轉變到п中的狀態。任意一個P狀態(x1, x2, …, xn),不妨假設從第一堆中取出若干顆石子。如果存在x1’<x1,而(x1’, x2, …, xn)也是P狀態。那麼x1+x2+…+xn=0=x1’+x2+…+xn,根據前面講的削去律,x1’=x1,與假設x1’<x1矛盾。所以(x1’, x2, …, xn)一定是N狀態,屬於п。

通過上面的證明,你能得到從一個N狀態走到P狀態的方案數嗎?而且這個數是奇數。

那麼,對於最後走步的人失敗的Nim遊戲,又怎麼辦呢?通常情況下,這類遊戲比最後走步的人獲勝的遊戲難得多。但Nim遊戲是個例外。我們來分析一下。
P狀態和N狀態的定義不變,如果初始狀態是N狀態,先走者有必勝策略。當超過1顆石子的堆數大於1的時候,按照前面所講的方法走。直到超過1顆石子的堆數等於1,這時將這堆石子全部取掉或剩1顆,保證非空(剩下1顆石子)的堆數爲奇數。如果初始狀態是N狀態,按照策略,先走者不可能將“超過1顆石子的堆數等於1”的狀態留給對方,因爲這樣的狀態不可能是P狀態。而且對方不可能在一步之內從“超過1顆石子的堆數大於1”的狀態變到“超過1顆石子的堆數小於1”的狀態。


圖遊戲
現在我們使用有向圖來描述一個遊戲,所有的狀態用頂點表示,所有合法的移動用有向邊表示。接下來我們會給出Sprague-Grundy函數(簡稱SG函數),它比起P狀態和N狀態,能夠提供更多的信息。

定義:用(X, F)來表示有向圖G。X是頂點集,F是後繼函數。設x是一個頂點,F(x)是一個集合,包含於X,任意一個元素y屬於F(x),表示從x出發到y有一條邊。F(x)就是x的後繼集合,也可看成從x出發的決策集。如果F(x)是空集,那麼就表示x是終止狀態。

圖遊戲:一個兩人遊戲,在一個圖G(X, F)上玩,指明一個頂點x0並按照下列的規則:
l    A先走,從x0開始;
l    兩人輪流走步;
l    從頂點x出發,只能走到頂點y,y屬於F(x);
l    遇到終止狀態,即不能走步,此人輸。

對於一個圖,如果不管x0是哪個點,總存在一個n,使得從x0出發的任意一條路經的長度都不超過n,那麼這個圖就被稱爲是“遞增有界”的。接下來主要討論遞增有界的圖遊戲。
拿遊戲1來舉例,設有n顆石子。頂點集X={0, 1, 2, …, n},F(0)是空集,F(1)={0},F(2)={0, 1},F(k)={k-3, k-2, k-1},3<=k<=n。下圖是n=10的情況。



SG函數
定義:
對於一個遞增有界的圖G(X, F)來說,SG函數g,是定義在X上的函數,函數值是非負整數,使得


用語言來描述就是:g(x)的值等於所有x的後繼的SG函數中沒有出現的最小非負整數。
對於遞增有界的圖,SG函數是唯一的、有界的。
所有的終止狀態x,因爲F(x)是空集,所以g(x)=0。

給出下圖的SG函數。


例1
給出遊戲1的SG函數,看看有什麼規律,與P狀態和N狀態有什麼關係。
x    0    1    2    3    4    5    6    7    8    9    10    11    …
g(x)    0    1    2    3    0    1    2    3    0    1    2    3    …

例2
有一堆石子,設當前剩下n顆石子,這一步至少要取走n/2取上界顆。唯一的終止狀態是剩0顆石子。給出SG函數,看看有什麼規律。
x    0    1    2    3    4    5    6    7    8    9    10    11    12    …
g(x)    0    1    2    2    3    3    3    3    4    4    4    4    4    …

根據例1的結果,我們猜測SG函數與P狀態和N狀態是有關的。如果g(x)=0,那麼x就是P狀態,否則x就是N狀態。證明是很顯然的,我們只要根據兩者的定義,考慮以下三點:
l    如果x是終止狀態,那麼g(x)=0。
l    一個狀態x,如果g(x)≠0,那麼一定存在一個x的後繼y,使得g(y)=0。
l    一個狀態x,如果g(x)=0,那麼所有x的後繼y,都有g(y)≠0。
當然,SG函數還包含了其他的信息,這些信息在以後會用到。


多個組合遊戲的並
給定若干個組合遊戲,可以按照下面的規則將它們併成一個新的遊戲。
l    對每個遊戲給定初始狀態。
l    兩人輪流走步,從A開始。
l    每一輪,選擇一個未到達終止狀態的遊戲,在這個遊戲中按照規則走一步,其他遊戲的狀態不變。
l    最後一個走步者獲勝,即走完之後所有遊戲都到達終止狀態。
我們稱這個新的遊戲爲“多個組合遊戲的並”。我們要來看如何用每一個遊戲的SG函數來求這個新的組合遊戲的SG函數。

n個圖遊戲的並
定義:有n個遞增有界的圖遊戲G1(X1, F1),……,Gn(Xn, Fn)。把它們合併成一個新的遊戲G(X, F),記爲G=G1+G2+…+Gn。X是所有遊戲頂點集的笛卡爾積,即X=X1*X2*…*Xn。也就是說,我們用n元組(x1, x2, …, xn)來表示G中的頂點x,其中xi屬於Xi,對於所有的i。x的後繼F(x)可以定義成:

這樣定義的新的遊戲G,一定也是遞增有界的。把每個遊戲的界相加,就得到了新遊戲的界。
正如Nim遊戲那樣,如果堆數是1,那麼非常簡單;如果堆數是2,也很容易分析;但堆數如果大於2,就不是很明顯了。所以即使每個圖遊戲都是很平凡的,n個圖遊戲的並也可能相當複雜。

下面介紹的SG定理可以看成是定理1的一般化。
定理2
設G=G1+G2+…+Gn,Gi的SG函數是gi,i=1, 2, …, n。那麼G的SG函數g(x1, x2, …, xn)=g1(x1)+g2(x2)+…+gn(xn),加法表示Nim和,即不進位的二進制加法。
證明:
令x(x1, x2, …, xn)是X中任意一點,b= g1(x1)+g2(x2)+…+gn(xn)。
根據SG函數的定義,我們要說明兩點:
(1)、對於任意的非負整數a(a<b),一定存在一個x的後繼y,使得g(y)=a。
(2)、x的任意一個後繼y,都有g(y)¹b。
首先來說明(1)。設d=a+b(nim和),d的二進制表示有k位,則2k-1<=d<2k。d的第k位是1而且a<b,所以a的第k位是0,b的第k位是1。因爲b= g1(x1)+g2(x2)+…+gn(xn),所以至少存在一個分量的第k位是1,不妨設它就是g1(x1)。那麼,就有d+g1(x1)<g1(x1),也就存在從x1到x1’的一次走步,使得g1(x1’) =d+g1(x1)。那麼g1(x1’)+g2(x2)+…+gn(xn)=d+g1(x1)+g2(x2)+…+gn(xn) = d+b=a。
再說明(2)。反證法。不失一般性,假設後繼的走步是從x1到x1’,又有g1(x1’)+g2(x2)+…+gn(xn) =g1(x1)+g2(x2)+…+gn(xn)。根據消去率,g1(x1’)=g1(x1),這與SG函數的定義不符,假設不成立。

例3、你每次可以從一堆石子中取走{1, 2, …, m}顆。對於1堆的問題,SG函數gm(x)=x mod (m+1)。如果考慮3個這樣的遊戲的並,第一個遊戲m=3,有9顆石子;第二個遊戲m=5,有10顆石子;第三個遊戲m=7,有14顆石子。g(9,10,14)=g3(9)+g5(10)+g7(14)=1+4+6=3,是一個N狀態。要取勝的話,下一次可以選擇第三個遊戲,取走1顆石子,使得g7(13)=5。那麼,還有別的取法嗎?
var
  n,m,p,t,i:longint;

begin
  readln(n);
  t:=0;
  for i:=1 to n do begin
    readln(m,p);
    t:=t xor (p mod (m+1));
    end;
  if t=0 then writeln('P') else writeln('N');
end.


取走-分割遊戲
這種遊戲允許取走某些東西,然後將原來的一個遊戲分成若干個相同的遊戲。
例1、Lasker’s Nim遊戲:每一輪允許兩種操作之一。(1)從一堆石子中取走任意多個(2)將一堆數量不少於2的石子分成都不爲空的兩堆。
分析:
很明顯,g(0)=0,g(1)=1。狀態2的後繼有0,1和(1,1),它們的SG函數值分別是0,1和0,所以g(2)=2。狀態3的後繼有0,1,2和(1,2),它們的SG函數值分別是0,1,2和3,所以g(3)=4。狀態4的後繼有0,1,2,3,(1,3)和(2,2),它們的SG函數值分別是0,1,2,4,5和0,所以g(4)=3。在推一些,我們得到:

我們推測:對於所有的k>=0,有g(4k+1)=4k+1;g(4k+2)=4k+2;g(4k+3)=4k+4;g(4k+4)=4k+3。
請自行證明。
假設遊戲初始時有3堆,分別有2、5和7顆石子。三堆的SG函數值分別是2、5和8,它們的Nim和等於15。所以要走到P狀態,就要使得第三堆的SG值變成7,可以將第三堆分成按1和6分成兩堆。
var
  g:array[0..100] of longint;
  b:array[0..100] of boolean;
  n,i,j:longint;

begin
  readln(n);
  g[0]:=0;
  for i:=1 to n do begin
    fillchar(b,sizeof(b),false);
    for j:=0 to i-1 do b[g[j]]:=true;
    for j:=1 to i div 2 do b[g[j] xor g[i-j]]:=true;
    j:=0;
    while b[j] do inc(j);
    g[i]:=j;
    writeln(i,': ',j);
    end;
end.


PAS
2人玩的遊戲,一個p*1的棋盤和紅、綠、藍三種棋子,棋子的大小分別是c*1、z*1和n*1,每種顏色的棋子個數無限。兩人輪流擺放棋子,規則是:
棋子不得超出棋盤範圍;
棋子不能有任何部分重疊;
如果哪個人沒有棋子可放,即算輸。
判斷先手是否有必勝策略。
輸入:
第一行是正整數c、z和n,都不超過1000。
第二行是m,表示棋盤種類。接下來的m行,每行一個正整數p。m和p都不超過1000。
輸出:
對於每種棋盤輸出一行,如果先手必勝輸出1,否則輸出2。
樣例
輸入
1 5 1



6
輸出
1
1
2

var
  c:array[1..3] of longint;
  g,q:array[0..1000] of longint;
  b:array[0..1000] of boolean;
  m,maxq,i,j,k:longint;

begin
  assign(input,'pas.in'); reset(input);
  assign(output,'pas.out'); rewrite(output);
  readln(c[1],c[2],c[3]);
  readln(m);
  maxq:=0;
  for i:=1 to m do begin
    read(q[i]);
    if q[i]>maxq then maxq:=q[i];
    end;
  g[0]:=0;
  for i:=1 to maxq do begin
    fillchar(b,sizeof(b),false);
    for j:=1 to 3 do
      for k:=0 to i-c[j] do b[g[k] xor g[i-c[j]-k]]:=true;
    j:=0;
    while b[j] do inc(j);
    g[i]:=j;
    end;
  for i:=1 to m do
    if g[q[i]]=0 then writeln(2) else writeln(1);
  close(input); close(output);
end.

尋找必敗態——一類博弈問題的快速解法

博弈是信息學和數學試題中常會出現的一種類型,算法靈活多變是其最大特點,而其中有一類試題更是完全無法用常見的博弈樹來進行解答。 尋找必敗態即爲針對此類試題給出一種解題思路。
                   此類問題一般有如下特點:
                   1、博弈模型爲兩人輪流決策的非合作博弈。即兩人輪流進行決策,並且兩人都使用最優策略來獲取勝利。
                   2、博弈是有限的。即無論兩人怎樣決策,都會在有限步後決出勝負。
                   3、公平博弈。即兩人進行決策所遵循的規則相同。
                   以下題目都屬於這一類:
                   POJ1740 A New Stone Game
                   MIPT100 Nim Game -- who is the winner? 
                   POJ1704 Georgia and Bob
                   POJ1067 取石子游戲

                   本着先理論後實踐的原則,本文先對“尋找必敗態”做出理論上的解釋:
                   
                  要理解這種思想,首先要明白什麼叫必敗態。說簡單點,必敗態就是“在對方使用最優策略時,無論做出什麼決策都會導致失敗的局面”。其他的局面稱爲勝態,值得注意的是在勝態下做出錯誤的決策也有可能導致失敗。此類博弈問題的精髓就是讓對手永遠面對必敗態。
                   必敗態和勝態有着如下性質:
                   1、若面臨末狀態者爲獲勝則末狀態爲勝態否則末狀態爲必敗態。
                   2、一個局面是勝態的充要條件是該局面進行某種決策後會成爲必敗態。
                   3、一個局面是必敗態的充要條件是該局面無論進行何種決策均會成爲勝態
                   
              這三條性質正是博弈樹的原理,但博弈樹是通過計算每一個局面是勝態還是必敗態來解題,這樣在局面數很多的情況下是很難做到的,此時,我們可以利用人腦的推演歸納能力找到必敗態的共性,就可以比較好的解決此類問題了。

                   下面就通過實際題目來做一些分析:
                   例1 POJ1740 A New Stone Game
                   
              題目大意是:有N堆石子,兩人輪流進行操作,每一次爲“操作者指定一堆石子,先從中扔掉一部分(至少一顆,可以全部扔掉),然後可以將該堆剩下的石子中的任意多顆任意移到其他未取完的堆中”,操作者無法完成操作時爲負。
                   分析:
                   只有一堆時先手必勝。
                   有兩堆時若兩堆相等則後手只用和先手一樣決策即可保證勝利,後手必勝。若不同則先手可以使其變成相等的兩堆,先手必勝。
                   有三堆時先手只用一次決策即可將其變成兩堆相等的局面,先手必勝。
                   有四堆時由於三堆必勝,無論先手後手都想逼對方取完其中一堆,而只有在四堆都爲一顆時纔會有人取完其中一堆,聯繫前面的結論可以發現,只有當四堆可以分成兩兩相等的兩對時先手纔會失敗。
                   
              分析到這裏,題目好像已經有了一些眉目了,憑藉歸納猜想,我們猜測必敗態的條件爲“堆數爲偶數(不妨設爲2N),並且可以分爲兩兩相等的N對”。
                   下面只需證明一下這個猜想。其實證明這樣的猜想很簡單,只用檢驗是否滿足必敗態的三條性質即可。
                   首先,末狀態爲必敗態,第一條性質符合。
                   其次,可以證明任何一個勝態都有策略變成必敗態(分奇數堆和偶數堆兩種情況討論)。
                   最後,證明任何一個必敗態都無法變成另一個必敗態(比較簡單)。
                   由於篇幅關係,這裏就不具體證明了,如果有興趣可以自己試試∶P
                接下來的程序就相當簡單了,只用判斷一下即可。


                   有些題則比這一題的條件隱蔽許多,例如:
                   例2 MIPT100 Nim Game -- who is the winner? 
                    題目大意是:有N堆石子,兩人輪流取,每次可以從任意一堆中取任意多顆(但至少一顆),誰先取完誰勝。
                    分析:
                    還是用按照“手推小數據=〉猜想=〉證明”的模式。
                    一堆時先手必勝。
                    兩堆時若兩堆相等則先手必敗,否則先手勝。
                    三堆的情況就有點複雜了,此時,我們只好藉助博弈樹來在小範圍內求解,從這些解中我們可以看出,對於由兩個不同數字構成的兩元組,都有且僅有一個三元必敗態包含它,這又意味着什麼呢?我們定義一個函數F(a,b),表示“包含a,b的三元必敗態中的第三數”,則有
                    F(1,2)=3,F(1,3)=2,F(1,4)=5,F(1,5)=4,F(1,6)=7,F(1,7)=6...
                    F(2,1)=3,F(2,3)=1,F(2,4)=6,F(2,5)=7,F(2,6)=4,F(2,7)=5...
                    F(3,1)=2,F(3,2)=1,F(3,4)=7,F(3,5)=6,F(3,6)=5,F(3,7)=4...
                    
              ..................................................................................
                
                    
              ..................................................................................
                
                敏銳的選手馬上會發現,這個F(a,b)不就是a  XOR(異或) b的結果麼?做到這裏,答案就在眼前了,‘XOR‘運算恐怕就是本題的關鍵。
                    
               繼續求出一些四元必敗態,這個性質仍然符合,於是我們猜想,必敗態即爲“所有堆的石子數XOR運算後結果爲零的局面”。這也解釋了爲什麼一堆石子必勝,兩堆石子僅在相等時必敗。
                    接下來又是證明:
                    依舊判斷是否符合三條性質。
                    第一條第三條顯然滿足,關鍵就是第二條。
                    
                 必勝態下,設所有堆石子XOR後結果爲N,將其寫成二進制,則至少有一堆石子寫成二進制後在N的最高位上爲一,則可以證明從這堆石子中取可以變成必敗態,這裏還是留給有興趣的選手:)
                    這一題就明顯沒有上一題輕鬆了,而且這是個經典問題,結論可以記下來。下面這個例子就是例2的強化版:


                    例3     POJ1704 Georgia and Bob
                    
                   題目大意是:一個1*M的棋盤上有N個棋子,初始位置一定,兩人輪流操作,每次移動一枚棋子,要求只能向左移且至少移動一格,而且不能到達或經過以前有棋子的格子,誰無法移動棋子就算輸。
                    分析:
                    乍一看這一題棋子移動還要受其他棋子的限制,好像無法求出通解,但仔細分析會發現別有洞天。
                    
                    一個棋子每一次向左移的最大步數是固定的,而且隨着移動減少,不是和取石子很像麼?那麼和取石子的區別在哪呢?就在於每一次移動時都會讓右邊相鄰的那顆棋子移動空間變大,這樣就和取石子只減不增有所不同了,我們應該怎樣解決這個問題呢?
                    我們並不放棄將其與我們熟悉的取石子對應,但我們將策略做小小的變動:
                    
                  將棋子從右端向左端每相鄰兩個分爲一對,如果只剩一個就將棋盤左端加一格放一顆棋子與之配對,這樣配對後好像和以前沒有什麼區別,但決策時就方便多了,因爲我們大可不必關心組與組之間的距離,當對手移動一組中靠左邊的棋子時,我們只需將靠右的那一顆移動相同步數即可!同時我們把每一組兩顆棋子的距離視作一堆石子,在對手移動兩顆棋子中靠右的那一顆時,我們就和他玩取石子游戲,這樣就把本題與取石子對應上了。
                  本例說明有許多模型看似複雜,但經過一些巧妙的變換,便可以轉化成一些我們熟悉的模型,同時也充分體現了博弈的靈活。
                  如果說前面的例子是介紹這種思想的運用的話,下面的方法就是講這種思路的優越性了,因爲這一題並不是走的“手推小數據=〉猜想=〉證明”的老路,而是直接利用性質推導必敗條件。
                   

                    例4 
              url=http://acm.pku.edu.cn/JudgeOnline/showmessage?message_id=4163]POJ1067
              取石子游戲[/URL]
                    題目大意是:......題目本來就是中文的-_-b。
                    分析:
                   剛拿到這一題時,我不加思索的猜想必敗態爲“兩堆石子的數目是2:1”,用性質判定:第一條顯然符合,第二條分情況討論每一種“勝態”都有一種固定的方法變成“必敗態”,再看第三條,設第一堆有N顆,第二堆有2*N顆,則無論怎樣拿都無法讓第二堆保持爲第一堆的兩倍。證畢。
                本以爲此題就這麼簡簡單單完了,但是我突然發現,當第一堆2顆,第二堆4顆時,從第二堆中取出3顆石子的話第二堆的確無法保持爲第一堆的兩倍,但第一堆會變成第二堆的兩倍,基於此,整個猜想被徹底推翻。
               於是我反轉思路,乾脆從性質入手。
               我們令必敗二元組爲(a,b)形式,並令a<b。
               根據性質三,有這樣兩個推論:
                    
               推論一:對於任意兩個的必敗二元組(a1,b1),(a2,b2),有a1<>a2,b1<>b2,a1<>b2,a2<>b1。
               推論二:對於任意兩個的必敗二元組(a1,b1),(a2,b2),有b1-a1<>b2-a2。
                    
              利用性質和該推論,我們證明如下結論:“將必敗二元組按首元爲關鍵字排序,每個必敗二元組中首元爲未在前面的必敗二元組中出現的最小正整數,並且第N組中兩個數差爲N”。
                    利用數學歸納法證明:
                    第一組爲(1,2),滿足題意。
                    若前N組滿足題意,則有:
                    設爲在前N組中出現的最小正整數爲M,則對於二元組(M,M+N+1)有: 
                    
             如果從數量爲M的堆中取了石子,不妨設變成了(K,L),則L-K>N,這樣就有一個包含K,且不與前面N組任何一組相同的二元組,根據推論一,這個二元組一定不是必敗二元組。
             如果只從數量爲M+N+1的堆中取,不妨設剩下K顆,又分三種情況:
                 K>M,則N+1>K-M>0,根據推論二,這個二元組一定不是必敗二元組。
                 K=M或0,顯然不是必敗二元組。
                 0<K<M,則(K,M)爲包含K,且不與前面N組任何一組相同的二元組,根據推論一,這個二元組一定不是必敗二元組。
           綜上,根據性質三,(M,M+N+1)爲必敗二元組,又根據排序的法則,(M,M+N+1)一定是數列的第(N+1)項。證畢。
           這樣利用性質和性質得出的推論,此題的必敗態也完美的找出了。

           從上面的例子可以看出,利用尋找必敗態的思路解題對猜想和數學證明的能力要求很高,對思維的訓練有很大好處,同時編程複雜度相當低,也不失爲一種好的解題方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章