演算法:採取minmax演算法,利用alpha-beta演算法減枝。
原理:首先,演算法是用於計算出當前下棋所產生的最好價值。
那麼,定義自己的價值越高數值越大(正),對手的價值越高數值越小(負)
下棋是你一手我一手的下,根據下棋的步驟,構建決策樹
所謂決策樹就是:每個節點是當前局面的評分,節點的基數層該自己下棋,偶數層該對手下棋
那麼,在遍歷決策樹時,首先要計算第一層能獲取的最大值max
要想獲得第一層,那就遍歷第二層(第二層為根節點所能產生的所有走法的評分)
在第二層中找到最小的那個min(為什麼要找最小的?因為第二層是對手下棋,對手最好的走法,對你來說最壞)
要想找第二層的最小值,那就得遍歷每個節點的第三層,找到第三層中最大的值(因為該你走),然後比較所有max中min的那乙個
這一句可能不太清楚,是說對手會遍歷你下一手的所有走法,然後找到最差的那個(對他最好)。所以是在max中找min
之後一直這樣遍歷
但是如果這樣的話,節點數量會成指數倍增加。效率大大的下降了。
如果每次正常的走法有n個。
那麼第一層節點的個數是1,第二層是n,第三層是n*n,第四層是n*n*n....第n層的節點數將會達到n的n次方。一輩子都算不完了
所以目前的做法有兩個
1、限制搜尋的層數,只搜尋有限層(層數越高當然智慧型越高,速度也越慢)
2、採用減枝(上面說的思路是每次都會遍歷所有子節點,但實際上可以通過一些計算,忽略點大部分節點)
而alpha-beta演算法就是採用了以上方法的minmax改進版
步驟如下:
1、如果要找某個節點(即為某個走法)的最優值(我們稱為alpha或者max),那麼需要首先找出第乙個子節點的alpha值
2、通過同樣的函式,計算子節點(對手的走法)中最好的值(但對我們來說是最壞的),取反。然後和當前的alpha和beta值比較
3、如果大於當前的beta值,說明如果選擇這一步,那對手就會走出對我們更不利的局面,那麼基於這個節點的所有子節點都拋棄掉(減枝)
4、如果大於當前的alpha值,說明找到了更好的走法,把當前的alpha設定為該值,然後繼續找剩下的走法。
5、返回alpha值,即為最好的走法。
6、重複尋找,一直達到最大深度。
考慮例子:
假設有n個袋子,每個袋子有n個物品(用於模擬下棋,袋子即為走法,物品即為走法的價值)
規則是你可以看所有的物品,然後選擇你想要的袋子,然後從袋子中拿走價值最低的那乙個。
很顯然,最簡單的做法是檢視所有的袋子,找出每個袋子中,價值最低的物品(min)
然後在這些物品中選擇相對來說最好的(max)物品所在的袋子。這就是minmax演算法
規則很簡單,演算法也很簡單。但如果袋子和物品很多,需要很多時間才能全部看完並且比較完價值。
如果有時間限制:比如需要在10分鐘之內做出決定,那顯然目前是辦不到的。
其實可以換種辦法。
首先檢視第乙個袋子中全部的物品,找出其中價值最小的物品(設max和min都為它)
然後從第二個袋子拿出乙個物品,如果這個物品的價值比min還小,那根據規則(所得物品為袋子中價值最少的物品)
你從這個袋子中獲得的物品的價值肯定是小於或者等於這個物品,也就是說肯定小於min
如果比min大,那就繼續查詢剩餘的物品,直到找到乙個比min還小的物品,那就捨棄這個袋子,或者找完所有物品。
找出其中價值最小的,與max比較,如果大於max,則表示選中這個袋子,價值更高。把max設定為這個物品的價值
重複找之後的袋子,直到找完。這時候,max物品所在的袋子就是你要選擇的袋子
當然,這個例子只是簡單的描述alpha-beta演算法,而且只是depth為1的情況。
以下是模擬演算法:
難點在於alpha和beta的位置不斷的互相轉變,值也在取反。
需要理解了這個函式的引數意義,以及該博弈樹是由自己和對手輪流走,引數的演算法樹
而且對手走的價值高的棋,對於我們來說是最低的
depth:當前層深度
max:當前能找到的最好值(也叫alpha)
min:當前能找到的最壞值(也叫beta)
(之所以取相反數,是因為正值表示對一方有利,負值表示對另一方有利)
// 計算對於當前走法的最佳價值
int alpha(int depth, int max, int min)
makeallpass(); // 產生所有走法
foreach ( pass p in allpass ) // 遍歷所有的走法
// 如果這個最壞值,比現在的max還要好,那就取這個值為max
if ( v > max )
}return max;
}寫的有點暈,大體上就是這麼回事了~~
演算法用於五子棋遊戲:
演算法框架其實已經搭建好了,需要實現的函式有
getcurrentvalue():用於計算當前走法的價值
makeallpass():用於產生所有有效的走法
dopass(pass):下一步棋
undopass(pass):悔一步棋
詳解alpha beta演算法
最近在做中國象棋對弈程式,用到了alpha beta演算法。在網上搜尋了很多但是智商的因素讓我無法清除的弄明白。今天我的人機對弈終於完成了,我把我對alpha beta演算法的理解寫出來。希望大神們有什麼不同的意見能夠指出來,幫助我改正加深我對演算法的理解,小弟先行謝過。首先貼出如下這幅圖,我會細緻...
AlphaBeta剪枝演算法
關於alphabeta剪枝的文章太多,這個方法是所有其它搜尋方法的基礎,得多花些時間認真地理解。先把基本概念再回顧一遍 節點 在中國象棋中就是乙個棋盤的當前局面board,當然該輪到誰走棋也是確定的。這裡的圓形節點表示終止節點,在中國象棋裡就是一方被將死的情況 或者到達了搜尋的最大深度 後續不會再有...
數獨c 解決 dfs 減枝
刷華為的機試題 傳送門 數獨 刷到了乙個關於數獨的題目,以為數獨還有什麼特殊的解,自己寫了個減枝的dfs過了83 的資料,但是好多同學都有同樣的問題,估計使題目的問題把,這題有多解但是做法不同,就有不同的答案,但是答案都是正確的,然後test有只有乙個這就很惱火,所以就假裝我這是正確的吧。以前聽說過...