minimax算法及α-β剪枝算法

minimax算法通常用于二人博弈游戏中,如井字棋,chomp游戏等。我对这个算法的理解是这样的:(以人和电脑下棋为例)
电脑要确定哪一步下棋使得优势最大,假设棋盘大小为nxm,不

考虑其他因素,那么电脑要对这nxm个位置进行评估,筛选出

最佳位置(有多个位置任选其一),评估的办法就是让电脑模拟

出所有可能的情况,可以想象成电脑(甲)在和电脑自己(乙)下

棋,甲和乙的智力水平是一样的,意思是甲和乙对位置的评估算

法一样,甲想让自己的优势尽可能大,乙想让甲的优势尽可能

小,甲在全面考虑了乙的所有下子可能后下子,反过来乙也是如

此,因为是自己和自己下棋嘛。(因此minimax算法又叫做悲观的

算法,因为每一步都建立在对方充分理性的前提下,实质上对方

如果是人类很难每一步都做到完美)

说了一堆没用的话…举个例子:
甲乙两人玩一个游戏,他们拿到的钱的乘积是定值 24(比如甲3

块钱,乙就8块钱)现在有3个袋子A,B,C,A里面有钱:(3,6),

B:(6,8)C:(4,12),先让乙从3个袋子里面各选出一个数字,然后再

让甲从乙选出的数字里面选,最后甲得到的钱就是他所选的钱。如

下图:甲从乙给出的数字中取最大值,乙从所给数字中取最小值
1下面是我制作井字棋里面的minimax函数代码(完整的代码贴在末尾)

int DealInfor::minmax(int h,std::vector<std::vector<int>>map,bool isMax,
                      int x,int y)  //h是搜索深度,空棋盘初始深度为0,有一个棋子深度就加1
//map存储了棋盘上面的所有棋子,AI的棋子记为-1,玩家的棋子记为1,
//isMax为true时,轮到AI下子,AI要从玩家所返回的值中取最大值(max),玩家要从AI所返回的值中取最小值(min)
//因为这个分值是对AI而言的,所有AI胜利加10分,玩家胜利那么AI减10分
{
   int comp=-10;
if(isMax==true){
    map[x][y]=-1;
    int ResentScore=isAIWin(map);
if(h==8)
    return ResentScore;
if(ResentScore==1)
    return 10;
    for(int i=0;i<TBlockNum;++i){
        for(int j=0;j<TBlockNum;++j){
            if(map[i][j]==0){
                int NextScore=minmax(h+1,map,false,i,j);
                if(NextScore==-10)  //判断出玩家胜利,返回-10,因为-10是最小的值,会被max给舍弃掉,
                  return -10;  //即这条路不能帮助AI胜利,要舍弃
                else
                comp=max(comp,NextScore);
            }
        }
    }
}
else{
    comp=10;
    map[x][y]=1;
    int ResentScore=isAIWin(map);
if(h==8)
    return ResentScore;
if(ResentScore==-1)
    return -10;
    for(int i=0;i<TBlockNum;++i){
        for(int j=0;j<TBlockNum;++j){
            if(map[i][j]==0){
                int NextScore=minmax(h+1,map,true,i,j);
                if(NextScore==10)   //判断出AI胜利,返回10
                    return 10;
                comp=min(comp,NextScore);
            }
        }
    }
}
return comp;

}`

α-β剪枝算法是针对minimax算法而言的,还拿上面那个图举例子
2因为minimax算法是深度优先遍历的(就是一条路走到底,看看是输还是赢),我们可以在之前minimax函数的基础上再加两个参数a,b(α,β)a表示之前游戏中甲所能取到的下限,就是甲最少也能拿到的钱数,b表示乙所能取得的数值的上限,不能再多了,不然钱都让甲拿走了。这里就拿a举例说明:(最开始main函数调用的时候,可以设置a=-1000,b=1000这样的)

当乙在A中选择完毕之后,甲至少能拿到3块钱,这时更新a的值为3(这里的a是甲所调用的minimax函数,就是图片中的第一层(‘’6‘’)),之后乙在B中选择完毕后,更新a的值为6(一样是第一层的a),接着当乙对C进行选择时,碰到的第一个数是4,b=4,因为4<6,即出现了b<a的情况这个时候直接跳出循环,(因为a=6意味着甲至少能拿到6块钱,而乙在C中不管遇到什么最多也就返回4,不可能让甲拿到更多的钱)不需要再判断后面的“12”了,即把“12”这个枝给剪掉了。

这个是用qt(C++代码)写的,后面那个chomp游戏,代码里面函数名字没有取好,不用在意函数名字(chomp游戏在《离散数学及其应用》中有提及)
井字棋
Chomp

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值