我正在编写一个程序,它基本上有一个使用java回溯搜索“pig”的对象。截至目前,我有猪移动和搜索,但它实际上无法“回溯”。我只是完全迷失了如何实际实现该段的代码,但我知道你会使用pathIndex--来减少路径长度。任何有关如何做到这一点的帮助都会非常有帮助。
public class MazeWalker {
/**
* The possible states of the current "walk" through a maze.
*/
public enum WalkerState {
/**
* Indicates that the maze walker has reached its assigned destination.
*/
THERE_ALREADY,
/**
* Indicates that the maze walker has concluded that it is impossible to
* reach its destination.
*/
IMPOSSIBLE_TO_GET_THERE,
/**
* Indicates that the maze walker would like to move left.
*/
MOVE_LEFT,
/**
* Indicates that the maze walker would like to move up.
*/
MOVE_UP,
/**
* Indicates that the maze walker would like to move right.
*/
MOVE_RIGHT,
/**
* Indicates that the maze walker would like to move down.
*/
MOVE_DOWN
}
/**
* Initializes the MazeWalker, providing it with the maze to use and the
* walker's destination.
*/
public MazeWalker(Maze maze, int destinationX, int destinationY) {
this.maze = maze;
this.destinationX = destinationX;
this.destinationY = destinationY;
// The path stack starts out empty.
path = new WalkerState[this.maze.getMazeWidth() * this.maze.getMazeHeight()];
pathIndex = -1;
// The "been-there" array starts off completely clear.
beenThere = new boolean[this.maze.getMazeHeight()][this.maze.getMazeWidth()];
for (int row = 0; row < beenThere.length; row++) {
for (int column = 0; column < beenThere[row].length; column++) {
beenThere[row][column] = false;
}
}
}
/**
* Takes a step toward reaching the given destination from the given current
* location, and returns either the direction of the next step, whether or
* not that destination has been reached, or whether that destination is
* impossible to reach.
*/
public WalkerState areWeThereYet(int currentX, int currentY) {
///currentWalkerState =
if ((currentX == destinationX) && (currentY == destinationY)) {
return WalkerState.THERE_ALREADY;
} else if (maze.getLocation(currentX, currentY).getRight().isOpen() && !beenThere[currentY][currentX + 1]) {
/// currentWalkerState = WalkerState.MOVE_RIGHT;
pathIndex++;
path[pathIndex] = WalkerState.MOVE_RIGHT;
return WalkerState.MOVE_RIGHT;
} else if (maze.getLocation(currentX, currentY).getLeft().isOpen() && !beenThere[currentY][currentX - 1]) {
/// currentWalkerState = WalkerState.MOVE_LEFT;
pathIndex++;
path[pathIndex] = WalkerState.MOVE_LEFT;
return WalkerState.MOVE_LEFT;
} else if (maze.getLocation(currentX, currentY).getAbove().isOpen() && !beenThere[currentY + 1][currentX]) {
/// currentWalkerState = WalkerState.MOVE_UP;
pathIndex++;
path[pathIndex] = WalkerState.MOVE_UP;
return WalkerState.MOVE_UP;
} else if (maze.getLocation(currentX, currentY).getBelow().isOpen() && !beenThere[currentY - 1][currentX]) {
/// currentWalkerState = WalkerState.MOVE_DOWN;
pathIndex++;
path[pathIndex] = WalkerState.MOVE_DOWN;
return WalkerState.MOVE_DOWN;
}
///Returning 6 different values///
///MazeWalker is the thing thats moving///
///MazeWalker is initialized with a Maze Object with the desired destination coordinates///
///Steve's initial location is sx, sy///
///Pig's location is px, py///
return WalkerState.IMPOSSIBLE_TO_GET_THERE;
}
/**
* Returns a representation of the locations which the walker has visited.
* The 2D array's dimensions should correspond to those of the walker's
* assigned maze.
*/
public boolean[][] getBeenThere() {
return beenThere;
}
/**
* Returns the current path taken by the walker.
*/
public WalkerState[] getCurrentPath() {
WalkerState[] currentPath = new WalkerState[pathIndex + 1];
for (int i = 0; i < pathIndex + 1; i++) {
currentPath[i] = path[i];
}
return currentPath;
}
/**
* The data structure for maintaining the current path.
*/
private WalkerState[] path;
/**
* The index for the current node in the path.
*/
private int pathIndex;
/**
* The data structure for keeping track of "passed" squares.
*/
private boolean[][] beenThere;
/**
* The maze that is being walked.
*/
private Maze maze;
/**
* The x-coordinate of the walker's destination.
*/
private int destinationX;
/**
* The y-coordinate of the walker's destination.
*/
private int destinationY;
}
答案 0 :(得分:0)
我实际上是在 C ++ 中写的,但这些想法很容易转移到Java。请注意,在实现回溯算法方法时,通常使用递归。
请注意,我使用的是Cell类和Maze类。变量&#34;矩阵&#34;是Maze类中的二维数组,矩阵中的每个[row] [column]位置都包含一个Cell对象。每个Cell都包含确定其属性的布尔变量(它是一个墙吗?它已经被访问了吗?它是开始吗?还是结束?等)。
/**
* determines whether path to maze can be found using backtracking
* algorithm
*/
bool MazeSolver::backtrackingFindPath(Cell toCell) {
// if cell moving to is not valid, return false
if (!maze.isValidMove(toCell)) {
return false;
}
// (base case) if cell moving to is finish, return true
if (maze.matrix[toCell.getRow()][toCell.getCol()].getIsFinish()) {
return true;
}
// if cell moving to is already visited, return false
if (maze.matrix[toCell.getRow()][toCell.getCol()].getIsVisited()) {
return false;
}
else {
// get row and column of cell moving to
int row = toCell.getRow();
int col = toCell.getCol();
// move to this cell in maze and set as visited
// store cell moved to in solution path
maze.move(maze.matrix[row][col]);
// if simply returned function call, first invalid cell would
// return a false value and exit function
// by wrapping in if statement, still calls function recursively
// but only returns value if moves to maze to stop recursion
// recurse north / up, if moves to finish, return true
if (backtrackingFindPath(maze.matrix[row - 1][col]) == true)
return true;
// recurse east / right
if (backtrackingFindPath(maze.matrix[row][col + 1]) == true)
return true;
// recurse south / down
if (backtrackingFindPath(maze.matrix[row + 1][col]) == true)
return true;
// recurse west / left
if (backtrackingFindPath(maze.matrix[row][col - 1]) == true)
return true;
// no valid or unvisited cells were available from this cell
// set as bad path and remove from solution path
maze.unmove(maze.matrix[toCell.getRow()][toCell.getCol()]);
// return false and go back to previous function call
return false;
}
}
确定是否可以在迷宫中进行移动。
/**
* is valid move
*/
bool isValidMove(Cell toCell) {
int row = toCell.getRow();
int col = toCell.getCol();
// check if within bounds of maze
if ((row >= 0 && row < rows) && (col >= 0 && col < cols)) {
// if not a wall
if (!matrix[row][col].getIsWall()) {
// if not a bad path
if (!matrix[row][col].getIsBadPath()) {
return true;
}
}
}
return false;
}
实际上移动,将Cell推到代表解决方案路径的堆栈上。
/**
* move (forward) in maze
*/
void move(Cell goodCell) {
// set cell moving to as visited
matrix[goodCell.getRow()][goodCell.getCol()].setIsVisited(true);
// update current location in maze to cell moving
setCurrent(goodCell);
// store cell moved to in stack (solution path)
path.push(goodCell);
}
向后移动,从表示解决方案路径的堆栈中弹出最近保存的Cell。
/**
* unmove (move back) in maze
*/
void unmove(Cell badCell) {
// set cell leaving as bad path
matrix[badCell.getRow()][badCell.getCol()].setIsBadPath(true);
matrix[badCell.getRow()][badCell.getCol()].setIsVisited(false);
// remove cell leaving from stack (solution path)
path.pop();
}
这里有一个good reference,用于理解为什么会回溯以及为什么会有效。