求迷宫的最短路径

来源:互联网 发布:骆家辉 杨澜 张欣 知乎 编辑:程序博客网 时间:2024/05/17 14:20

迷宫的表示是一个N×M的二位数组,左上角的位置(0,0)是入口,右下角的位置(N-1,M-1)是迷宫的出口,其中的1表示迷宫不能走,0表示可以行走,本文使用类似的A*算法来进行寻路。

首先是定义个一个点的类,Poin表示迷宫的每个点的位置,如下:

package wyhllk.algorithm;/** * @author wyhllk * */public class Point {private int x;private int y;public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public Point(int x, int y) {super();this.x = x;this.y = y;}@Overridepublic String toString() {return "(" + x + ", " + y + ")";}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + x;result = prime * result + y;return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Point other = (Point) obj;if (x != other.x)return false;if (y != other.y)return false;return true;}}
然后定义个算法的实现:

package wyhllk.algorithm;import java.util.HashMap;import java.util.HashSet;import java.util.LinkedHashSet;import java.util.Map;import java.util.Set;public class Graph {private static Map<Point, Point> parent = new HashMap<Point, Point>();private static Set<Point> open = new LinkedHashSet<Point>();private static Set<Point> close = new HashSet<Point>();private static Map<Point, Integer> cost = new HashMap<Point, Integer>();private static boolean hasPath = false;public static int shortestDist(int[][] amaze) {int N = amaze.length;int M = amaze[0].length;Point start = new Point(0, 0);parent.put(start, null);open.add(start);cost.put(start, 0);Point end = new Point(N - 1, M - 1);while (!open.contains(end)) {if (open.isEmpty()) {return Integer.MAX_VALUE;}Point point = findPoint();addPoint2Open(point, amaze);close.add(point);open.remove(point);}hasPath = true;return cost.get(end);}public static String printPath(int[][] amaze) {int N = amaze.length;int M = amaze[0].length;String res = "";if (hasPath) {Point end = new Point(N - 1, M - 1);Point start = new Point(0, 0);Point point = end;while (!point.equals(start)) {res = point.toString() + res;point = parent.get(point);}res = start + res;} else {res = "No Path";}return res;}private static Point findPoint() {int realCost = Integer.MAX_VALUE;Point current = null;for (Point point : open) {if (realCost > cost.get(point)) {realCost = cost.get(point);current = point;}}return current;}private static void addPoint2Open(Point point, int[][] amaze) {int N = amaze.length;int M = amaze[0].length;// 从下、右、上、左4个方向判断int xDown = point.getX() + 1;int yDown = point.getY();if (xDown < N && amaze[xDown][yDown] != 1) {Point downPoint = new Point(xDown, yDown);if (!close.contains(downPoint)) {addPoint(point, downPoint);}}int xRight = point.getX();int yRight = point.getY() + 1;if (yRight < M && amaze[xRight][yRight] != 1) {Point rightPoint = new Point(xRight, yRight);if (!close.contains(rightPoint)) {addPoint(point, rightPoint);}}int xUp = point.getX() - 1;int yUp = point.getY();if (xUp >= 0 && amaze[xUp][yUp] != 1) {Point upPoint = new Point(xUp, yUp);if (!close.contains(upPoint)) {addPoint(point, upPoint);}}int xLeft = point.getX();int yLeft = point.getY() - 1;if (yLeft >= 0 && amaze[xLeft][yLeft] != 1) {Point leftPoint = new Point(xLeft, yLeft);if (!close.contains(leftPoint)) {addPoint(point, leftPoint);}}}private static void addPoint(Point prePoint, Point nextPoint) {if (!open.contains(nextPoint)) {open.add(nextPoint);int realCost = cost.get(prePoint) + 1;cost.put(nextPoint, realCost);parent.put(nextPoint, prePoint);} else {int srcCost = cost.get(nextPoint);int currentCost = (cost.get(prePoint) + 1);if (currentCost < srcCost) {int realCost = currentCost;cost.put(nextPoint, realCost);parent.put(nextPoint, prePoint);}}}}

最后定义了一个测试的类:

package wyhllk.algorithm;public class DistanceShortest {public static void main(String[] args) {int[][] amaze = { { 0, 1, 0, 0, 0, 0 },{ 0, 1, 0, 1, 0, 1 },{ 0, 1, 0, 1, 0, 1 },{ 0, 0, 0, 0, 0, 0 },{ 0, 0, 1, 0, 0, 0 } };System.out.println(Graph.shortestDist(amaze));System.out.println(Graph.printPath(amaze));}}

测试的结果如下:





原创粉丝点击