我正在尝试实现DFS回溯算法,该算法涉及利用维基百科上的堆栈(而不是递归算法)。我试图生成一个由0和1组成的迷宫,其中1代表一堵墙,0代表一条可用路径。对于迷宫中不是墙的任何给定空间,必须始终有一条有效的路径,可以从任何其他非墙单元格到达。
我从一个迷宫开始,它是一个二维大小的迷宫阵列[15][20],然后按照算法将需要标记为已正确访问的单元格标记为已访问。最初,所有单元格(不包括外部边框)都标记为“未访问”。所有单元都用“1”值初始化,期望算法能在整个迷宫中挖掘出独特的路径。
链接到算法(递归回溯器第二次实现,利用堆栈):
https://en.wikipedia.org/wiki/Maze_generation_algorithm
我写的代码:
public void innerMaze() {
List<Coordinate> listOfCoordinates = new ArrayList<>();
List<Coordinate> coordinatesToBeRemoved = new ArrayList<>();
Stack<Coordinate> DFS_Stack = new Stack();
Coordinate initialCell = new Coordinate(1, 1);
checkIfVisited.put(initialCell, true);
DFS_Stack.push(initialCell);
int randomInteger = 0;
int cx = 0;
int cy = 0;
int gx = 0;
int gy = 0;
while (!DFS_Stack.empty()) {
Coordinate currentCoordinate = DFS_Stack.pop();
cx = currentCoordinate.getX();
cy = currentCoordinate.getY();
if ((cx - 2) >= 1) {
Coordinate up = findCoordinate((cx - 2), cy);
up.setDirection('N');
listOfCoordinates.add(up);
}
if ((cx + 2) <= MAX_ROW) {
Coordinate down = findCoordinate((cx + 2), cy);
down.setDirection('S');
listOfCoordinates.add(down);
}
if ((cy - 2) >= 1) {
Coordinate left = findCoordinate(cx, (cy - 2));
left.setDirection('W');
listOfCoordinates.add(left);
}
if ((cy + 2) <= MAX_COL) {
Coordinate right = findCoordinate(cx, (cy + 2));
right.setDirection('E');
listOfCoordinates.add(right);
}
for (Coordinate s : listOfCoordinates) {
if (checkIfVisited.get(s) == true) {
coordinatesToBeRemoved.add(s);
}
}
listOfCoordinates.removeAll(coordinatesToBeRemoved);
if (!listOfCoordinates.isEmpty()) {
DFS_Stack.push(currentCoordinate);
randomInteger = ThreadLocalRandom.current().nextInt(0, listOfCoordinates.size());
Coordinate temp = listOfCoordinates.get(randomInteger);
char direction = temp.getDirection();
Coordinate newWall;
if (direction == 'N') {
newWall = findCoordinate((cx - 1), cy);
} else if (direction == 'S') {
newWall = findCoordinate((cx + 1), cy);
} else if (direction == 'W') {
newWall = findCoordinate(cx, (cy - 1));
} else {
newWall = findCoordinate(cx, (cy + 1));
}
System.out.println(newWall);
gx = newWall.getX();
gy = newWall.getY();
completeMaze[gx][gy] = 0;
checkIfVisited.put(temp, true);
checkIfVisited.put(newWall, true);
listOfCoordinates.clear();
DFS_Stack.push(temp);
}
}
}
在我当前的实现中,每个单元格要么代表一堵墙,要么代表一条路径,因此我稍微改变了算法,将两个单元格之间的墙删除为将两个单元格之间的墙删除,将中间的一个更改为墙。我的输出示例如下:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 0 1 1 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1
1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 0
1 1 1 1 0 1 0 1 1 1 1 1 1 1 0 1 0 1 0 1
1 0 1 1 1 0 1 1 1 0 1 0 1 1 1 1 1 1 1 0
1 1 0 1 1 1 1 1 0 1 1 1 0 1 0 1 1 1 0 1
1 1 1 0 1 0 1 0 1 1 1 1 1 1 1 0 1 0 1 1
1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1
1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0
1 1 0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1
1 0 1 1 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 0
1 1 0 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1
1 1 1 0 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1 0
1 1 0 1 0 1 1 1 0 1 0 1 1 1 0 1 0 1 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
乍一看,2d数组索引[1][1]被封装在墙上,因此它是一个无法到达的区域。通过多次处决,这也是非常一致的。
任何帮助都将不胜感激。
我强烈建议使用不同的算法。我在编写迷宫生成算法方面有相当多的经验,递归回溯总是导致非常长的路径,几乎没有任何选择。我看不出你的代码中有什么问题,但这里是我自己的递归回溯的Java实现(如果代码不好,很抱歉,它已经有几年历史了)。
public class Maze {
private int sizeX, sizeY;
private Cell[][] cells;
private List<Cell> backtracker = new ArrayList<>();
public Maze(int sizeX, int sizeY) {
this.sizeX = sizeX;
this.sizeY = sizeY;
this.cells = new Cell[sizeX][sizeY];
for (int i = 0; i < sizeX; i++) {
for (int j = 0; j < sizeY; j++)
cells[i][j] = new Cell(this, i, j);
}
generate();
}
private void generate() {
Cell current = cells[0][0];
current.visit();
boolean hasUnvisited = hasUnvisited();
while (hasUnvisited) {
current = current.pickNext();
if (!current.isVisited()) {
current.visit();
backtracker.add(current);
hasUnvisited = hasUnvisited();
}
}
}
private boolean hasUnvisited() {
for (int i = 0; i < sizeX; i++) {
for (int j = 0; j < sizeY; j++) {
if (!cells[i][j].isVisited()) {
return true;
}
}
}
return false;
}
public Cell backtrack() {
if (backtracker.size() == 0) return null;
Cell cell = backtracker.get(backtracker.size() - 1);
backtracker.remove(cell);
return cell;
}
public Cell getCell(int x, int y) {
return cells[x][y];
}
}
public class Cell {
private Maze maze;
private int x, y;
private boolean visited = false;
// top, right, bottom. left
private boolean[] walls = new boolean[]{true, true, true, true};
public Cell(Maze maze, int x, int y) {
this.maze = maze;
this.x = x;
this.y = y;
}
public Cell pickNext() {
List<Cell> neighbors = new ArrayList<>();
if (y != maze.sizeY - 1) neighbors.add(maze.getCell(x, y + 1));
else neighbors.add(null);
if (x != maze.sizeX - 1) neighbors.add(maze.getCell(x + 1, y));
else neighbors.add(null);
if (y != 0) neighbors.add(maze.getCell(x, y - 1));
else neighbors.add(null);
if (x != 0) neighbors.add(maze.getCell(x - 1, y));
else neighbors.add(null);
boolean hasUnvisitedNeighbor = false;
for (Cell c : neighbors) {
if (c == null) continue;
if (!c.isVisited()) hasUnvisitedNeighbor = true;
}
if (hasUnvisitedNeighbor) {
int random = (int) Math.floor(Math.random() * 4);
Cell next = neighbors.get(random);
while (next == null || next.isVisited()) {
random = (int) Math.floor(Math.random() * 4);
next = neighbors.get(random);
}
this.breakWall(random);
next.breakWall((random + 2) % 4);
return next;
} else return maze.backtrack();
}
public void breakWall(int wall) {
walls[wall] = false;
}
public void visit() {
visited = true;
}
public boolean isVisited() {
return visited;
}
}
我是C的新手,我目前正在一个项目中创建一个使用DFS算法生成的迷宫。 我已经成功地生成了一条路径,例如 如上所述, Source是初始单元,1是我根据随机邻居创建的路径,D是“死胡同”。所以,如果可能的话,我想回到S,从另一个方向开始。我该如何处理队列和堆栈?有人能解释一下吗?非常感谢你?
下面是DFS算法的伪代码http://www.mazeworks.com/mazegen/mazetut/index.htm 创建一个CellStack(后进先出)来保存单元格位置列表 设置TotalCells=网格中的单元格数 随机选择一个单元格并将其命名为CurrentCell 设置VisitedCells=1 在探访牢房时 别的 从CellStack中弹出最近的单元格条目 使其成为Curre
本文向大家介绍Java实现走迷宫回溯算法,包括了Java实现走迷宫回溯算法的使用技巧和注意事项,需要的朋友参考一下 以一个M×N的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。 (1) 根据二维数组,输出迷宫的图形。 (2) 探索迷宫的四个方向:RIGHT为向右,DOWN向下,LEFT向左,UP向上,输出从入口到
我在一门课上学习序言。我有一个练习,我需要读取一个文件,从中生成一个迷宫,获得从源到目标的路径,然后将其写入一个文件。 我读了文件,对我拥有的每个单元格断言,对连接的每两个单元格断言。 ,,,都是整数坐标,所以我知道起点和终点。 我的工作原理是,如果当前节点连接到目标,完成并返回。否则,找到当前节点所连接的节点,并用新节点调用递归
我想用谷歌搜索一下,通过回溯来解决迷宫问题!我看到了这个算法:递归:解迷宫 这是: 查找路径(x,y) > 如果(x,y在迷宫外)返回false 如果(x,y是目标)返回true 如果(x,y未打开)返回false 将x、y标记为解决方案路径的一部分 if(FIND-PATH(x,y以北)=true)返回true if(FIND-PATH(x,y以东)=true)返回true 如果(FIND-PA
本文向大家介绍java 实现迷宫回溯算法示例详解,包括了java 实现迷宫回溯算法示例详解的使用技巧和注意事项,需要的朋友参考一下 用一个7 x 7的矩形表示迷宫,0和1分别表示的是通路和障碍。通过设计编写程序找到蓝色小球达到蓝色旗子的路线 思路: 构建一个迷宫(用二维数组)实现找通路的方法findRoad() 构建二维数组不难,我们主要是要实现findRoad()这个方法,在实现这个方法前,我们