我正在尝试使用DFS实现骑士之旅。为简单起见,我的主板是5x5。
下面是我的代码
class StackK
{
private final int SIZE = 25;
private int[] st;
private int top;
// ------------------------------------------------------------
public boolean isFull()
{return (top == SIZE-1);}
// ------------------------------------------------------------
public StackK() // constructor
{
st = new int[SIZE]; // make array
top = -1;
}
public void push(int j) // put item on stack
{ st[++top] = j; }
// ------------------------------------------------------------
public int pop() // take item off stack
{ return st[top--]; }
// ------------------------------------------------------------
public int peek() // peek at top of stack
{ return st[top]; }
// ------------------------------------------------------------
public boolean isEmpty() // true if nothing on st ack
{ return (top == -1); }
// ------------------------------------------------------------
} // end class StackK
////////////////////////////////////////////////////////////////
class VertexK
{
public String label; // label (e.g. 'A')
public boolean wasVisited;
public int lastVisited;
// ------------------------------------------------------------
public VertexK() // constructor
{
label = "O";
wasVisited = false;
lastVisited = 0;
}
// ------------------------------------------------------------
} // end class VertexK
////////////////////////////////////////////////////////////////
class GraphK
{
private final int SIZE = 5;
private final int AREA = 5*5;
private VertexK vertexList[]; // list of vertices
private int adjMat[][]; // adjacency matrix
private int nVerts; // current number of vertices
private StackK theStack;
// ------------------------------------------------------------
public GraphK() // constructor
{
vertexList = new VertexK[AREA];// chess board
adjMat = new int[AREA][AREA];// adjacency matrix
nVerts = 0; // number of vertices
for(int y=0; y<SIZE; y++) // set adjacency
for(int x=0; x<SIZE; x++) // matrix to 0
adjMat[x][y] = 0;
theStack = new StackK(); //initialize stack
for(int i=0;i<AREA;i++) // make a chess board
addVertex();
for(int i = 0; i < SIZE; i++) // add all possible moves to adjMat
for(int j = 0; j < SIZE; j++)
addMoves(i, j);
}
// ---------------------------------------------------------------
public void displayBoard(){
int count =0;
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
System.out.print(vertexList[(count+j)].label+" ");
}
count = count+5;
System.out.println("");
}
System.out.println("----------------------------------------------");
}
// ---------------------------------------------------------------
public void addMoves(int i, int j)
{
int currentRow = i*SIZE; //row
int currentCol = j; //col
int currentVertex = currentRow+currentCol;
if(i-1>=0){
if(j-2>=0){
addEdge(currentVertex,currentVertex-SIZE-2);
}
if(j+2<SIZE){
addEdge(currentVertex,currentVertex-SIZE+2);
}
}
if(i+1<SIZE)
{
if(j-2>=0){
addEdge(currentVertex, currentVertex+SIZE-2);
}
if(j+2<SIZE){
addEdge(currentVertex, currentVertex+SIZE+2);
}
}
if(i-2>=0){
if(j-1>=0){
addEdge(currentVertex, currentVertex-(SIZE*2)-1);
}
if(j+1<SIZE){
addEdge(currentVertex,currentVertex-(SIZE*2)+1);
}
}
if(i+2<SIZE){
if(j-1>=0){
addEdge(currentVertex,currentVertex+(SIZE*2)-1);
}
if(j+1<SIZE){
addEdge(currentVertex,currentVertex+(SIZE*2)+1);
}
}
}
// ------------------------------------------------------------
public void addVertex()
{
vertexList[nVerts++] = new VertexK();
}
// ------------------------------------------------------------
public void addEdge(int start, int end)
{
adjMat[start][end] = 1;
}
// ------------------------------------------------------------
public void dfs() // depth-first search
{
vertexList[0].wasVisited = true;
vertexList[0].label = "V";
theStack.push(0);
while( !theStack.isEmpty() )
{
if(theStack.isFull()){
System.out.println("You Win");
}
int last = theStack.peek();
int v = getNext( theStack.peek() );
if(v == -1){
System.out.println("DEAD END HERE");
theStack.pop();
vertexList[last].label = "O";
displayBoard();
}
else
{
vertexList[v].label = "V";
displayBoard();
vertexList[v].lastVisited = last;
vertexList[v].wasVisited = true;
theStack.push(v);
}
} // end while
// stack is empty, so we're done
}
// ------------------------------------------------------------
// returns an unvisited VertexK adj to v
public int getNext(int v)
{
for(int j=0; j<nVerts; j++)
if(adjMat[v][j]==1 && vertexList[j].wasVisited==false)
return j;
return -1;
} // end getAdjUnvisitedVertexK()
// ------------------------------------------------------------
public void displayAdj()
{
for(int i=0;i<AREA;i++){
System.out.print(i+"th row: ");
for(int k=0;k<AREA;k++)
System.out.print(adjMat[i][k]);
System.out.println("");
}
}
// ------------------------------------------------------------
} // end class GraphK
public class KnightApp
{
public static void main(String[] args)
{
GraphK k = new GraphK();
k.displayAdj();
k.dfs();
k.displayBoard();
} // end main()
} // end class DFSApp
我的程序从索引0开始,然后转到索引7,因为如果你运行代码就会注意到,这不是正确的解决方案(我还递归写了骑士之旅以检查我应该从哪里开始获得正确的解决方案) 。因此它应该一直回溯到起始方块0,0并转到索引11而不是它因为当theStack为空时while循环结束而停止。如果它一直回溯到起点,我怎么能让它仍然继续,当回溯时如何将被访问的方块再次标记为假。 LIFT TJE BAN
提前谢谢你。
答案 0 :(得分:0)
当你找到一个死胡同时,你需要将当前Vertex的isvisted归为false,将其从其(当前的)最后一个顶点的邻接中删除,并将其(当前的)lastVistied设置为零: 所以现在方法dfs中的if条件是:
if (v == -1) {
System.out.println("DEAD END HERE");
theStack.pop();
vertexList[last].label = "O";
vertexList[last].wasVisited = false;
adjMat[vertexList[last].lastVisited][last] = 0;
vertexList[last].lastVisited = 0;
displayBoard();
}