1

I'm trying to implement Knight's tour.

I've been working on(more like planning) it for almost good 2~3hours now. and I still haven't made any progress. I seem to be unable to find the starting point..

below is the basic dfs method which I have to modify to knight's tour version.

class StackK
{
private final int MAX_VERTS = 25;
private int[] st;
private int top;
// ------------------------------------------------------------
public boolean isFull()
{return (top == MAX_VERTS-1);}
// ------------------------------------------------------------
public StackK()           // constructor
  {
  st = new int[MAX_VERTS];    // 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 stack
  { return (top == -1); }
// ------------------------------------------------------------
}  // end class StackK

class VertexK
{
public char label;        // label (e.g. 'A')
public boolean wasVisited;
// ------------------------------------------------------------
public VertexK(char lab)   // constructor
  {
  label = lab;
  wasVisited = false;
  }
// ------------------------------------------------------------
}   // end class VertexK

class GraphK
{
private final int MAX_VERTS = 5;
private VertexK VertexKList[]; // list of vertices
private int adjMat[][];      // adjacency matrix
private int nVerts;          // current number of vertices
private StackK theStack;
// ------------------------------------------------------------
 public GraphK()               // constructor
  {
  VertexKList = new VertexK[MAX_VERTS];
                                      // adjacency matrix
  adjMat = new int[MAX_VERTS][MAX_VERTS];
  nVerts = 0;
  for(int y=0; y<MAX_VERTS; y++)      // set adjacency
     for(int x=0; x<MAX_VERTS; x++)   //    matrix to 0
        adjMat[x][y] = 0;
  theStack = new StackK();
  for(int i=0;i<MAX_VERTS;i++)
       addVertex((char)('A'+i));

  }


// ------------------------------------------------------------
public void move(int row, int col)
{

}
// ------------------------------------------------------------
public void addVertex(char lab)
   {
   VertexKList[nVerts++] = new VertexK(lab);
   }
// ------------------------------------------------------------
public void addEdge(int start, int end)
  {
  adjMat[start][end] = 1;
  }

 // ------------------------------------------------------------
public void displayVertexK(int v)
  {
  System.out.print(VertexKList[v].label);
  }


 // ------------------------------------------------------------

public void dfs()  // depth-first search
  {                                 
  VertexKList[0].wasVisited = true;  
  displayVertexK(0);                 
  theStack.push(0);

  displayAdj();


  while( !theStack.isEmpty() )      
     {

     int v = getAdjUnvisitedVertexK( theStack.peek() );
     if(v == -1)                    
        theStack.pop();
     else                           
        {
        VertexKList[v].wasVisited = true;  
        displayVertexK(v);                 
        theStack.push(v);                
        }
     }  // end while

  // stack is empty, so we're done
  for(int j=0; j<nVerts; j++)          // reset flags
     VertexKList[j].wasVisited = false;
  }  // end dfs

 // ------------------------------------------------------------
// returns an unvisited VertexK adj to v
public int getAdjUnvisitedVertexK(int v)
  {
  for(int j=0; j<nVerts; j++)
     if(adjMat[v][j]==1 && VertexKList[j].wasVisited==false)
        return j;
  return -1;
  }  // end getAdjUnvisitedVertexK()
// ------------------------------------------------------------
public void displayAdj()
{
   for(int i=0;i<nVerts;i++){
       for(int k=0;k<nVerts;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();


  }  // end main()
}  // end class DFSApp

I chose to make the board size 5x5 for simplicity. I have googled it and looked some of the solutions and most of them didn't make sense to me. How can I make use of the DFS method? I think I could somewhat implement it if were to use recursion without using DFS. However, I have no idea, not even where to start with DFS.

Can anyone give me some guidance on where to start? I'm not asking for a solution, just need a place to start

Thank you in advance.

false
  • 10,264
  • 13
  • 101
  • 209
Hello
  • 286
  • 3
  • 18
  • what is DFS? what has it to do with your starting point? shouldn't you be able to start at any field on the board? – Rhayene Mar 22 '16 at 11:14
  • DFS = depth first search for graphs. By starting point, I meant starting point of solving the problem. – Hello Mar 22 '16 at 11:16
  • how does DFS change the choice of algorithm? (i.e. warnsdorffs rule in combination with backtracking) Sorry I might not be able to help you as I have no knowledge of this DFS – Rhayene Mar 22 '16 at 11:23
  • I'm not sure either as the book I'm using(Lafore's data structures and algorith) doesn't even mention Warnsdorff's rule. – Hello Mar 22 '16 at 11:25
  • the warndorff's rule says that you go to the field with the smallest number of possible moves from there on first (which reduces the backtracking a lot) but the bigger the board the more often you have more than one field with the same number of possible next moves (on a 8x8 board you have 2 starting points where you need the backtracking then) - squirrel and cull refined that algorithm later - but it seems it doesn't have anything to do with your DFS ^^ – Rhayene Mar 22 '16 at 12:07
  • Thanks for mentioning it, i will make sure i look that up after I figure this out ! – Hello Mar 22 '16 at 12:09

1 Answers1

1

Depth first search as such is a general strategy for enumeration of the nodes of a graph; it can be implemented recursively or iteratively supported by a user-defined stack. The graph to search can be encoded explicitly, which is usually done when the approach is explained.

Hoever, in your case, the graph (which is some kind of decision tree of a game) does not need to be encoded explicitly; new successor nodes can be generated by selecting a feasible move, representing the new state on a global state (representing the board), and after recursive evaluation undo the move to proceed with the next feasible move. Using this approach, backtracking can be implemented via recursion.

Codor
  • 17,447
  • 9
  • 29
  • 56
  • @maytham-ɯɐɥʇʎɐɯ Thanks for the remark, I updated the answer. – Codor Mar 22 '16 at 11:55
  • Thank you. Will I have to create a separate method to show feasible moves and go from there? where should I start? – Hello Mar 22 '16 at 11:55
  • 2
    @LookAtTheBigPicture Create some structure (array or the like) to represent the borard; then create a method to obtain all possible moves for a board state and a method to do and undo moves. Finally you need some code to detect whether you have obtained a final state (i.e. a leaf of the search tree). These basic building blocks then have to be plugged into the depth-first search. – Codor Mar 22 '16 at 11:59
  • isn't adjMat used as a board in my code? I thought I was adding '1's to the adjMat to represent the moves of the knight. Are you saying i need a another matrix ? – Hello Mar 22 '16 at 12:04
  • No, `adjMat` seems to be suitable for that. Additional hint - the search has reached a final state if and only if all fields are visited (contain ones) or some fields are unvisited, but no legal move is possible. – Codor Mar 22 '16 at 12:04