极大极小搜索+alpha beta剪枝详解 模板:csp 棋局评估

博弈形式:双方轮流操作,我方目的是让自己的得分最大化,敌方目的是让我方的得分最小化。然后评估当前形势下的最终最多得分。

解法:

暴力极大极小dfs:

最容易想到的就是对所有棋局(以下棋为例)进行dfs搜索,当我方下的时候,就选择当前子状态中得分最高的一种,当敌方下的时候,当然便是选择子状态中得分最低的一种。
那么,我们就可以把整棵dfs搜索树分布为MAX层和MIN层交替进行,在我方下的时候,为MAX层,选择所有子节点中权值最大的一个作为当前节点的值。敌方下的时候则相反。
大体形式为:判断是否达到最终状态,达到了则返回得分,回溯。未达到则遍历所有子节点,找到子节点中的最大得分或最小得分,返回得分,回溯。
这便是极大极小搜索的大体过程,一种接近暴力的棋局搜索,时间复杂度取决与棋局大小,大约为n2logn,搜索层数为n2

apha beta剪枝:

如果暴力搜索,将会产生很多没用的节点,也就是MAX层或MIN层绝对不会去选择的节点,这些节点造成了大量的时间和空间的浪费。那么最好的解决方案就是去掉这些节点,不对其进行搜索。
那么我们就需要思考到底是去掉哪些节点呢?以当前层为MIN层的节点2为例,此节点的目的当然是找到子节点中的最小值,且它的下一层和上一层一定是MAX层。

假设当前节点2的取值最终为5,那么它的父节点1的取值一定最少为5,因为父节点为MAX层,会选择子节点中最大的一个。
那么,回溯到了父节点1(>=5),那么进入下一个子节点3,继续搜索,在找到3的第一个子节点4的时候,发现它的值为3,那么也就是说,3号节点的值最多为3(暂且不看其它节点)。进而可以说,1号节点绝对不会选择3号节点作为它的取值,以为1号的值现在最少是5了,为啥要去选择一个取值最多只有3的节点呢?

3号节点作废,无需继续搜索3号节点,可以直接回溯到1号节点了。

好,那么怎么判断是否废除当前节点的进一步搜索呢?
我们可以发现,3号节点废除的原因是它的最大取值小于了它的父节点1的最小取值,所以废除。

3号节点是MIN层节点,那么MAX层节点如何呢?
如果一个MAX层节点的最小取值大于了它的父节点(MIN层)的最大取值,那么这个节点当然也会被废除,因为父节点取得是最小值,已存在另外一个肯定更小的子节点,那么何必取这个节点呢。

OK,让我们思考一下如何记录吧。
在每一个节点上,我们都设定一个 a:当前节点上界,一个 b:当前节点下界。
并且以传参的方式,将父节点当前的a和b原封不动地传给子节点,这样就可以得知当前节点的父节点的上下界了。

在MAX层,我们更新b,不断取子节点中的更大的值保存在下界b中,若出现了上界a小于下界b的情况,就说明当前节点的最小取值已经大于了其父节点的最大取值,停止当前搜索,废除当前节点,直接返回b。
同样,在MIN层,我们更新上界a即可,遇到a小于b则回溯。

剪枝就大功告成啦。
上模板:

int st[4][4];

int dfs(int div,int a,int b,int who)
{
   
    if(full(st))   	//终局判断
        return 0;
    int tans;
    int x,y;
    if(who>0)	//我方下,即为MAX层
    {
   
        for(x=1;x<=3;x++)
        {
   
            for(y=1;y<=3;y++)
            {
   
                if(st[x][y]!=0)
                    continue;
                st[x][y]=who;
                tans=win(st);
                if(tans!=0)
                {
   
                    b=max(b,tans);	//更新下界
                }
                else
                {
   
                    b=max(b,dfs(div+1,a,b,-1*who));
                }
                st[x][y]=0;
                if(a<=b)	//废除当前节点,回溯
                    return b;
            }
        }
        return b;	//无废除,正常回溯
    }
    else	/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值