搜索算法(一)--DFS/BFS求解拯救同伴问题(JAVA)
2018-01-07 20:14
447 查看
拯救同伴问题
问题描述:假设有如下迷宫,求解从某一点出发到目标位置的最短距离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 b99e 的是,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 )
- 搜索算法(二)--DFS/BFS求解炸弹人问题(JAVA )
- 模拟求解迷宫问题(DFS+BFS)
- 独立岛问题的BFS,DFS求解
- 关于迷宫问题的dfs与bfs两中求解方式
- BFS求解迷宫问题初探(java版)
- 迷宫问题(maze problem)——深度优先(DFS)与广度优先搜索(BFS)求解
- [置顶] 模拟求解迷宫问题(DFS+BFS)
- 迷宫问题(maze problem)——深度优先(DFS)与广度优先搜索(BFS)求解
- 模拟求解迷宫问题(DFS+BFS)
- 回溯法求解N皇后问题(Java实现)
- 教你通透彻底理解:BFS和DFS优先搜索算法
- BFS和DFS优先搜索算法
- 用Java实现天平称球问题的自动求解
- 2011.11.13 poj2251 如果要用到BFS或者DFS,如果最短路径的相关问题,那么肯定是BFS!!!不会是DFS!!!
- NYU AI作业习题-活动安排问题 BFS+DFS Iterative deepening depth-first search
- NYU AI作业习题-活动安排问题 BFS+DFS Iterative deepening depth-first search
- 教你通透彻底理解:BFS和DFS优先搜索算法
- 经典算法研究系列:四、教你通透彻底理解:BFS和DFS优先搜索算法(转csdn)
- 经典算法研究系列:四、教你通透彻底理解:BFS和DFS优先搜索算法