演算法與資料結構 博弈論

2021-06-03 20:32:20 字數 4400 閱讀 3212

遊戲a 簡單博弈

有兩個遊戲者:a和b。有21顆石子。兩人輪流取走石子,每次可取1、2或3顆。a先取。取走最後一顆石子的人獲勝,即沒有石子可取的人算輸。

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

p狀態和n狀態

就像第乙個遊戲一樣,狀態0,4,8,……是剛才走步的人的必勝狀態,我們稱之為p狀態;

而1,2,3,5,6,7,……都是下乙個走步的人的必勝狀態,我們稱之為n狀態。

我們可以從終止狀態出發,推出每乙個狀態,指出它是p狀態還是n狀態。

現在對遊戲1略微擴充套件一下。

有乙個決策集s,s中的元素是正整數。遊戲的規則大致與遊戲1一樣,只是現在每次可以取的石子數必須是s中的元素。

如果s=,那麼就是遊戲1。

大家分析一下,當s=的時候,哪些狀態是p狀態,哪些是n狀態。

我們發現p狀態是,n狀態是。

規律是如果n除以7的餘數是0或2,那麼狀態n就是p狀態,否則就是n狀態。

如果遊戲開始時,石子總數是100,那麼這是乙個p狀態,也就是說後走的人有必勝策略。

遊戲b nim遊戲

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

我們用三元組來表示狀態,很明顯(0, 0, 0)是唯一的終止狀態,是p狀態。

先考慮只剩一堆有石子的情況(0, 0, x),很明顯這是,這些狀態都是n狀態。

剩兩堆的情況,如果兩堆的石子數相等(0, x, x),那麼這些都是p狀態。因為下一次走步的人一定會使得兩堆石子不相等,再下一次可以使得兩堆的石子數回到相等的狀態,包括終止狀態。如果兩堆的石子數不相等,那麼就是n狀態。

「nim和」就是兩個數二進位制表示的不進製加法,也就是兩個整數進行xor位運算。

定義:兩個數(xm…x0)2和(ym…y0)2,是(zm…z0)2,其中zi=(xi+yi) mod 2,0<=i<=m

整數關於nim和(以後用「+」表示)滿足交換律和結合律。

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

遊戲c 圖遊戲

乙個兩人遊戲,在乙個圖g(x, f)上玩,指明乙個頂點x0並按照下列的規則:

a先走,從x0開始;

兩人輪流走步;

從頂點x出發,只能走到頂點y,y屬於f(x);

遇到終止狀態,即不能走步,此人輸。

後繼函式定義:

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

sprague-grundy函式定義:

對於乙個遞增有界的圖g(x, f)來說,sg函式g,是定義在x上的函式,函式值是非負整數,使得

g(x)=min

即g(x)的值等於所有x的後繼的sg函式中沒有出現的最小非負整數。

sg函式與p狀態和n狀態是有關的。如果g(x)=0,那麼x就是p狀態,否則x就是n狀態。

如果x是終止狀態,那麼g(x)=0。

乙個狀態x,如果g(x)≠0,那麼一定存在乙個x的後繼y,使得g(y)=0。

乙個狀態x,如果g(x)=0,那麼所有x的後繼y,都有g(y)≠0。

對於遊戲b和遊戲c本質上其實一致。有如下理論:

加法理論:

局面:(a1,a2,……,an)+(b1,b2,……,bm)=(a1,a2,……,an,b1,b2,……,bm)

對於局面a,b,s,若s=a+b,則稱局面s可以分解為「子局面」a和b。

推論:若初始局面s可以分成兩個相同的「子局面」,則先行者負(s負)。

分解理論:

對於局面s=a+b,若先行者有必勝策略,則稱「s勝」,否則稱「s負」。

1)若a與b一勝一負,則s勝。

2)若a負b負,則s負。

3)若a勝b勝,則s時勝時負。

推論:1)s=a+c+c,則s的情況和a相同。故可用其簡化局面,如局面(3,3,1)可以簡化為局面(1)。

2)空局面是負局面。

一般解法:

用#s表示局面s對應的而二進位制數,則:

局面s=a+b => #s=#a+#b

即#s等於該堆石子數a的sg函式值g(a)。如可以用#3表示(3)。(這裡g(x)=x)

則有(3,3)=(3)+(3) => #(3,3)=#(3)+#(3)=11b+11b=0 (無進製2進製加法即異或運算)。

結論:若#s=0,則s負,否則s勝。

推廣遊戲b為每次取有上限m,則只需更改g(x)=x%(m+1)。

遊戲d 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)可以定義成:

定理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和,即不進製的二進位制加法。

必勝策略:只需要用合併後的sg值與每一堆sg值分別異或,看得到的結果是否小於原來該堆的sg值,如果小則可以取該堆。

遊戲e 取走-分割遊戲

甲乙面對若干排石子,其中每一排石子的數目可以任意確定。如初始局面為(7,3,3)。

每一步必須從某一排中取走兩枚石子;

這兩枚石子必須緊挨著。

分析:每取一次相當於再分堆。

一般解法:

1)用乙個n元祖(a1,a2,……,an),來描述遊戲中的乙個局面。

2)用符號#s,表示局面s對應的二進位制數。

3)用符號$(x),表示局面(x)的下一步所有可能出現局面的集合。

4)定義集合g(x),設:$(x)=,則g(x)=。

5)令非負整數集為全集,集合g(x)表示集合g(x)的補集。

6)定義函式f(n):f(n)=min,即f(n)等於集合g(n)中的最小數。

7)設局面s=(a1,a2,……,an),#s=f(a1)+f(a2)+……+f(an),採用無進製二進位制加法即異或運算。

若#s≠0,則s勝,否則s負。

題目推薦:

zoj problem set - 3529 a game between alice and bob

題意:alice和bob兩個人在玩遊戲,最開始有n個正整數,alice先操作,之後雙方輪流操作,可以任選乙個數將其變為乙個該數的乙個和自己不等的約數,誰將所有數都變為1,誰就獲勝了。

分析:sg函式 g(n)=。

求質因子個數先用快速帥選素數法標出素數以及每個數的最大質因子。

那麼再處理這個數的質因子個數就是除以最大質因子之後的那個數的質因子個數+1(dp);

然後利用博弈問題的合併,可知,如果每個數得到的sg值進行異或,非0則勝,為0則負。然後後半部分又是另乙個經典問題,只需要用合併後的sg值與每一堆sg值分別異或,看得到的結果是否小於原來該堆的sg值,如果小則可以取該堆。

#include "stdio.h"

#define max 5000005

long isprime[max];

long input[max];

long sg[max];

/** * 初始化素數表

* 若i為素數isprime[i]=i 否則isprime[i]為其最大質因子

*/void initprime()

for(i=2;i/** * dp求取sg函式值

* n的質因子個數等於除以最大質因子之後的那個數的質因子個數+1

*/long getsg(long n)

int main()

for(i=0;iif(sg!=0)printf("test #%ld: alice %ld\n",count++,i+1);

else printf("test #%ld: bob\n",count++);

} return 0;

}

演算法與資料結構 博弈論(高階篇之SG博弈)

sg博弈的命名源於sg函式和sg定理,而sg函式的出現則來自於乙個簡單的取石子遊戲 有1堆n個的石子,每次只能取個石子,先取完石子者勝利,判斷對於不同的n,先手能否取勝?分析 這個遊戲和巴什博弈的不同在於 sg博弈中取東西是無規則不連續的,而巴什博弈中取東西則是連續的 因此在討論sg博弈時要複雜很多...

演算法與資料結構 博弈論(高階篇之尼姆博弈)

尼姆博弈 nimm game 有任意堆物品,每堆物品的個數是任意的,雙方輪流從中取物品,每一次只能從一堆物品中取部分或全部物品,最少取一件,取到最後一件物品的人獲勝。分析 我們先來看假設有三堆物品時的情況 這種情況最有意思,它與二進位制有密切關係,我們用 a,b,c 表示某種局勢,則前幾種奇異局勢如...

博弈論演算法

複習 兩個頂尖聰明的人在玩遊戲,有一堆n個石子,每次每個人能取 1,m 個石子,不能拿的人輸,請問先手與後手誰必敗?結論 通過上面的分析可以得出結論 當n能整除m 1時先手必敗,否則先手必勝。兩個頂尖聰明的人在玩遊戲,有nn堆石子,第ii堆有aiai個,每人每次能從一堆石子中取任意多個石子但不能不取...