實用演算法實現 第 15 篇 對抗搜尋

2021-05-28 16:09:33 字數 4469 閱讀 7675

《人工智慧,一種現代方法》對於對抗搜尋的介紹非常好。

極大值極小值策略是一種最優策略。當對手不犯錯誤時,最優策略能夠導致至少不比其它任何其它策略差的結果。需要注意的是,最優策略針對的是最優化對手:如果使用極大值極小值策略對付非最優化對手,可能沒有使用其它策略好,但是使用那些策略對付最優化對手必定要比極大值極小值策略差。

極小值極大值策略是指存在兩個最優化的博弈對手min和max,min的目的是使得value最小,而max則是使得value最大。由於兩個對手都不會犯錯誤,即採用最優策略,故此有如下公式:

不難發現使用極小值極大值策略實際完成的是對策略空間的一種深度優先搜尋。

對於兩個使用最優策略的博弈者,乙個博弈的value的最終結果總是確定的。而極大值極小值搜尋則是通過搜尋博弈樹,來找出博弈的value的最終結果。極大值極小值搜尋進行dfs搜尋,一直深入搜尋到葉子。如果結點的所有子樹已搜尋完畢,則該結點回溯到父結點。該搜尋從初始狀態,經過搜尋過程p,達到當前狀態s,搜尋至當前結點n。可以知道,搜尋過程p唯一地決定了當前狀態s,而s狀態正在考察結點n。

為了減少不必要的搜尋,對博弈樹的搜尋進行α-β剪枝。每個結點n都維持兩個變數α和β。α和β表示通過搜尋過程p,在搜尋進行到當前狀態s時,max和min探索清楚的value值的一些情況。α的意義是:如果博弈過程為p,那麼博弈到結點n時,max所能保證的value的最小值為α。β的意義是:博弈過程為p,那麼博弈到結點n時,min所能保證的value的最大值為β。

在維護α和β的之後,可以發現有一些情況可以不必再搜尋子樹而直接回溯到父結點。當搜尋到結點n時,雙方已經博弈到第n步。

1. 如果結點n是max,且發現n的某子樹返回的vlaue的值v比β還大,它可以斷定在第n-1步min做決定的時候不會讓max有這種機會。因為在第n-1步,min就知道存在著乙個策略d,使得value值為β;如果v比β大,min會毫不猶豫地採用d策略。

2. 如果結點n是min,且發現n的某子樹返回的vlaue的值v比α還小,它可以斷定在第n-1步max做決定的時候不會讓min有這種機會。因為在第n-1步,max就知道存在著乙個策略d,使得value值為α;如果v比α小,max會毫不猶豫地採用d策略。

上述結論對於第n = 1步也是成立的,因為此時α取為取為-∞,β取為+∞,α-β剪枝的條件不可能滿足。

pku judgeonline, 1085, ******** war.

如上圖,a、b進行博弈。如果某人連線兩點之後完成乙個三角形,則得一分,且再需走一步。得分多的人獲勝。

先給定一些已經走好的步驟,求最後誰勝。46

24 45

59 36

25 35

724

45 59

36 25

35 78

612

23 13

24 25

45 10

12 25

36 58

47 610

24 45

48 7 8

game1: b wins.

game2: a wins.

game3: a wins.

game 4: b wins.

標準的極大值極小值策略問題。考慮到時間複雜度,對博弈樹進行α-β剪枝。

為了儲存和表示的方便,對每個連線編號為1~18。每個連線又對應到9個三角形的三邊。使用link這個陣列來儲存這些資料。

例如連線(1,2)為第1個連線,這個連線是第1個三角形的左邊。

(1,3)為第2個連線,這個連線是第1個三角形的右邊。

(2,3)為第3個連線,這個連線是第1個三角形的中邊,也是第3個三角形的中邊。

依次表示為如下資料:

1 1 l

1 1 r

2 1 m 3 m

1 2 l

2 2 r 3 l

2 3 r 4 l

1 4 r

2 2 m 6 m

2 4 m 8 m

1 5 l

2 5 r 6 l

2 6 r 7 l

2 7 r 8 l

2 8 r 9 l

1 9 r

1 5 m

1 7 m

1 9 m

其中,第1個數表示該邊是幾個三角形的邊,第2個(或者第4個)數表示該邊是哪個三角形的邊。第3個(或者第5個)數表示該邊是該三角形的那條邊(左l、右r、中m)。

可一直到一條連線最少是一條三角形的邊,最多是兩條三角形的邊。表示是三角形的那條邊(邊的編號)需要3 bits,表示是哪個三角形(共9個三角形)需要4 bits。故此每個連線只要14 bits就可以表示這些資訊,用乙個int就可以了。用callink()函式計算成int,int的表示形式是:

18 bits 0         3bits                4 bits          3bits             4bits

邊的編號      三角形編號    邊的編號     三角形編號

本題目不僅可以對博弈樹進行α-β剪枝,而且由於得分的具體數目不重要,重要的只是輸贏,所以可以同時進行另乙個剪枝:

需要注意這種情況:給的初始狀態已經表明a或者b已經獲勝。

2^18種可能,每種可能需要2 bit。乙個bit為是否搜尋過,另乙個bit為搜尋結果(贏1或者輸0)。用char變數表示。每個char儲存四個可能。故此指標位置為:table[key >> 2]& (3 << ((key & 3) * 2))

#include #include #include #include using namespace std;

#define max 0x7ffffff

const int link[19] =

;int tri[10];

#define tri_mask 15

#define direction_mask 7

#define tri_bit 4

#define direction_bit 3

bool used[19];

int addstick(int pos)

l = l >> direction_bit;

p = l & tri_mask;

if(p != 0)

}returnscore;

}void removestick(int pos)

}int originstep;

#define lowest 5

#define highest 4

int minvalue(int step, int basevalue, intalpha, int beta);

int maxvalue(int step, int basevalue, intalpha, int beta)

n = addstick(i);

if(n> 0)else

removestick(i);

if (max< t )

max = t;

if(max+ basevalue >= beta)

if(alpha< max + basevalue)

if(alpha> highest)

}return max;

}int minvalue(int step, int basevalue, intalpha, int beta)

n = addstick(i);

if(n> 0)else

removestick(i);

if (min> t)

min = t;

if(min+ basevalue <= alpha)

if(beta> min + basevalue)

if(beta< lowest)

}return min;

}#define left 0

#define right 1

#define middle 2

const int dot[19][2] =,

, ,,

, , , ,

, ,, , , , , ,

, , };

int callink()

elseif(c == 'r')else

pos = 1 << pos;

result = result << 7;

result |= (pos << 4) |index;

}cout << result << ", ";

}return 1;}

int main()

}n = addstick(j);

if(n== 0)elseelse}}

printf("game%d: ", k);

if(losed<= 4 && originvalue <= 4)else

if(originvalue> highest)elseif(originvalue < lowest)else

}else if(originvalue > 4)else

printf("wins.\n");

}return 1;

}

實用演算法實現 第 10 篇 動態規劃

pku judgeonline,1160,post office.一條直線上分布著v個村莊。要在這些村莊中的某些村莊裡建一共p個郵局,使得村莊到離它最近的郵局的距離之和最小。輸出這個的最小距離之和。10512 3 6 7 9 11 22 44 50 思路 用opt i j 記錄把前i個郵局建到前j個...

實用演算法實現 第 10 篇 動態規劃

pku judgeonline,1160,post office.一條直線上分布著v個村莊。要在這些村莊中的某些村莊裡建一共p個郵局,使得村莊到離它最近的郵局的距離之和最小。輸出這個的最小距離之和。10512 3 6 7 9 11 22 44 50 思路 用opt i j 記錄把前i個郵局建到前j個...

實用演算法實踐 第 32 篇 其它

pku judgeonline,1702,eva sbalance是乙個平衡三進製問題的例項。將乙個某進製數轉換為平衡三進製數的方法為 先轉化為用0,1,2表示的3進製,然後通過 借位 轉換。也即 若對應的係數為2,則變為 1,高一位 1。若對應的係數為3,則變為0,高一位 1。為0或1時不變 pk...