搜索算法(一)--DFS/BFS求解拯救同伴问题(JAVA)
生活随笔
收集整理的這篇文章主要介紹了
搜索算法(一)--DFS/BFS求解拯救同伴问题(JAVA)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
拯救同伴問題
問題描述:假設有如下迷宮,求解從某一點出發到目標位置的最短距離
Input:
5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3
Output:
7
深度優先搜索(DFS)
import java.util.Scanner;public class DFS {static int[][] a = new int[51][51];static int[][] book = new int[51][51];static int n, m, p, q, min = 99999999;static int sum = 1;public static void main(String[] args) {Scanner input = new Scanner(System.in);n = input.nextInt();m = input.nextInt();for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {a[i][j] = input.nextInt();}}int startX = input.nextInt();int startY = input.nextInt();p = input.nextInt();q = input.nextInt();book[startX][startY] = 1;dfs(startX,startY,0);System.out.println(min);}public static void dfs(int x, int y, int step) {/*** 按照右,下,左,上的順時針順序遍歷* 定義一個方向數組,便于操作* */int[][] next = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};int tx, ty;/*** 是否到達目標位置,更新最小值* */if (x == p && y == q) {min = min < step ? min : step;return;}/*** 計算下個點的坐標* */for (int i = 0; i < 4; i++) {tx = x + next[i][0];ty = y + next[i][1];/*** 檢查臨界* */if (tx < 1 || tx > n || ty < 1 || ty > m) {continue;}/*** 不是障礙物,也未加入路徑中,則執行dfs,注意回溯* */if (a[tx][ty] == 0 && book[tx][ty] == 0) {book[tx][ty] = 1;dfs(tx, ty, step + 1);/*** 為了找到最短的路徑必須進行回溯* */book[tx][ty] = 0;}}} }同樣的廣度優先搜索(BFS)也可以接這個題目,但是要注意廣度優先搜索需要有一個隊列Queue來控制。這里需要創建一個Point類來保存坐標和距離。
另外,由于java本身沒有提供隊列獲取隊尾元素的api,所以在下面的算法中需要注意處理,方法不唯一。
廣度優先搜索(BFS)
import java.util.LinkedList; import java.util.Queue; import java.util.Scanner;class Point{public int x;public int y;public int s;Point(int x, int y, int s) {this.x = x;this.y = y;this.s = s;} }public class BFS {static int[][] a = new int[51][51];static int[][] book = new int[51][51];static Queue<Point> queue = new LinkedList<>();static int n, m, p, q;static int min = 99999999;public static void main(String[] args) {Scanner input = new Scanner(System.in);n = input.nextInt();m = input.nextInt();for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {a[i][j] = input.nextInt();}}int startX = input.nextInt();int startY = input.nextInt();p = input.nextInt();q = input.nextInt();queue.add(new Point(startX, startY, 0));book[startX][startY] = 1;bfs();System.out.println(min);}public static void bfs() {/*** 按照右,下,左,上的順時針順序遍歷* 定義一個方向數組,便于操作* */int[][] next = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};int tx, ty;int flag = 0;while (!queue.isEmpty()) {for (int i = 0; i < 4; i++) {tx = queue.peek().x + next[i][0];ty = queue.peek().y + next[i][1];/*** 臨界條件* */if (tx < 1 || tx > n || ty < 1 || ty > m) {continue;}/*** 非障礙物,未標記為1,則進行入隊操作* */if (a[tx][ty] == 0 && book[tx][ty] == 0) {/*** 標記為已拓展,不同于DFS的是,BFS每個點只會被拓展一次,無需進行回溯* */min = queue.peek().s + 1;book[tx][ty] = 1;queue.add(new Point(tx, ty, min));}if (tx == p && ty == q) {flag = 1;break;}}if (flag == 1) {/*** 這里要注意的是,每次拓展完,且未到達目標位置時都會移出隊首元素一次,* 但是最后一次隊列中至少存在兩個元素,即正在處理的點,和這個點拓展到的目標* 而直接出隊操作是做不到的(即使將出隊操作提前也不能實現),而且,* 當大于兩個點的時候,一次出隊也不能起到實質性的作用* 所以在這里我們在上個判斷中直接改變全局變量mark的值即可實現* */break;}queue.remove();}} }總結
以上是生活随笔為你收集整理的搜索算法(一)--DFS/BFS求解拯救同伴问题(JAVA)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何点击打印,直接打印出来,不弹打印设置
- 下一篇: java sort排序