您的位置:首页 > 移动开发 > IOS开发

Game Theory: 公平博弈

2011-08-21 16:33 253 查看
Notes: The following excerpt is from a book 《GAME THEORY》by Thomas && S.Ferguson and a paper by Ulyssess.

一. 公平聯合博弈

公平聯合博弈(Impartial combinatorial game ):兩個參與者,輪流活動;狀態集合有限;對每個局面(position),每個參與者有相同的地位; 在“通常規則”下,最後一個活動的參與者贏;滿足“結束條件”,即博弈在有限次“活動”之後必然會結束。由此可以看出沒有平手(draw)的出現!

P局面(P-positions )和N局面(N-positions)是被遞歸地定義的:1)所有的最終局面為P局面;2)從每一個N局面出發,存在至少一次可選“活動”到達P局面;3)從每一個P局面出發,每一次“活動”都指向N局面。P局面是必敗局面,而N局面是必勝局面。

由歸納法可知:每一個局面要么是P局面,要么是N局面。

圖博弈(Graph Game)是和DAG(directed acyclic graph)聯繫在一起的。表示為G=(X,F) ,其中X為狀態集合,而F為X上的一個函子,F(x)表示狀態x時所有可能的可選活動能到達的狀態,簡稱x的可選狀態集合(the followers of x)。如果F(x)為空集,則表示x為最終局面。

圖博弈的和(The Sum of n Graph Games):用Gi=(Xi, Fi)表示n個公平組合博弈,i=1~n;記G =(X,F)為n個博弈的和,其中G = G1+···+Gn ,X = X1×···×Xn,F(x)= F(x1,...,xn)= F1(x1) ×{x2}×···×{xn} U ··· ∪{x1}×{x2}×···× Fn(xn).

通過畫圖,可以知道每個公平聯合博弈可以表示為一個圖博弈!

二.SG函數(Sprague-Grundy function)

首先定義集函數mex (Minimal EXclusive):對於由若干自然數組成的集合S,mex(S)表示不在S的最小非負自然數 。

接著定義SG函數SG : V → N 為SG(u) = mex{SG(w) : w ∈ F(u)} = min{n ≥ 0: n != SG(w) for w ∈ F(u)}.

用SG函數可以有效地判斷一個局面是P的還是N的:對一個局面u,1)如果SG(u)=0,則u是P局面;2)如果SG(u)!=0,則u是一個N局面。(用歸納法證明)
SG定理:G =(X,F)為n個公平組合博弈G1,...,Gn 的和,每個Gk (k = 1, 2, . . . , n) 為有限DAG. 則對於每個u = (u1, . . . , un) ∈ G,有
SG(u) = SG(u1) ⊕ . . . ⊕ SG(un).
proof: We divide the proof into two parts

1) For any given nonnegative integer a < b, there is w ∈ F(u) such that SG(w)=a;
2) The set {w |∈ F(u), SG(w)=b} is empty.

the proof of 1): Let d=a⊕b and assume that k(d) is the kth digit in the binary expansion of d, so that 2^(k-1)≤d<2^k. Since a<b, we have k(a)=0 and k(b)=1. Thus, there is at least one is 1 in {k(SG(u1)),...,k(SG(un))},
and WLOG we assume k(SG(u1))=1. Then d ⊕SG(u1)< SG(u1), and by the definition of SG, there exists w1∈ F1(u1)  such that SG(w1)=d⊕SG(u1). The following computation completes the proof:
SG(w1,u2,u3,…,un)=SG(w1)⊕SG(u2)⊕…⊕SG(un)= d⊕SG(u1)⊕SG(u2)⊕…⊕SG(un) = d⊕b= a⊕b⊕b= a
the proof of 2): By contradiction. If there exist w={w1,u2,…,un}(w1 ∈ F1(u1) )∈ {w |∈ F(u), SG(w)=b} , we could get the equation SG(u1)⊕SG(u2)⊕…⊕SG(un) = SG(w1)⊕SG(u2)⊕…⊕SG(un). By the cancellation law, SG(u1)= SG(w1).
三.計算SG函數的算法
sg[v]:=-1 , for all v \in V;
N:=|V|;  sg[sink]=0;
int cal_sg(int x)
{
if(sg[x] != -1) return sg[x];
bool v
= {0};
for(i \in Adj[x])
v[cal_sg(i)] = 1;
sg[x] = 0;
while(v[sg[x]]) sg[x]++;   //compute the mex
return sg[x];
}

四. Some Examples
4.1 Nim
(1)simple take-away game: a pile of N chips. Two players alternate taking some(>0 && <=k) chips. The last player to take wins.
Solve: let x be the position corresponds to the number of the pile. Thus, SG(0)=0;SG(1)=1;......;SG(x)=x%(k+1);...          //O(1)
(2)Nim: n piles of chips (a1,a2,...,an). Two players take turns moving. Each move consists of selecting one of the piles and removing chips from it.You may not remove chips from more than one pile
in one turn, but from the pile you selected you may remove as many chips as desired, from one chip to the whole pile. The winner is the player who removes the last chip.
Solve: position (x1,x2,...,xn).For each xi, we have SG(xi)=xi. Thus,SG(x1,x2,...,xn)=SG(x1)⊕…⊕SG(xn)=x1⊕…⊕xn.         //O(n)
APP1: POJ 2234 (Matches Game)
#include <iostream>        //M:240k      T:16ms
using namespace std;
int main()
{
int M;
long a[21];
while(cin>>M){
int sg=0;
for(int i=1;i<=M;i++){
cin>>a[i];
sg=sg^a[i];
}
sg==0?puts("No"):puts("Yes");
}
return 0;
}

(3)S-Nim:as the same rule of "Nim" except for the constraint of the number of removed chips every time must be in the set S(the subset of N).
Solve:SG(x)=mex{SG(x-S)}
APP2:POJ 2960 (S-Nim)
#include <iostream>       //M:2280K     T:250MS
#include<algorithm>
using namespace std;

int k,m,l;
int si[101],hi[101];
int sg[10001];

int cal_sg(int x)
{
if(sg[x]!=-1) return sg[x];
bool v[1001];          //要在函數內定義并初始化
memset(v,0,sizeof(v));
for(int i=0;i<k;i++){
int temp=x-si[i];
if(temp < 0) break;
v[cal_sg(temp)]=1;
}
sg[x]=0;
while(v[sg[x]]) sg[x]++;
return sg[x];
}

int main()
{
while(cin>>k && k){
for(int i=0;i<k;i++){
cin>>si[i];
}
sort(si,si+k);
memset(sg,-1,sizeof(sg));
cin>>m;
for(int i=0;i<m;i++){
cin>>l;
int temp=0;
for(int j=0;j<l;j++){
cin>>hi[j];
temp=temp^cal_sg(hi[j]);
}
if(temp==0)
cout<<"L";
else
cout<<"W";
}
cout&
4000
lt;<endl;
}
return 0;
}

4.2 Wythoff’s Game? very difficult!
POJ 1067 (Picking Stones)
沒想明白
4.3 Odd the Even
(1)Lyle's Game:
發現“理解了(或懂了)”與“表述”是兩回事,曾嘗試花了十個小時也沒能表述好,這就是創造與學習的區別!以後再表述了……
(2)POJ 1082(Calendar Game):
//從2001.11.4這一天向前推理,猜想跟奇偶性有關,假設每個月是31天的話,有結論:“如果‘月+日=偶數’則必勝,否則必敗。”
//再考慮那些30天的月份,只有09.30和11.30這兩天特殊,都是必勝。
//最後就是leap years了,經研究也是一樣的結論。
#include <iostream>     //232K 0MS
using namespace std;
int main()
{
int n,month,data;
cin>>n;
for(int i=1;i<=n;i++){
cin>>month>>month>>data;
bool Yes=1;
if((month+data)%2) Yes=0;
if((month==9 && data==30)||(month==11 && data==30)) Yes=1;
Yes?puts("YES"):puts("NO");
}
return 0;
}

4.4 poj2425“A chess game”
#include <iostream>       //M:5148k     T:1688ms
using namespace std;
int g[1001][1001];
int N,M;
int sg[1001];
int cal_sg(int x,int n)
{
if(sg[x]!=-1) return sg[x];
bool v[1001];
memset(v,0,sizeof(v));
for(int i=0;i<n;i++)
if(g[x][i])
v[cal_sg(i,n)]=1;
sg[x]=0;
while(v[sg[x]]) sg[x]++;
return sg[x];
}

int main()
{
while(cin>>N){
memset(g,0,sizeof(g));
memset(sg,-1,sizeof(sg));
for(int i=0;i<N;i++){
int tempM;cin>>tempM;
if(tempM==0){
sg[i]=0;continue;
}
for(int j=0;j<tempM;j++){
int tem;cin>>tem;
g[i][tem]=1;
}
}
while(cin>>M && M){
int k=0,position;
for(int i=0;i<M;i++){
cin>>position;
k=k^cal_sg(position,N);
}
k?puts("WIN"):puts("LOSE");
}
}
return 0;
}
4.5 poj1704“Georgia and bob”
#include <iostream>           //244K 0MS
#include <algorithm>
using namespace std;
int T,N;
int a[1001];

int main()
{
cin>>T;
for(int i=1;i<=T;i++){
cin>>N;
a[0]=0;
for(int j=1;j<=N;j++) cin>>a[j];
sort(a,a+N+1);           //Attension: sort a[0],...,a
increasingly
for(int j=N;j>0;j--) a[j]=a[j]-a[j-1]-1;
int ans=0;
for(int j=N;j>0;j=j-2) ans^=a[j];
ans?puts("Georgia will win"):puts("Bob will win");
}
return 0;
}
4.6 poj2348“Euclid game”
//For the given example(25,7),25/7=3>1,thus,whether the position (4,7) is N-position or not,Stan can control which one to reach (4,7).
#include <iostream>    //240K 0MS
using namespace std;
int main()
{
int a,b;
while(cin>>a>>b){
if(a==0 && b==0) break;
if(a==b){cout<<"Stan wins"<<endl;continue;}     //border
if(a<b){int temp=a;a=b;b=temp;}
bool Stan=1;
while(1){          //recursion
if(a/b>1){Stan?puts("Stan wins"):puts("Ollie wins");break;}
int temp=a%b;a=b;b=temp;
if(b==0){Stan?puts("Stan wins"):puts("Ollie wins");break;}
Stan=!Stan;
}
}
return 0;
}
4.7
to be continued
五. Summary
to be continued
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息