首页 > 代码库 > 迭代加深搜索[codevs1004 四子连棋]
迭代加深搜索[codevs1004 四子连棋]
迭代加深搜索
一、算法简介
迭代加深搜索是在速度上接近广度优先搜索,空间上和深度优先搜索相当的搜索方式。由于在使用过程中引入了深度优先搜索,所以也可以当作深度优先搜索的优化方案。
迭代加深搜索适用于当搜索深度没有明确上限的情况。
例如上图的一棵搜索树,在进行深度优先搜索前先规定好这次搜索的最大深度dep,当搜索到达dep却还没搜索到结果时回溯。
之后不断加大搜索深度,重新搜索,直到找到结果为止。虽然这样搜索次数会累计很多次,但每一次搜索的范围和下一次搜索的范围相比微不足道,所以整体搜索速度不会受太大影响。
由于深度是从小到大逐渐增大的,所以当搜索到结果时可以保证搜索深度是最小的。这也是迭代加深搜索在一部分情况下可以代替广度优先搜索的原因(还比广搜省空间)。
二、算法图示
假设G是需要搜索到的结果。
当 dep = 1 时搜索深度为1,搜索到节点 A,未搜索到结果,dep++ 并进行下一次深搜。
当 dep = 2 时搜索深度为2,搜索到节点 A,B,C,D 未搜索到结果,dep++ 并进行下一次深搜。
当 dep = 3 时搜索深度为3,搜索到节点 A,B,C,D,E,G 搜索到结果G,停止全部搜索并记录记录结果。
三、[codevs 1004四子连棋]
在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。
● | ○ | ● | |
○ | ● | ○ | ● |
● | ○ | ● | ○ |
○ | ● | ○ |
一般这样找最小搜索深度的题都用广度优先搜索写,但是由于广搜空间占用多,于是我们可以用迭代加深搜索作替代品。
本题迭搜思路就是逐渐增加每一次下棋的最大移动步数,当棋盘状态满足题目所给条件时退出并记录步数。
下面贴AC程序
1 #include <stdio.h> 2 #include <iostream> 3 #include <algorithm> 4 using namespace std; 5 int board[5][5]; 6 int movex[5]={0,-1,0,1,0},movey[5]={0,0,1,0,-1}; 7 int Ox1,Oy1,Ox2,Oy2,dep,f; 8 int avalible(int a,int b,int k){ 9 if(board[a][b]!=k&&a>=1&&a<=4&&b>=1&&b<=4) return 1;10 else return 0;11 }12 int jdg(){13 for(int i=1;i<=4;i++){14 if(board[i][1]==board[i][2]&&board[i][2]==board[i][3]&&board[i][3]==board[i][4]) return 1;15 if(board[1][i]==board[2][i]&&board[2][i]==board[3][i]&&board[3][i]==board[4][i]) return 1;16 }17 if(board[1][1]==board[2][2]&&board[2][2]==board[3][3]&&board[3][3]==board[4][4]) return 1;18 if(board[1][4]==board[2][3]&&board[2][3]==board[3][2]&&board[3][2]==board[4][1]) return 1;19 return 0;20 }21 void dfs(int x,int y,int p,int q,int pre,int step){22 if(jdg()){23 f=1;24 return ;25 }26 else if(step>dep) return ;27 for(int i=1;i<=4;i++){28 int nx=x+movex[i];29 int ny=y+movey[i];30 int np=p+movex[i];31 int nq=q+movey[i];32 33 if(avalible(nx,ny,pre)){34 swap(board[x][y],board[nx][ny]);35 36 dfs(nx,ny,p,q,board[x][y],step+1);37 38 swap(board[x][y],board[nx][ny]);39 }40 if(avalible(np,nq,pre)){41 swap(board[p][q],board[np][nq]);42 43 dfs(x,y,np,nq,board[p][q],step+1);44 45 swap(board[p][q],board[np][nq]);46 }47 }48 }49 int main(){50 for(int i=1;i<=4;i++)51 for(int j=1;j<=4;j++){52 char ch;53 cin>>ch;54 if(ch==‘B‘) board[i][j]=1;55 else if(ch==‘W‘) board[i][j]=2;56 else board[i][j]=3;57 58 if(board[i][j]==3&&!Ox1) Ox1=i,Oy1=j;59 else if(board[i][j]==3) Ox2=i,Oy2=j;60 }61 for(dep=0;;dep++){62 dfs(Ox1,Oy1,Ox2,Oy2,1,1);63 dfs(Ox1,Oy1,Ox2,Oy2,2,1);64 if(f){65 printf("%d",dep);66 return 0;67 }68 }69 return 0;70 }
迭代加深搜索[codevs1004 四子连棋]