迭代加深搜索[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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM