算法笔记--极大极小搜索及alpha-beta剪枝

参考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;//返回最小值 
    } 
} 

猜你喜欢

转载自www.cnblogs.com/widsom/p/10153159.html
今日推荐