极大极小搜索策略一般都是使用在一些博弈类的游戏之中:
理论上可以穷举所有的走法,这就需要生成整棵博弈树。这样就会使得时间复杂度非常的大。怎么解决这个问题呢?
因此搜索时可以限定博弈树的深度,相当于只往前看n步,来减少时间复杂度。 这样策略本质上使用的是深度搜索策略,在搜索过程中,对本方有利的搜索点上应该取极大值,而对本方不利的搜索点上应该取极小值,实现上就可以通过极大搜索函数和极小搜索 函数,在对己方有利的搜索点上调用极大搜索函数,那下一次对方走的时候一定是对己方不利的点,所以直接在极大搜索函数中调用极小搜索函数,这样两个函数互相调用,正是极大极小搜索。
关于alpha-beta剪枝,是在极大极小搜索上,通过可行性剪枝,限制搜索的深度来减小时间复杂度;
直接上郭老师ppt的图:
alpha剪枝:
若结点x是Min节点,其兄弟节点中,已经求到的最大估价值是b(有些兄弟节点的估价值,可能还没有算出来),那么在对ⅹ的子节点进行考查的过程中,如果一旦发现某子节点的估价值<=b,则不需要考查x后面的子节点了,直接剪掉。
beta剪枝:
若结点x是Max节点,其兄弟节点中,已经求到的最小估价值是a(有些兄弟节点的估价值,可能还没有算出来)
那么在对x的子节点进行考查的过程中,如果一旦发现某子节点的估价值a,则不需要考查x后面的子节点了。
题意:相当于四子棋,给出一个4x4的棋局的局面,问先手 "x" 是不是能找在接下来的一步中
找到一个必胜局面,如果有,输出 'x' 下一步下子的坐标(行列都由 0 开始);否则输出字符串 "#####"。
样例:
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
int ansx,ansy,ct;
char map[5][5];
int alpha(int x ,int y);
int beta(int x,int y);
int check(){
int xa=0,xb=0;
int ya=0,yb=0;
for(int i=0;i<4;i++){
int ra=0,rb=0;
int ca=0,cb=0;
if(map[i][i]=='x')xa++;
else if(map[i][i]=='o')xb++;
if(map[i][3-i]=='x')ya++;
else if(map[i][3-i]=='o')yb++;
for(int j=0;j<4;j++){
if(map[i][j]=='x')ra++;
else if(map[i][j]=='x')rb++;
if(map[j][i]=='x')ca++;
else if(map[j][i]=='o')cb++;
}
if(ra==4||ca==4||xa==4||ya==4||ra==4||cb==4||xb==4||yb==4)
return 1;
}
return 0;
}
int alpha(int x,int y){
if(check())
return -1;
if(ct==16)
return 0;
int k;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(map[i][j]=='.'){
map[i][j]='x';
ct++;
k=beta(i,j);
map[i][j]='.';
ct--;
if(k==1)
return 1;
}
}
}
return -1;
}
int beta(int x,int y){
if(check())return 1;
if(ct==16)return 0;
int k;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(map[i][j]=='.'){
map[i][j]='o';
ct++;
k=alpha(i,j);
map[i][j]='.';
ct--;
if(!k||k==-1)
return -1;
}
}
}
return 1;
}
int dfs(){
int k;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(map[i][j]=='.'){
map[i][j]='x';
ct++;
k=beta(i,j);
map[i][j]='.';
ct--;
if(k==1){
ansx=i;ansy=j;
return 1;
}
}
}
}
return 0;
}
int main(){
char s[5];
while(cin>>s&&s[0]!='$'){
int alpha =-1,beta=1;
ct=0;
for(int i=0;i<4;i++){
cin>>map[i];
for(int j=0;j<4;j++){
if(map[i][j]!='.')
ct++;
}
}
if(ct<=4){
cout<<"####"<<endl;
continue;
}
if(dfs()){
cout<<"("<<ansx<<","<<ansy<<")"<<endl;
}
else {
cout<<"####"<<endl;
}
}
return 0;
}