我创建了两个堆栈。一个用于路径,另一个用于我已经搜索过的斑点。理想情况下,我会检查搜索到的路径是否包含方向上的下一个点。如果确实如此,它会检查另一个方向。
样本迷宫
0 1 0 1 0
0 0 0 1 0
0 1 0 0 0
0 1 0 1 1
0 1 0 0 0
我的算法似乎陷入2,3和2,4之间。永远不要探索1,4或0.4。我看到它在无限循环中在2,3和2,4之间反弹。所以看来我的searching.contains()运行不正常。有什么建议来修复我的搜索堆栈?理想情况下,当我运行我的代码。我希望它检查东,南,西,然后北方已经被搜查过。如果已经检查了所有点,它将使用while循环中的current = path.pop从我的路径堆栈中弹出最后一个位置并重复。
位置是一个自定义类。我已经考虑过将一个前一个位置变量添加到位置类的构造函数中,但是如果我可以让我的路径堆栈工作,似乎根本不需要它。如果我错了,请告诉我。
class Position{
public int i; //row
public int j; //column
public char val; //1, 0, or 'X'
// reference to the previous position (parent) that leads to this position on a path
Position parent;
Position(int x, int y, char v){
i=x; j = y; val=v;
}
Position(int x, int y, char v, Position p){
i=x; j = y; val=v;
parent=p;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + i;
result = prime * result + j;
result = prime * result + ((parent == null) ? 0 : parent.hashCode());
result = prime * result + val;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Position other = (Position) obj;
if (i != other.i)
return false;
if (j != other.j)
return false;
if (parent == null) {
if (other.parent != null)
return false;
} else if (!parent.equals(other.parent))
return false;
if (val != other.val)
return false;
return true;
}
}
public static Position [] stackSearch(char [] [] maze){
//todo: your path finding algorithm here using the stack to manage search list
//your algorithm should modify maze to mark positions on the path, and also
//return array of Position objects coressponding to path, or null if no path found
ArrayDeque <Position> path = new ArrayDeque<Position>();
ArrayDeque <Position> searched = new ArrayDeque<Position>();
//creates position object
Position start = new Position(0,0,'0');
Position current;
Position north,south, east, west;
int i = 0; int j = 0;
//push (0,0) onto stack
path.push(start);
searched.push(start);
while(!path.isEmpty()){
current=path.pop();
i=current.i;
j=current.j;
if(i==maze.length-1 && j==maze.length-1 && maze[i][j]=='0'){
Position[] trail= new Position [path.size()];
while(!path.isEmpty()){
for(int k=0; k<path.size();k++){
trail[k]=path.pop();
}
return trail;
}
}
System.out.println(i +"," +j);
//check east.
east= new Position(i,j+1,'0');
south= new Position(i+1,j,'0');
west= new Position(i,j-1,'0');
north= new Position(i-1,j,'0');
if (j+1 >= 0 && j+1 < maze.length && maze[i][j+1] == '0' && searched.contains(east)==false)
{
searched.push(east);
path.push(current);
path.push(east);
}
//check south, add its position to the list.
else if (i+1 >= 0 && i+1 < maze.length && maze[i+1][j] == '0' && searched.contains(south)==false)
{
searched.push(south);
path.push(current);
path.push(south);
}
//check west.
else if (j-1 >= 0 && j-1 < maze.length && maze[i][j-1] == '0' && searched.contains(west)==false)
{
searched.push(west);
path.push(current);
path.push(west);
}
//check north
else if (i-1 >= 0 && i-1 < maze.length && maze[i-1][j] == '0' && searched.contains(north)==false)
{
searched.push(north);
path.push(current);
path.push(north);
}
}
return null;
}
答案 0 :(得分:0)
我不相信你正确使用堆栈。例如,您似乎正在使用路径堆栈将最终解决方案存储到迷宫中,以及存储尚未完全检查的路径部分(并且可能不是正确的解决方案)。您正在向北,向南,向东,向西推进到路径堆栈,并且您正在转换路径堆栈以作为解决方案返回。这不会奏效。你怎么知道北方的位置导致死胡同?在您已经确定通过迷宫的最终路径之前,您无法开始向路径堆栈添加内容。
您可以使用称为深度优先搜索的内容来确定迷宫中的路径:
首先,您应该使用堆栈来管理[您的]搜索列表。&#34;换句话说,您应该在堆栈中存储要检查的所有位置。
然后,您使用堆栈在迷宫上执行深度优先搜索。 http://en.wikipedia.org/wiki/Depth-first_search
到达目的地后,您应该回溯。因此,您可能需要在Position类中使用先前的位置变量。
这样的事情应该有用......
let toSearch be a Stack of positions to search
let visited be a 2D array indicating all locations of the maze we've visited (or a stack, or whatever you prefer)
let start be the starting Position
let end be the ending Position
toSearch.push( start );
while( toSearch is not empty ) {
posToSearch = toSearch.pop();
if ( posToSearch is the end ) {
let s be a stack
let temp = end
//backtracking with a stack
while( temp is not start ) {
s.push( temp );
//also modify the maze to indicate the path
maze[ temp.i ][ temp.j ] = '*';
temp = temp.previous;
}
s.push( start );
//turn the information in the stack into an array
let rtn be an array of size s.size()
for i=0 ... s.size();
rtn[ i ] = s.pop();
return rtn;
}
if ( posToSearch is not already visited ) {
if ( you can go north ) {
start.push( position north of posToSearch );
}
if ( you can go south ) {
start.push( position south of posToSearch );
}
if (... east ... )
if (... west ... )
label posToSearch as visited
}
}
//if the end was never reached, then there cannot be a solution to the maze
return null;