搜索——深度優先算法(dfs)
有一天,小哈一個人去玩迷宮。凡是方向感不好的小哈很快迷路了。
小啊得知後便去解救無助的小哈。小啊當然是有備而來,已經弄清楚了迷宮的地圖,現在小啊要以最快的速度去解救小哈
迷宮由m行n列組成(m,n>=50)
迷宮由空地和牆組成,0代表空地,1代表牆。
任務是找出一條小啊營救小哈的最短路徑。
import java.util.Random;
import java.util.Scanner;
/**
* @author sjf
* @date 2020/3/2 21:58
*/
public class dfs_manRescuewoman {
static int endx, endy; //小啊的位置座標
static int min=999999; //需要走的步數
static int[][] next = {{-1,0}/*上*/ ,{0,-1}/*左*/,{1,0}/*下*/,{0,1}/*右*/}; //方向數組,利於跑圖
static int n,m; //迷宮爲 n行m列
static int [][] map = new int[51][51]; //地圖
static int [][] book = new int[51][51]; //標記數組
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
for (int i = 0; i <n; i++) {
for (int j = 0; j <m; j++) {
map[i][j] = new Random().nextInt(2); //輸入地圖
System.out.print(map[i][j]+" ");
}
System.out.println();
}
//小啊的起始座標
int startx = sc.nextInt();
int starty = sc.nextInt();
//小哈的座標
endx =sc.nextInt();
endy =sc.nextInt();
//從起點開始搜索
book[startx][starty] = 1;
dfs(startx,starty,0);
//輸出
if(min!=999999)
System.out.println(min);
else
System.out.println("設置錯標出錯!!!/\n不可能完成營救任務!!!");
}
public static void dfs(int x ,int y ,int step){
int tx,ty;
//出口 即是 小啊 找到 小哈
if(x== endx &&y== endy){
//更新最小值
if(step<min){
min = step;
}
return;
}
//要做的是 上左下右 的走 相當於 放 卡牌到盒子裏 這是我要做的
for (int i = 0;i<4;i++){
//嘗試每一種走法
tx = x +next[i][0];
ty = y +next[i][1];
//判斷是否越界
if(tx<0 || tx>n-1 || ty<0 || ty>m-1){
continue; //越過此次
}
//判斷該點是否爲 障礙物 且 是否走過
if(map[tx][ty]==0 && book[tx][ty]==0){
book[tx][ty] = 1; //標記這個點走過了
dfs(tx,ty,step+1); //往下一步走
book[tx][ty] = 0; //取消標記
}
}
return;
}
}
深度優先搜索:建立於遞歸回溯之上,其實就是遍歷搜索樹,每次失敗導致回溯然後把做過的痕跡抹去,不斷的去嘗試,直至達到返回條件。
理解深度優先搜索的關鍵在於解決“當下該怎麼做?”。至於“下一步如何做”“則與當下應該怎麼做”是一樣的。
void dfs(int step){
判斷邊界
嘗試每一種可能 for(){
繼續下一步 dfs(step+1);
}
返回
}
深度優先搜索對於迷宮跑圖問題,不容易解決的問題就是設計出來一條路線
比如圖片中的路線爲:
DLLDLDLDDDDRRRDRRURRRDRRUUUR
(其中 D、U、L、R 分別表示向下、向上、向左、向右走)
廣度優先搜索可以很好地解決此問題。