三大經典博弈 尼姆博奕 + 巴仕博弈 + 威佐夫博弈 +SG函式
一,特例分析
有三堆各若干個物品,兩個人輪流從某一堆取任意多的物品,規定每次至少取一個,多者不限,最後取光者得勝。
我們用(a,b,c)表示某種局勢,首先(0,0,0)顯然是奇異局勢,無論誰面對奇異局勢,都必然失敗。
第二種奇異局勢是(0,n,n),只要與對手拿走一樣多的物品,最後都將導致(0,0,0)。
任何奇異局勢(a,b,c)都有a^b^c =0。
如果我們面對的是一個非奇異局勢(a,b,c),要如何變為奇異局勢呢? 只要將其中一個是
變成其他兩個數的異或就行了。
二,例題題目1:今有若干堆火柴,兩人依次從中拿取,規定每次只能從一堆中取若干根,可將一堆全取走,但不可不取,
最後取完者為勝,求必勝的方法。
備註: 若所有火柴數異或為0,則該狀態被稱為利他態,用字母T表示;否則, 為利己態,用S表示。
[定理1]:對於任何一個S態,總能從一堆火柴中取出若干個使之成為T態。
[定理2]:T態,取任何一堆的若干根,都將成為S態。
[定理 3]:S態,只要方法正確,必贏。
[定理4]:T態,只要對方法正確,必敗。
題目2:今有若干堆火柴,兩人依次從中拿取,規定每次只能從一堆中取若干根,可將一堆全取走,但不可不取,
最後取完者為負,求必勝的方法。
備註:若一堆中僅有1根火柴,則被稱為孤單堆。若大於1根,則稱為充裕堆。0:沒有富裕堆,1:有一個富裕堆 ,
2:有大於等於個富裕堆
[定理2]:S0 即僅有奇數個孤單堆,必敗,T0 態必勝。
[定理3]:S1態,只要方法正確,必勝
[定理4]:S2態,只要方法正確,必勝.
四,一般情況有N堆石子,其中第i堆有Pi顆石子,每次從某一堆裡選出若干石子去掉(但不能不去石子),兩人輪流取石,
誰不能繼續取誰就輸了。
備註: 若所有火柴數異或為0,則該狀態被稱為利他態,用字母T表示;否則, 為利己態,用S表示。若只有一堆石子,為T狀態
若有m堆石子,每堆有k顆石子, m堆為奇數時 ,為T狀
定理:
對於一個局面,令H=P1^P2^P3^… ^Pn。若H=0則為T局面,否則為s局面
總結:
有n堆各若干個物品,兩個人輪流從某一堆取任意多(或者最多m個,只需把每堆%m)的物品,規定每次至少
取一個,多者不限,最後取光者得勝。 把每堆數量求異或a1^a2^...^ai'^...^an,結果為零則先手必輸,否則必贏
三,Nim問題的擴充套件
問題:取石子問題
有N堆石子,其中第i堆有Pi顆石子,每次去掉某一堆裡最多m棵石子(m>0),兩人輪流取石,
誰不能繼續取誰就輸了。什麼情況下先手必勝,什麼情況下後手必勝?
解析:
將P1,P2,P3, … Pn 對m+1求餘得到q1,q2,q3, …,qn然後符合定理一的結果,記H=q1^q2^q3^ …^qn 。
若H=0則為T局面,否則為s局面。
備註: s: 為利己態,先手必勝,非奇異態。
T:為利他態,先手必敗,奇異態。
四,Nimk問題的取石子方法
問題:取石子問題
有N堆石子,其中第i堆有Pi顆石子,每次可以從最多K堆中選出若干石子去掉(但不能不去石子),
兩人輪流取石,誰不能繼續取誰就輸了。
什麼情況下先手必勝,什麼情況下後手必勝?
K=1,為Nim問題。
對於K>1的情況,我們令把P1~Pn這n個數,轉成二進位制,然後每位分別相加,每位最後結果mod (K+1)即可。
如果每一位結果都是0,則為T局面,否則是s局面
第二:Sprague-Grundy函式(SG函式)
一,概述:
如果我們把遊戲中的某一個局面看作一個頂點,把局面之間的轉換用邊來表示,
那麼很多遊戲都可以轉化成圖遊戲模型。圖遊戲模型 給定有向無環圖G=(V,E)和一個起始點,
雙方輪流行動。每個人每次可以從當前點出發沿著一條有向邊走到另外一個點。誰無法走了誰就輸。
一些圖遊戲可以通過Sprague-Grundy函式來判定先手的勝負情況(簡稱SG函式)。
SG函式 一個圖G=(V,E)的SG函式g,是定義在v上的一個非負整數函式:
g(x)=min{key>=0 | key≠g(y) for <x,y>∈E}
key屬於[0,n](n為頂點個數)
如果x的出度為0,那麼g(x)=0。(邊界條件)
g(x)就是x的後繼點的SG值中沒有出現過的最小值
解析:
這樣定義有什麼好處呢?我們把一個圖的當前狀態值定義為遊戲者處在的這個點的SG值。
如果遊戲者處在一個點x,g(x)≠0。那麼0, 1, …, g(x)-1這些數必然都出現在x的後繼節點的SG值中
而遊戲者可以走到這些點中的任意一個。也就是說:遊戲者可以通過一步走棋把圖的當前狀態值任意的減小
(當然必須保證狀態值始終>=0)。如果遊戲者處在一個點x,g(x)=0。那麼遊戲者無論如何移動,
下一個點的SG值都不等於0。
定理:
對於一個圖遊戲,如果圖的當前狀態等於0,那麼先手必敗,否則必勝。
擴充套件:
多圖遊戲 有多個圖,每個圖都有一個當前節點。兩個遊戲者輪流行動。每個人每次可以把某一個圖中的
當前節點沿著該點連出的有向邊移動到另一個點。無法移動的那個人輸。
結論:
設這些圖的當前狀態值分別是a1, a2, …, ak,如果:a1 ^ a2 ^ … ^ ak = 0,那麼先手必敗,否則必勝。
三,定理
1、 所有終結點都是必敗點P
2、所有一步能走到必敗點P的就是N點;
3、通過一步操作只能到N點的就是P點;
第三:巴仕博弈(Bash Game)
一,題目:
只有一堆n個物品,兩個人輪流從這堆物品中取物,規 定每次至少取一個,最多取m個。最後取光者得勝。
二,分析
1,如果n=m+1,那麼由於一次最多隻能取m個,所以,無論先取者拿走多少個,
後取者都能夠一次拿走剩餘的物品,後者取勝。必敗
2,法則:如果n=(m+1)*r+s,(r為任意自然數,s≤m),那麼先取者要拿走s個物品,如果後取者拿走k(≤m)個,
那麼先取者再拿走m+1-k個,結果剩下(m+1)(r-1)個,以後保持這樣的取法,那麼先取者肯定獲勝。
總之,要保持給對手留下(m+1)的倍數,就能最後獲勝。必勝局
3,備註:
P點:即必敗點,某玩家位於此點,只要對方無失誤,則必敗;
N點:即必勝點,某玩家位於此點,只要自己無失誤,則必勝。
第四:威佐夫博弈(Wythoff Game)
一,題目:
有兩堆各若干個物品,兩個人輪流從某一堆或同時從兩堆中取同樣多的物品,規定每次至少取一個,
多者不限,最後取光者得勝
二,解析
1,。我們用(a[k],b[k])(a[k] ≤ b[k] ,k=0,1,2,...,n)表示兩堆物品的數量並稱其為局勢。
2,如果甲面對(0,0),那麼甲已經輸了,這種局勢我們稱為奇異局勢。
3,奇異局(舉例)
首先列舉人們已經發現的前幾個奇異局勢:(0,0)、(1,2)、(3,5)、(4,7)、(6,10)
(8,13)、(9,15)、(11,18)、(12,20)。
通過觀察發現:a[0]=b[0]=0,a[k]是未在前面出現過的最小自然數,而 b[k]= a[k] + k。
4,奇異局勢有如下三條性質:
1)任何自然數都包含且僅包含在一個奇異局勢中。
2)任意操作都可以使奇異局勢變為非奇異局勢。
3)必有一種操作可以使非奇異局勢變為奇異局勢。
5,奇異局勢公式:
a[k]=[k*(1+√5)/2],b[k]=a[k]+k。
(k=0,1,2......,[ ]表示取整)
有趣的是,式中的(1+√5)/2正是黃金分割比例。
6,判斷
可以看出,如果兩人都採取正確的操作,那麼對於非奇異局勢,先拿者必勝,對於奇異局勢,
先拿者必敗。
第五,SG函式模板
//模板:(SG函式)
int f[N],sg[N],hash[N];
void getSG(int n)
{
int i,j;
memset(sg,0,sizeof(sg));
for(i=1;i<=n;i++)
{
memset(hash,0,sizeof(hash));
for(j=1;f[j]<=i;j++)
hash[sg[i-f[j]]]=1;
for(j=0;j<=n;j++)
{
if(hash[j]==0)
{
sg[i]=j;
break;
}
}
}
}
第六,威佐夫博弈模板
//威佐夫博弈模板
#include <stdio.h>
#include <math.h>
const double Gsr=(1+sqrt(5.0))/2;
void swap(int &a,int &b)
{
int t=b;
b=a;
a=t;
}
int main()
{
int a,b;
while(~scanf("%d%d",&a,&b))
{
if(a>b)
swap(a,b);
if(a == (int)(Gsr*(b-a))) //奇異局勢,先拿者輸
puts("First Lose");
else
puts("First Win");
}
return 0;
}