博弈论经典算法(一)——对抗搜索与Alpha-Beta剪枝
前言
在一些復雜的博弈論題目中,每一輪操作都可能有許多決策,于是就會形成一棵龐大的博弈樹。
而有一些博弈論題沒有什么規律,針對這樣的問題,我們就需要用一些十分玄學的算法。
例如對抗搜索。
對抗搜索簡介
一、 對抗搜索的適用范圍
在博弈論題目中,如果決策雙方的獲勝條件是截然相反的,即一方要求得分越高越好,另一方要求得分越低越好,這時我們就可以用上對抗搜索算法。
二、對抗搜索的主要思想
對抗搜索的核心思想就是\(dfs\)遍歷一遍博弈樹。
不難想到,如果博弈樹非常龐大,在不加優化的情況下,對抗搜索的時間效率是十分低下的。
因此,我們就需要對對抗搜索進行一定的優化。
三、對抗搜索的優化
對抗搜索的優化一般來講有兩種:記憶化和 \(Alpha-Beta\)剪枝 。
不過需要注意,如果兩個優化一起使用,很可能會產生化學反應出現一些奇妙的\(Bug\)(我已經親身體驗過了)。
對抗搜索優化一:記憶化
記憶化應該是搜索中一個比較常用的技巧。
一、大致思路
它的大致思路就是,對于當前的某一種狀態,在求解后將結果記錄下來,下一次再訪問到時直接將存下來的結果返回即可。
二、模板
記憶化優化對抗搜索的偽代碼如下:
inline int dfs(Status s,int Which)//Status記錄當前狀態,Which記錄當前操作的選手,其中0號選手取Max,1號選手取Min {if(res[s]) return res[s];//如果之前已經求出過這個狀態的結果,直接返回if(IsEnd(s)) return GetVal(s);//如果當前狀態已經為最終狀態,就返回當前狀態的分值register int i,ans=Which?1e9:0;expend(s);//擴展當前狀態,并將新狀態存儲于NewStatus數組中,用NewStatusTotal記錄新狀態的數量for(i=1;i<=NewStatusTotal;++i)//枚舉從當前狀態能夠擴展到的新狀態ans=Which?min(ans,dfs(NewStatus[i],Which^1):max(ans,dfs(NewStatus[i],Which^1);//不斷dfs,更新ansreturn res[s]=ans;//將最終求解出的結果存儲下來 }對抗搜索優化二:\(Alpha-Beta\)剪枝
\(Alpha-Beta\)剪枝應該是對抗搜索一個比較巧妙的優化。
一、大致思路
如圖是一棵博弈樹:
假設第一個決策者的目的是取最大值,第二個決策者的目的是取最小值。
在搜索完根節點的兩個子節點后,博弈樹就會變成這樣:
這時,我們再來看根節點的第三個子節點。
不難發現,在處理完第三個節點的第一個子節點之后,第三個節點的權值就會變成\(2\)。
因為第三個節點的目標是取最小值,因此最終第三個節點的權值必定小于等于\(2\)。
而根節點的目標是取最大值,且此時根節點的權值已經為\(3\)了。
也就是說,第三個節點對最終答案肯定是沒有任何貢獻的。
因此對于第三個節點的剩余兩個狀態,我們就無需繼續搜索了,可以直接退出。
這就是傳說中的\(Alpha-Beta\)剪枝了。
二、模板
\(Alpha-Beta\)剪枝優化對抗搜索的偽代碼如下:
inline int dfs(Status s,int Alpha,int Beta,int Which)//Status記錄當前狀態,Which記錄當前操作的選手,其中0號選手取Max,1號選手取Min //Alpha存儲較大值,Beta存儲較小值 //如果當前節點是取Max的節點,則Alpha表示當前節點父親的父親的權值,Beta表示當前節點父親的權值 //如果當前節點是取Min的節點,則Alpha表示當前節點父親的權值,Beta表示當前節點父親的父親的權值 {if(IsEnd(s)) return GetVal(s);//如果當前狀態已經為最終狀態,就返回當前狀態的分值register int i;expend(s);//擴展當前狀態,并將新狀態存儲于NewStatus數組中,用NewStatusTotal記錄新狀態的數量for(i=1;i<=NewStatusTotal;++i)//枚舉從當前狀態能夠擴展到的新狀態{t=dfs(NewStatus,Alpha,Beta,Which^1);//求出當前枚舉到的新狀態的分值(s.Which?Beta=min(Beta,t):Alpha=max(Alpha,t)); //如果當前節點取min,就更新Beta,否則更新Alphaif(Alpha>=Beta) break;//如果Alpha≥Beta,就說明這個節點對最終答案沒有貢獻了,就結束搜索}return s.Which?Beta:Alpha;//返回相應值 }后記
對抗搜索的核心內容差不多也就是這些。
但是,如果真正用起來,對抗搜索其實還是挺復雜的。
下面推薦一道例題:【BZOJ3106】[CQOI2013] 棋盤游戲
轉載于:https://www.cnblogs.com/chenxiaoran666/p/AlphaBetaDFS.html
總結
以上是生活随笔為你收集整理的博弈论经典算法(一)——对抗搜索与Alpha-Beta剪枝的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++常见操作的模板
- 下一篇: React 项目使用 React-rou