1. 程式人生 > 其它 >Maven pom檔案的scope

Maven pom檔案的scope

轉自https://www.cnblogs.com/lfri/p/10662291.html

博弈論的題目有如下特點:

  1. 有兩名選手
  2. 兩名選手交替操作,每次一步,每步都在有限的合法集合中選取一種進行
  3. 在任何情況下,合法操作只取決於情況本身,與選手無關
  4. 遊戲敗北的條件為:當某位選手需要進行操作時,當前沒有任何可以執行的合法操作

下面介紹幾個經典的博弈。

巴什博弈(Bash Game)

一堆n個物品,兩個人輪流從中取出1~m個,最後取光者勝(不能繼續取的人輸)。

同餘定理:n=k(m+1)+rn=k∗(m+1)+r,先者拿走rr個,那麼後者無論拿走1m1m個先者只要的數目使和為m+1m+1,那麼先手必贏。反之若

n=k(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)。從這些必輸局勢可以發現,每組的第一個是前面沒有出現的最小正整數,ak=[k(1+5–√)/2],bk=ak+k,k=0,1,2,3...

ak=[k∗(1+5)/2],bk=ak+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)|yx}sg(x)=mex{sg(y)|y是x的後繼}

SG函式的求法

  1. 找出必敗態
  2. 找出當前所有狀態的前驅結點
  3. 根據定義計算結點SG值
  4. 重複上述步驟,直到整棵樹建立完成

按上述步驟建成的樹如下:

這顆樹有什麼意義呢?比如說我們將一個頂點放在根節點上,當前這個點的sg值為0,說明當前這個點是必敗態。為什麼這麼說呢?我們將這個點交替進行移動,先手有兩種選擇,往右移動,顯然後手再移動一步就進入必敗態;往左移動,後手會選擇往右移動,先手同樣進入必敗態。

如何通過SG函式值來解決之前的有向圖問題呢?對於n個棋子,設它們對應的頂點的SG函式值分別為{a1,a2,...an}{a1,a2,...an},再設局面{a1,a2,...an}{a1,a2,...an}時的Nim遊戲的必勝策略是把aiai變成kk,那麼原遊戲的一種必勝策略就是把第ii枚棋子移動到一個SG值為kk的頂點。

簡單來說,我們讓每個結點都擁有一個SG值(假設這個值為xx),那麼對於任何一個玩家操作(移動到當前結點的某個後繼結點)實際上就是把棋子移動到0~x-1的某個結點上,等價的就是從x個物品中取走一個,最多x個!。

不是是覺得有點不對,單根據mex的定義,可能出現如下情況,移動到比自身SG值大的結點:

其實這種情況是不存在的,博弈問題中先手不會移動到對自己不利的局面的,在這裡也就是不會移動到SG值為4的結點。

SG定理:所以我們可以定義有向圖遊戲的和。設G1,G2,...GnG1,G2,...Gn為n個“有向圖”遊戲的和(Sum),遊戲G的移動規則是:任選一個子遊戲GiGi並移動上面的棋子。SG定理就是:sg(G)=sg(G1)sg(G2)....sg(Gn)sg(G)=sg(G1)∧sg(G2)∧....∧sg(Gn)。也就是說,遊戲的SG函式值就是它的所有子游戲的SG函式值的異或。

因此,當我們面對n個不同遊組成的遊戲時,只需要求出每個遊戲的SG函式值,把這些SG值都看作Nim的石子堆,然後依照找Nim遊戲的必勝策略的方法來找這個遊戲的必勝策略。