算法筆記--極大極小搜索及alpha-beta剪枝
阿新 • • 發佈:2018-12-21
cor article posit oss else hab alt 葉子節點 知乎
參考1:https://www.zhihu.com/question/27221568
參考2:https://blog.csdn.net/hzk_cpp/article/details/79275772
參考3:https://blog.csdn.net/BIT1120172185/article/details/80963609
極小極大搜索算法即minimax搜索算法
主要應用於零和博弈(非勝即負,如圍棋,象棋,井子棋等),完全信息(玩家知道之前所有的步驟。象棋就是完全信息,因為玩家是交替著落子,且之前的步驟都能在棋盤上體現)
這個算法采用搜索算法遞歸實現,一層為先手,記為a, 一層為後手,記為b, 交替出現
對於最終局面,有一個分數(比如:先手勝分數為1, 平局分數為0,先手輸分數為-1)
先手a想要讓這個分數越大越好,後手b想要讓這個分數越小越好,於是搜索到先手這一層,取最大返回,搜索到後手這一層,取最小返回
如下圖:
於是偽代碼為:
int MaxMin(position,int d) { int bestvalue,value; if(game over) //檢查遊戲是否結束 return evaluation(p);// 遊戲結束,返回估值 if(depth<=0) //檢查是否是葉子節點 return evaluation(p);//葉子節點,返回估值 if(max) //極大值點 bestvalue=-INFINTY; else //極小值點 bestvalue=INFINTY; for(each possibly move m) { MakeMove(m); //走棋 value=MaxMin(p,d-1); UnMakeMove(m); //恢復當前局面 if(max) bestvalue=max(value,bestvalue);//取最大值 elsebestvalue=min(value,bestvalue);//取最小值 } return bestvalue; }
關於alpha-beta剪枝:
如果當前層為取最小,如果取最小後比上一層當前最大值還小,則不需要往下搜索,因為上一層根本不會選擇當前節點往下搜,還有更好的選擇
同理,如果當前層為取最大,如果取最大後比上一層當前最小值還大,則不需要往下搜索,因為上一層根本不會選擇當前節點往下搜
具體推薦看最上面的知乎鏈接點贊最多的回答。
alpha-beta剪枝後的偽代碼:
int AlphaBeta(nPlay,nAlpha,nBeta) { if(game over) return Eveluation; //勝負已分,返回估值 if(nPly==0) return Eveluation; //葉子節點返回估值 if(Is Min Node) //判斷 節點類型 { // 極小值節點 for(each possible move m) { make move m; //生成新節點 score=AlphaBeta(nPly-1,nAlpha,nBeta)//遞歸搜索子節點 unmake move m;//撤銷搜索過的節點 if(score<nBeta) { nBeta=score;//取極小值 if(nAlpha>=nBeta) return nAlpha;//alpha剪枝,拋棄後繼節點 } } return nBeta;//返回最小值 } else {//取極大值的節點 for(each possible move m) { make move m; //生成新節點 score=AlphaBeta(nPly-1,nAlpha,nBeta)//遞歸搜索子節點 unmake move m;//撤銷搜索過的節點 if(score>nAlpha) { nAlpha=score;//取極小值 if(nAlpha>=nBeta) return nBeta;//nBeta剪枝,拋棄後繼節點 } } return nAlpha;//返回最小值 } }
算法筆記--極大極小搜索及alpha-beta剪枝