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