minimax算法通常用于二人博弈游戏中,如井字棋,chomp游戏等。我对这个算法的理解是这样的:(以人和电脑下棋为例)
电脑要确定哪一步下棋使得优势最大,假设棋盘大小为nxm,不
考虑其他因素,那么电脑要对这nxm个位置进行评估,筛选出
最佳位置(有多个位置任选其一),评估的办法就是让电脑模拟
出所有可能的情况,可以想象成电脑(甲)在和电脑自己(乙)下
棋,甲和乙的智力水平是一样的,意思是甲和乙对位置的评估算
法一样,甲想让自己的优势尽可能大,乙想让甲的优势尽可能
小,甲在全面考虑了乙的所有下子可能后下子,反过来乙也是如
此,因为是自己和自己下棋嘛。(因此minimax算法又叫做悲观的
算法,因为每一步都建立在对方充分理性的前提下,实质上对方
如果是人类很难每一步都做到完美)
说了一堆没用的话…举个例子:
甲乙两人玩一个游戏,他们拿到的钱的乘积是定值 24(比如甲3
块钱,乙就8块钱)现在有3个袋子A,B,C,A里面有钱:(3,6),
B:(6,8)C:(4,12),先让乙从3个袋子里面各选出一个数字,然后再
让甲从乙选出的数字里面选,最后甲得到的钱就是他所选的钱。如
下图:甲从乙给出的数字中取最大值,乙从所给数字中取最小值
下面是我制作井字棋里面的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算法而言的,还拿上面那个图举例子
因为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