[英]Path Finding (2D Array)
I want to find the path from one point to another point.我想找到从一点到另一点的路径。 the black boxes are obstacles and we can't go to it and the blue box is the starting point and the yellow box is the end point I want to go from starting point to end point.
黑框是障碍,我们不能去,蓝框是起点,黄框是我想从起点到终点的终点。 I write this code with the help of an algorithm from my book, actually now I want to make it dynamic that means for nxn matrix.
我在我书中的算法的帮助下编写了这段代码,实际上现在我想让它动态化,这意味着 nxn 矩阵。 so I want guidance that what steps should I have to take to make it run able for nxn matrix.
所以我需要指导我应该采取哪些步骤才能使其能够为 nxn 矩阵运行。 and I also want to ask that is this a best solution to find a shortest path in this scenario or something else ?
我还想问,这是在这种情况下找到最短路径的最佳解决方案还是其他什么?
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
public class Main {
public static void main(String[] args) {
boolean[][] boolMaze = new boolean[][] {
{ true, true, true, true, true },
{ false, true, false, true, true },
{ true, false, true, true, true },
{ false, true, true, false, false },
{ false, false, false, false, false },
{ true, true, true, true, true },
{ false, true, false, true, true },
{ true, false, true, true, true },
{ false, true, true, false, false },
{ false, false, false, false, false },
{ true, true, true, true, true },
{ false, true, false, true, true },
{ true, false, true, true, true },
{ false, true, true, false, false },
{ false, false, false, false, false },
{ true, true, true, true, true },
{ false, true, false, true, true },
{ true, false, true, true, true },
{ false, true, true, false, false },
{ false, false, false, false, false } };
Maze maze = new Maze(boolMaze);
List<Maze.Cell> path = maze.findPath(0, 0, 3, 2);
System.out.println("found path in maze: " + path);
}
}
class Maze {
private final boolean[][] maze;
public Maze(boolean[][] maze) {
this.maze = maze;
}
public int height() {
return maze.length;
}
public int width() {
return maze[0].length;
}
}
public List<Cell> findPath(int xStart, int yStart, int xGoal, int yGoal) {
LinkedList<Cell> path = new LinkedList(); // use a linked list, since we
// don't know how many
// elements it will contain
// straight away..
path.add(new Cell(xStart, yStart));
HashSet<Cell> visited = new HashSet(); // this set will store all
// visited cells. Make sure to
// add any cell you looked at.
// Don't work with cells which
// you have visited previously,
// by checking
// visited.contains(cell).
visited.add(path.getFirst());
// ///////////////////////////
if (xStart - 1 >= 0 && maze[xStart][yStart - 1]) {
Cell cell = new Cell(xStart, yStart - 1);
return path;
}
else if (yStart + 1 < height() && maze[xStart][yStart + 1]) {
Cell cell = new Cell(xStart, yStart + 1);
return path;
}
else if (xStart + 1 < width() && maze[xStart + 1][yStart]) {
Cell cell = new Cell(xStart + 1, yStart);
return path;
}
else if (xStart - 1 >= 0 && maze[xStart - 1][yStart]) {
Cell cell = new Cell(xStart - 1, yStart);
return path;
}
// //////////////////////////
// use your path finding algorithm here (note that you can use getLast()
// and getFirst() on your list.
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Cell))
return false;
Cell cell = (Cell) o;
if (x != cell.x)
return false;
return y == cell.y;
}
@Override
public int hashCode() {
int result = x;
result = 31 * result + y;
return result;
}
class Cell implements Comparable<Cell> {
Cell(int x, int y) {
this.x = x;
this.y = y;
}
int x;
int y;
@Override
public int compareTo(Cell o) {
if (o.equals(x) && o.equals(y))
return 0;
return 1;
}
}
There are two parts to your question.你的问题有两个部分。 First is to make the solution work on a NxM maze and the other is style and performance improvements.
首先是使解决方案适用于 NxM 迷宫,另一个是样式和性能改进。
First of all, there are two things you can quickly fix by using find and replace.首先,您可以使用查找和替换快速修复两件事。
Integer
with int.Integer
。 Integer
s are actual objects which have to be created and destroyed by the garbage collector. Integer
是垃圾收集器必须创建和销毁的实际对象。 Also they have to be converted each time you use them for calculation, which heavily affects performance.boolean[][]
insteadboolean[][]
代替Please also remove the directions array.还请删除方向数组。 It is pointless, since
directions[i] == i
is always true
.这是毫无意义的,因为
directions[i] == i
总是true
。 You could just work with int variables all the time.您可以一直使用 int 变量。 There would even be an even nicer solution with enum, but lets not introduce too many new concepts here..
使用 enum 甚至会有更好的解决方案,但我们不要在这里引入太多新概念。
This code:这段代码:
for(int i = 0; i < directions.length; i++) {
Cell newCell = findCell(current,directions[i]);
//code..
}
would become this code:将成为这个代码:
for(int i = 0; i < 4; i++) {
Cell newCell = findCell(current,i);
//code..
}
Then you should start using maze as an object, since it is already a class.然后你应该开始使用 maze 作为一个对象,因为它已经是一个类。 You'll have to remove the static keyword from all variables and methods, since they will work on private members in the future Create a new
Class
called Main
, where you call the following code in the newly added main method:您必须从所有变量和方法中删除 static 关键字,因为它们将来会在私有成员上工作 创建一个名为
Main
的新Class
,您可以在新添加的 main 方法中调用以下代码:
boolean[][] boolMaze = new boolean[][]{/*initialize array*/};
Maze maze = new Maze(boolMaze);
List<Cell> path = maze.findPath(0, 0, 3, 2);
System.out.println("found path in maze: "+path)
So we need two new things.所以我们需要两个新东西。 A proper constructor for
Maze
and the method findPath
. Maze
的正确构造函数和findPath
方法。
The class Maze
should contain the private (possibly final) member boolean[][]
maze and the constructor should set it.类
Maze
应该包含私有(可能是 final)成员boolean[][]
迷宫,并且构造函数应该设置它。
public Maze(boolean[][] maze) {
this.maze = maze;
}
Also remove the variables WIDTH
and HEIGHT
, as they don't necessarily reflect the size of the array.还要删除变量
WIDTH
和HEIGHT
,因为它们不一定反映数组的大小。 The nice thing about java is, that arrays remember which size they have. Java 的好处是,数组可以记住它们的大小。 Add public helper functions for quick access though:
添加公共帮助函数以快速访问:
public int height() {
return maze.length;
}
public int width() {
return maze[0].length; // assuming that maze.length is always > 0
}
The findPath
method should create a List<Cell>
and return it: findPath
方法应该创建一个List<Cell>
并返回它:
public List<Cell> findPath(int xStart, int yStart, int xGoal, int yGoal) {
LinkedList<Cell> path = new LinkedList(); //use a linked list, since we don't know how many elements it will contain straight away..
path.add(new Cell(xStart, yStart));
HashSet<Cell> visited = new HashSet(); //this set will store all visited cells. Make sure to add any cell you looked at. Don't work with cells which you have visited previously, by checking visited.contains(cell).
visited.add(path.getFirst());
//use your path finding algorithm here (note that you can use getLast() and getFirst() on your list.
return path;
}
You can then also get rid of the parent attribute in cell.然后,您还可以摆脱单元格中的父属性。 And to compare if two
Cell
s are the same, don't use compare.并且要比较两个
Cell
是否相同,请不要使用 compare。 That method is used to sort objects.该方法用于对对象进行排序。 Implement:
实施:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Cell)) return false;
Cell cell = (Cell) o;
if (x != cell.x) return false;
return y == cell.y;
}
@Override
public int hashCode() {
int result = x;
result = 31 * result + y;
return result;
}
In Cell
.在
Cell
。 When checking if two Cells are the same, call cell.equals(otherCell)
检查两个Cell是否相同时,调用
cell.equals(otherCell)
You actually implemented a flood fill algorithm, which means you just naively fill the whole plane until you found your goal.您实际上实现了洪水填充算法,这意味着您只是天真地填充了整个平面,直到找到目标。 The standard algorithm for solving mazes is always trying to stick to one wall.
解决迷宫的标准算法总是试图坚持一堵墙。 Note that this only works, if your entry point and your goal are on the edge of your maze (like it is often the case) Use this site to learn more about the algorithm You might want to keep your path finding algorithm and only use the improved one if your start and goal are next to the edge.
请注意,这仅在您的入口点和目标位于迷宫边缘时才有效(就像经常发生的情况一样) 使用此站点了解有关该算法的更多信息 您可能希望保留您的寻路算法并仅使用如果您的起点和目标接近边缘,则改进一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.