博弈論的題目有如下特點:
- 有兩名選手
- 兩名選手交替操作,每次一步,每步都在有限的合法集合中選取一種進行
- 在任何情況下,合法操作只取決於情況本身,與選手無關
- 游戲敗北的條件為:當某位選手需要進行操作時,當前沒有任何可以執行的合法操作
下面介紹幾個經典的博弈。
巴什博弈(Bash Game)
一堆n個物品,兩個人輪流從中取出1~m個,最后取光者勝(不能繼續取的人輸)。
同余定理:$n=k*(m+1)+r$,先者拿走$r$個,那么后者無論拿走$1~m$個先者只要的數目使和為$m+1$,那么先手必贏。反之若$n=k*(m+1)$,那么先手無論怎樣都會輸。
if (n % (m + 1)) return false; else return true;
威佐夫博弈(Wythoff Game)
有兩堆各若干物品,兩個人輪流從任意一堆中至少取出一個或者從兩堆中取出同樣多的物品,規定每次至少取一個,至多不限,最后取光者勝。
這里的必輸局勢:(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20)。從這些必輸局勢可以發現,每組的第一個是前面沒有出現的最小正整數,$a_k = [k * (1+\sqrt{5}) / 2],\ b_k = a_k + k,\ k = 0,1,2,3...$。
所以,先求出差值,差值*黃金分割比 == 最小值的話后手贏,否者先手贏。
double r = (sqrt(5) + 1) / 2; int d = abs(a - b) * r; if (d != min(a, b)) return true; else false;
注:如果a,b的值非常大的話,需要高精度來計算這個double類型的r。
斐波那契博弈(Fibonacci Nim Game)
一堆石子有n個,兩人輪流取,先取者第一次可以去任意多個,但是不能取完,以后每次取的石子數不能超過上次取子數的2倍。取完者勝。
同樣是一個規律:先手勝當且僅當n不是斐波那契數。
f[0] = f[1] = 1; for (int i = 0; f[i - 1] < n; i++) { f[i] = f[i - 1] + f[i - 2]; if (f[i] == n) return true; } return false;
尼姆博弈(Nimm Game)
有n堆物品,兩人輪流取,每次取某堆中不少於1個,最后取完者勝。
假如有3堆物品(a,b,c)
(0,0,0)狀態時先手是一個必輸局勢因為沒有東西可取,(0,n,n) 狀態時也是必輸局勢只要后者在另一堆取得物品與前者一樣多時那么前者也就是必輸局勢。慢分析(1,2,3)也是一個必輸局勢。如果我們將其轉化為二進制形式並通過異或運算(^)我們會發現:
0001^0010^0011=0000
通過驗證所有的堆數量累^后只要為0就都是必輸局勢,所以我們就只要記住這個規則:將n堆物品數量全部異或后結果為0先手必敗,否則必勝。
int res = 0; for (int i = 1; i <= n; i++) res ^= arr[i]; if (res) return true; else return false;
但是,實際問題中不可能給出如此標准的博弈模型,對於更加一般的博弈問題,我們該如何求解呢?通過SG函數轉換為尼姆博弈。
SG函數
首先給出一種ICG博弈游戲模型,給定一個有向無環圖和一個起始頂點上的一枚棋子,兩名選手交替的將這枚棋子沿着有向邊進行移動,無法移動者判負。
將ICG問題進行轉化:任何一個ICG都可以通過把每個局面看作一個頂點,對每個局面和它的子局面連一條有向邊來抽象這個“有向圖游戲”。
於是我們將ICG問題轉化為上述這個游戲,再通過尋找這個游戲的一般解法來處理ICG問題。
首先定義mex(minimal excludant)運算,這是定義於一個集合的運算,表示最小的不屬於這個集合的最小非負整數。例如mex{0,1,2,4}=3,mex{2,3,4}=0,mex{}=0.
SG函數(Sprague-Grundy):對於一個給定的有向無環圖,定義關於這個圖的每個頂點的SG函數如下:$sg(x) = mex\{sg(y) \ | \ y是x的后繼 \}$
SG函數的求法:
- 找出必敗態
- 找出當前所有狀態的前驅結點
- 根據定義計算結點SG值
- 重復上述步驟,直到整棵樹建立完成
按上述步驟建成的樹如下:
這顆樹有什么意義呢?比如說我們將一個頂點放在根節點上,當前這個點的sg值為0,說明當前這個點是必敗態。為什么這么說呢?我們將這個點交替進行移動,先手有兩種選擇,往右移動,顯然后手再移動一步就進入必敗態;往左移動,后手會選擇往右移動,先手同樣進入必敗態。
如何通過SG函數值來解決之前的有向圖問題呢?對於n個棋子,設它們對應的頂點的SG函數值分別為$\{a_1,a_2,...a_n\}$,再設局面$\{a_1,a_2,...a_n\}$時的Nim游戲的必勝策略是把$a_i$變成$k$,那么原游戲的一種必勝策略就是把第$i$枚棋子移動到一個SG值為$k$的頂點。
簡單來說,我們讓每個結點都擁有一個SG值(假設這個值為$x$),那么對於任何一個玩家操作(移動到當前結點的某個后繼結點)實際上就是把棋子移動到0~x-1的某個結點上,等價的就是從x個物品中取走一個,最多x個!。
不是是覺得有點不對,單根據mex的定義,可能出現如下情況,移動到比自身SG值大的結點:
其實這種情況是不存在的,博弈問題中先手不會移動到對自己不利的局面的,在這里也就是不會移動到SG值為4的結點。
SG定理:所以我們可以定義有向圖游戲的和。設$G_1,G_2,...G_n$為n個“有向圖”游戲的和(Sum),游戲G的移動規則是:任選一個子游戲$G_i$並移動上面的棋子。SG定理就是:$sg(G)=sg(G_1) \wedge sg(G_2) \wedge .... \wedge sg(G_n)$。也就是說,游戲的SG函數值就是它的所有子游戲的SG函數值的異或。
因此,當我們面對n個不同游組成的游戲時,只需要求出每個游戲的SG函數值,把這些SG值都看作Nim的石子堆,然后依照找Nim游戲的必勝策略的方法來找這個游戲的必勝策略。