I code the Knight\'s tour algorithm in c++ using Backtracking method. But it seems too slow or stuck in infinite loop for n > 7 (bigger than 7
Examine your algorithm. At each depth of recursion, you examine each of 8 possible moves, checking which are on the board, and then recursively process that position. What mathematical formula best describes this expansion?
You have a fixed board size, int[8][8], maybe you should make it dynamic,
class horse
{
...
int** board; //[s][s];
...
};
horse::horse(int s)
{
int i, j;
size = s;
board = (int**)malloc(sizeof(int*)*size);
for(i = 0; i < size; i++)
{
board[i] = (int*)malloc(sizeof(int)*size);
for(j = 0; j < size; j++)
{
board[i][j] = 0;
}
}
}
Changing your tests a little by adding a function to check that a board move is legal,
bool canmove(int mx, int my)
{
if( (mx>=0) && (mx=0) && (my
Note that the mark() and unmark() are very repetitive, you really only need to mark() the board, check all legal moves, then unmark() the location if none of the backtrack() return true,
And rewriting the function makes everything a bit clearer,
bool horse::backtrack(int x, int y)
{
if(counter > (size * size))
return true;
if(unvisited(board[x][y]))
{
mark(board[x][y]);
if( canmove(x-2,y+1) )
{
if(backtrack(x-2, y+1)) return true;
}
if( canmove(x-2,y-1) )
{
if(backtrack(x-2, y-1)) return true;
}
if( canmove(x-1,y+2) )
{
if(backtrack(x-1, y+2)) return true;
}
if( canmove(x-1,y-2) )
{
if(backtrack(x-1, y-2)) return true;
}
if( canmove(x+2,y+1) )
{
if(backtrack(x+2, y+1)) return true;
}
if( canmove(x+2,y-1) )
{
if(backtrack(x+2, y-1)) return true;
}
if( canmove(x+1,y+2) )
{
if(backtrack(x+1, y+2)) return true;
}
if( canmove(x+1,y-2) )
{
if(backtrack(x+1, y-2)) return true;
}
unmark(board[x][y]);
}
return false;
}
Now, think about how deep the recursion must be to visit every [x][y]? Fairly deep, huh? So, you might want to think about a strategy that would be more efficient. Adding these two printouts to the board display should show you how many backtrack steps occured,
int counter = 1; int stepcount=0;
...
void horse::print()
{
cout<< "counter: "<
Here is the costs for 5x5, 6x6, 7x6,
./knightstour 5
>>> Successful! <<<
counter: 26
stepcount: 253283
./knightstour 6
>>> Successful! <<<
counter: 37
stepcount: 126229019
./knightstour 7
>>> Successful! <<<
counter: 50
stepcount: 56342
Why did it take fewer steps for 7 than 5? Think about the ordering of the moves in the backtrack - if you change the order, would the steps change? What if you made a list of the possible moves [ {1,2},{-1,2},{1,-2},{-1,-2},{2,1},{2,1},{2,1},{2,1} ], and processed them in a different order? We can make reordering the moves easier,
int moves[ ] =
{ -2,+1, -2,-1, -1,+2, -1,-2, +2,+1, +2,-1, +1,+2, +1,-2 };
...
for(int mdx=0;mdx<8*2;mdx+=2)
{
if( canmove(x+moves[mdx],y+moves[mdx+1]) )
{
if(backtrack(x+moves[mdx], y+moves[mdx+1])) return true;
}
}
Changing the original move sequence to this one, and running for 7x7 gives different result,
{ +2,+1, +2,-1, +1,+2, +1,-2, -2,+1, -2,-1, -1,+2, -1,-2 };
./knightstour 7
>>> Successful! <<<
counter: 50
stepcount: -556153603 //sheesh, overflow!
But your original question was,
The question is: What is the Time complexity for this algorithm and how can I optimize it?!
The backtracking algorithm is approximately 8^(n^2), though it may find the answer after as few as n^2 moves. I'll let you convert that to O() complexity metric.
I think this guides you to the answer, without telling you the answer.