0

Could anyone point the flaw in the code? The idea that I used is backtracking with recurrence and I would like to stick to this way of sloving the given problem. When the variable moves is <= 60 couple of answers are printed instantly though the program is still running. If moves = 61,62 it takes couple of minutes to print some solutions and if moves = 63 no solution is printed within 15 mins in both cases the program is still running. Here is the code:

//checking on which move was the square visited
int board[8][8] = {{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}};
int x = 0;//x and y coordinate of the knight's placement
int y = 0;
//move knight by
int move_to[8][8] = {{1,2},{-1,-2},{-1,2},{1,-2},{2,1},{-2,-1},{-2,1},{2,-1}};
//how many moves have been done
int moves = 0;

void solve()
{
    //printing one solution
    if(moves==63)
    {
        for(int k = 0; k < 8; k++)
        {
            for(int n = 0; n < 8; n++)
                cout << setw(2) << board[k][n] << " ";
            cout << "\n";
        }
        cout << "--------------------\n";
        return;
    }
    else
    {
     for(int i = 0; i < 8; i++)
    {
        //checking if knight is not leaving the board
        if(x+move_to[i][0]<0 || x+move_to[i][0]>7 || y+move_to[i][1]<0 ||
            y+move_to[i][1]>7 || board[x+move_to[i][0]][y+move_to[i][1]]>0)
            continue;
        //moving theknight
        x+=move_to[i][0];
        y+=move_to[i][1];
        //increasing the moves count
        moves++;
        //marking the square to be visited
        board[x][y] = moves+1;
        //backtracking
        solve();
        board[x][y] = 0;
        x-=move_to[i][0];
        y-=move_to[i][1];
        moves--;
    }
    }
}

int main()
{
    solve();

    return 0;
}
1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
somerndguy
  • 103
  • 3
  • 3
    doesn't finish compiling or doesn't finish running? – Alan Birtles Apr 24 '21 at 18:41
  • cmd.exe after couple of solutions printed, prints '_' so, I think it means that - doesn't finish running is what I meant ;D. Gonna fix it. – somerndguy Apr 24 '21 at 18:47
  • Do you have optimizations turned on when you compile? – 1201ProgramAlarm Apr 24 '21 at 19:08
  • Removing `moves--;` it executes. Maybe you are asking how to implement your specific goal. – MatG Apr 24 '21 at 19:08
  • @1201ProgramAlarm I don't even know what you are asking for :D – somerndguy Apr 24 '21 at 19:12
  • 1
    You need to add a heuristic to make this computationally feasible, I seem to recall that you should move to a square that is surrounded by already visited squares. – Captain Giraffe Apr 24 '21 at 19:26
  • 1
    Ehm, when choosing the next move would make sense exclude the previous square? If not there is an infinite loop. – MatG Apr 24 '21 at 19:37
  • Doesn't line board[x][y] = 0; solve the issue? The one below solve(); call. – somerndguy Apr 24 '21 at 19:50
  • @MatG Decrementing moves is part of the backtracking, along with subtracting from x and y and resetting the board location back to 0. The previous square is ignored as part of the `if` statement (because it would be nonzero). – 1201ProgramAlarm Apr 24 '21 at 19:53
  • @1201ProgramAlarm Have you got any idea about the flaw in code? – somerndguy Apr 24 '21 at 20:03
  • You're doing way too much work every iteration. A few things to look in to: use `unsigned`s to eliminate half of the bounds checks, or eliminate them entirely (with a little more work), just leaving the "occupied" check. Rather than double indexing you can use a single index (so rather than an 8x8 2 dimensional array, use a 64 element 1 dimensional one). – 1201ProgramAlarm Apr 25 '21 at 18:05
  • I' ve tried that but the result is still the same. While looking for a flaw I found this: https://www.geeksforgeeks.org/the-knights-tour-problem-backtracking-1/ the code there seems to be very similar to mine but unlike mine it works. Do you know what is the difference between those two codes? – somerndguy Apr 25 '21 at 18:33

1 Answers1

0

I remember this problem from study. I do not fix them but I change initial position then the first path is found faster (that is how I passed this lab ;P). It is normal because the number of path is too big.

But you can:

  • choose from move_to in random order
  • use multiple threads

Other hand you can read about "Constraint Programming"

kamaz08
  • 21
  • 1
  • 5
  • I would like to solve the problem with top-left corner as a starting point and maybe later genralize. I don't see how using move_to in random order makes the program faster. As for the "multiple threads" part u mean treads in CPU right? – somerndguy Apr 24 '21 at 19:49
  • Adding probability you will average the time to get solution. Adding multiple threads you can find multiple path simultaneously but your code is not thread save. Also you can add constraint when a unavailable field exists (example: field [0][7] is not visited but [1][5] and [2][6] is. Your program never find path to [0][7] but path will continue to be searched). – kamaz08 Apr 25 '21 at 15:52
  • I don't want to realy on sheer luck I just want to make the algorithm efficient. I' ve run the code that prints solutions for moves = 60 and indeed the square [0][7] is never visited but I dont understand your reasoning. Could you elaborate? – somerndguy Apr 25 '21 at 18:44
  • You can not search every paths in real time. {{-2,-1},{2,-1},{-2,1},{2,1},{-1,-2},{1,-2},{-1,2},{1,2}} - try with that move_to array. by adding probability you avoid the unfortunate order of moves. Constraint - you don't print ways with less number than 64. And current moves is { {1,X,0,...,0}, {0,0,0,3,0,...,0}, {5,2,7,0,...,0}, {8,0,4,0,...,0}, ... } X field is not available but your program will still working with this path. – kamaz08 Apr 25 '21 at 21:55