骑士使用Graph(DFS)Java游览

时间:2016-03-24 09:43:44

标签: java algorithm data-structures

我正在尝试使用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

提前谢谢你。

1 个答案:

答案 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();
}