1. 程式人生 > >算法筆記--極大極小搜索及alpha-beta剪枝

算法筆記--極大極小搜索及alpha-beta剪枝

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);//取最大值 else
bestvalue=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剪枝