NIM博弈+SG函数求解
ICG
給定一個有向無環圖和一個起始頂點上的一枚棋子,兩名選手交替的將這枚棋子沿有向邊進行移動,無法移動者判負。
這個游戲可以認為是所有 Impartial Combinatorial Games 的抽象模型。也就是說,任何一個 ICG 都可以通過把每個局面看成一個頂點,對每個局面和它的子局面連一條有向邊來抽象成這個“有向圖游戲”。
滿足以下條件的游戲是ICG:
1、有兩名選手;
2、兩名選手交替對棋子進行移動(move),每次一步,選手可以在有限的合法移動集合中任選一種進行移動;
3、對于游戲的任何一種可能的局面,合法的移動集合只取決于這個局面本身,不取決于輪到哪名選手操作、以前的任何操作、骰子的點數或者其它什么因素;?
4、如果輪到某名選手移動,且這個局面的合法的移動集合為空(也就是說此時無法進行移動),則這名選手負。
?
下 面我們就在有向無環圖的頂點上定義 Sprague-Garundy 函數。首先定義 mex(minimal excludant)運算,這是施加于一個集合的運算,表示最小的不屬于這個集合的非負整數。例如 mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。
對于一個給定的有向無環圖,定義關于圖的每個頂點的 Sprague-Grundy 函數 g(x)如下:g(x)=mex{ g(y) | y 是 x 的后繼 }。
SG 函數的性質:
1.首先,所有的 terminal position 所對應的頂點,也就是沒有出邊的頂點,其 SG 值為 0,因為它的后繼集合是空集。
2.然后對于一個 g(x)=0 的頂點 x,它的所有后繼 y 都滿足 g(y)!=0。
3.對于一個 g(x)!=0 的頂點,必定存在一個后繼 y 滿足 g(y)=0。
以上這三句話表明,頂點 x 所代表的 postion 是 P-position 當且僅當 g(x)=0。
我們通過計算有向無環圖的每個頂點的 SG 值,就可以對每種局面找到必勝策略了。
?
Nim 游戲的規則:
有K堆各N個石子,兩個人輪流從某一堆中取出任意多個石子,每次至少取一個,取走最后石子的人獲勝。
分析:
最后一個奇異局勢是(0,0...,0),無論誰面對奇異局面,都是必敗的。另一個奇異局勢是(n,n,0...0),只要對手總是和我拿走一樣多的物品,最后會面對(0,0...,0)。
奇異局勢的判定:
????對于一個普通的局勢,如何判斷其是不是奇異局勢?對于一個局勢(s1,s2,...sk),對所有石子個數做位的異或運算,s1^s2^s3^...^sk,如果結果為0,那么局勢(s1,s2,...sk)就是奇異局勢(平衡),否則就不是(非平衡)。
????從二進制位的角度上說,奇異局勢時,每一個bit位上1的個數都是偶數。
玩家的策略:
????就是把面對的非奇異局勢變為奇異局勢留給對方。也就是從某一堆取出若干石子之后,使得每一個bit位上1的個數都變為偶數,這樣的取法一般不只有一種??梢詫⑵渲幸欢训氖訑底優槠渌咽訑档奈划惢蜻\算的值(如果這個值比原來的石子數小的話)。
每次選擇 一堆數量為 k 的石子,可以把它變成 0、變成 1、……、變成 k-1,但絕對不能保持 k不變。
變形
假設不是一枚棋子,而是n枚棋子,如何獲勝?
讓我們再來考慮一下頂點的 SG 值的意義。當 g(x)=k 時,表明對于任意一個0<=i<k,都存在 x 的一個后繼 y 滿足 g(y)=i。
也 就是說,當某枚棋子的 SG 值是 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 的頂點。
其實我們還是只要證明這種多棋子的有向圖游戲的局面是 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 的必勝策略的方法來找這個游戲的必勝策略了!
?
NIM游戲例題
有 n 堆石子,每次可以從第 1 堆石子里取 1 顆、2 顆或 3顆,可以從第 2 堆石子里取奇數顆,可以從第 3 堆及以后石子里取任意顆,先手必勝輸出Y,否則輸出N
分析:
我們可以把它看作 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 個“任取石子游戲”的和嗎?
#include<bits/stdc++.h> using namespace std;int main() {ios::sync_with_stdio(false);int n,t;cin>>t;while(t--){cin>>n;int x,ans=0;int sg1=0,sg2=0,sg3=0;cin>>x;//第一堆sg1=x%4;cin>>x;//第二堆sg2=x%2;for(int i=0;i<n-2;i++){cin>>x;sg3^=x;}ans=sg1^sg2^sg3;if(ans==0)//必敗printf("N\n");elseprintf("Y\n");}return 0;}總結
SG 函數與“游戲的和”的概念不是讓我們去組合、制造稀奇古怪的游戲,而是把遇到的看上去有些復雜的游戲試圖分成若干個子游戲,對于每個比原游戲簡化很多的子游戲找出它的 SG 函數,然后全部異或起來就得到了原游戲的 SG 函數,就可以解決原游戲了。
尋找必敗態
必敗態就是“在對方使用最優策略時,無論做出什么決策都會導致失敗的局面”。其他的局面稱為勝態,值得注意的是在 勝態下做出錯誤的決策也有可能導致失敗。此類博弈問題的精髓就是讓對手永遠面對必敗態。
必敗態和勝態有著如下性質:
1、若面臨末狀態者為獲勝則末狀態為勝態否則末狀態為必敗態。
2、一個局面是勝態的充要條件是該局面進行某種決策后會成為必敗態。
3、一個局面是必敗態的充要條件是該局面無論進行何種決策均會成為勝態。
這三條性質正是博弈樹的原理,但博弈樹是通過計算每一個局面是勝態還是必敗態來解題,這樣在局面數很多的情況下是很難做到的,此時,我們可以利用人腦的推演歸納能力找 到必敗態的共性,就可以比較好的解決此類問題了。
解題思路
分析初始局勢是屬于哪種形態,然后根據博弈中的些結論去推導當前狀態是否是必敗態。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的NIM博弈+SG函数求解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU4825 Xor Sum 01字典
- 下一篇: 动态规划下的巴什博弈