[笔记]极大极小过程的alpha-beta剪枝不可与记忆化搜索一起使用
今天做SGU 423,WA得我眼淚汪汪。后來發(fā)現(xiàn)原來這個問題很早就被何牛提到過:
極大極小過程的alpha-beta剪枝不可與記憶化搜索一起使用。
原因是這樣的:
在一個博弈圖中,可能存在這樣的情況:一個狀態(tài)有不止一個前繼。
比如,設(shè)狀態(tài)u和狀態(tài)v都可以轉(zhuǎn)移到同一個狀態(tài)w。
假設(shè)極大極小過程先搜索到u,為了得到u的估值f(u),我們要搜索w并且給本次搜索一個估值上界beta(u),一旦在w的搜索過程中發(fā)現(xiàn)f(w)當(dāng)前值>=beta(u),則立刻停止搜索因?yàn)閒(u)的估值不會用到w這個分支。這就是alpha-beta剪枝。
但是請注意,此時并不保證f(w)的正確性,我們僅僅知道f(w)>=beta(u)而已。這次剪枝僅僅保證u的搜索結(jié)果的正確性。
為了得到v的估值f(v)我們會再次搜索到w,注意此時所給的估值上界是beta(v)而不是beta(u),也就是這兩次搜索對于w的限制是不同的。如果使用記憶化,就相當(dāng)于默認(rèn)f(w)為精確值。但是由于之前的剪枝,我們得到的僅僅是f(w)的一個界而已,這里就會出現(xiàn)錯誤。更確切地,當(dāng)beta(v)>beta(u)時,就會由于u與beta(u)對于w的限制被記憶,導(dǎo)致計(jì)算v的估值所需要的w的信息被誤剪。
T_T
順便貼個alpha-beta剪的思路模板吧:
//alpha-beta剪枝 //不可以和記憶化搜索混用 //需要在外部記錄狀態(tài)(局面以及當(dāng)前先手者),通過make_move和unmake_move函數(shù)進(jìn)行改變。 int ab(int alpha, int beta, int depth, bool pass) {// 當(dāng)前最佳估值,預(yù)設(shè)為負(fù)無窮大int best = -INF;// 如果到達(dá)預(yù)定的搜索深度if (depth <= 0) {// 計(jì)算出估值return eval();}// 嘗試每個后繼狀態(tài)foreach (move) {// 試著走后繼狀態(tài)if (make_move(move)) {// 如果合法,對所形成的局面進(jìn)行遞歸搜索int now = -alpha_beta(-beta, -alpha, depth-1, 0);// 恢復(fù)原來的局面 unmake_move(move);// 如果這步棋引發(fā)剪枝if (now >= beta) {// 停止對當(dāng)前局面的搜索,立即返回。return now;}// 如果這步更好if (now > best) {// 保存更好的結(jié)果best = now;// 更新估值下限if (now > alpha) {alpha = now;}}}}// 如果沒有合法后繼,則此步為棄著if (best == -INF) {// 如果上一步也是棄著,表明對局結(jié)束if (pass) {// 計(jì)算出精確值return calc();}// 否則這步棋棄著,局面不變先后手互換 make_move(PASS_MOVE);// 遞歸搜索,并標(biāo)明該步棄著。best = -alpha_beta(-beta, -alpha, depth, 1);// 恢復(fù)原來的局面 unmake_move(PASS_MOVE);}// 返回最佳估值return best; }轉(zhuǎn)載于:https://www.cnblogs.com/jffifa/archive/2012/08/01/2618960.html
總結(jié)
以上是生活随笔為你收集整理的[笔记]极大极小过程的alpha-beta剪枝不可与记忆化搜索一起使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET中常用的26个优化性能方法
- 下一篇: 一些Web Service的经验