Home > Mobile >  knight tour algorithm returns maximum number of trials (Backtracking)
knight tour algorithm returns maximum number of trials (Backtracking)

Time:09-02

I'm trying to make the knight tour problem, return the maximum number of moves possible, (when n = 3 will be 8) instead of just 1 for when it's possible and 0 when there's no solution.

My return is always coming back to zero.

It looks like I have to change the base case because my recursion goes back to the beginning where the plays parameter is equal to 0.

Can someone help me??

#include <stdio.h>
#define N 3
 
int solveKTUtil(int x, int y, int movei, int sol[N][N], int xMove[], int yMove[], int numJog);
 
int isSafe(int x, int y, int sol[N][N])
{
    return (x >= 0 && x < N && y >= 0 && y < N && sol[x][y] == -1);
}
 
void printSolution(int sol[N][N])
{
    for (int x = 0; x < N; x  ) {
        for (int y = 0; y < N; y  )
            printf(" - ", sol[x][y]);
        printf("\n");
    }
}
 
void solveKT()
{
    int sol[N][N];
 
    /* Initialization of solution matrix */
    for (int x = 0; x < N; x  )
        for (int y = 0; y < N; y  )
            sol[x][y] = -1;
 
    sol[0][0] = 0; // Since the Knight is initially at the first block
 
    /* xMove[] and yMove[] define next move of Knight. */
    int xMove[8] = { 2, 1, -1, -2, -2, -1, 1, 2 };
    int yMove[8] = { 1, 2, 2, 1, -1, -2, -2, -1 };
     
    /* Start from 0,0 and explore all tours using solveKTUtil() */
    printf("Numbers of Attempts %d\n" , solveKTUtil(0, 0, 1, sol, xMove, yMove, 0));
    printSolution(sol);            
 
}
 
/* A recursive utility function to solve Knight Tour problem */
int solveKTUtil(int x, int y, int movei, int sol[N][N], int xMove[N], int yMove[N], int plays)
{
    int play = 0;
    if (movei == N * N) 
        return 1;
 
    for (int k = 0; k < 8; k  ) {
        int next_x = x   xMove[k];
        int next_y = y   yMove[k];
        if (isSafe(next_x, next_y, sol)) 
        {
            plays = plays  1;
            printf("%d", plays);
            printf("\n");
            play = plays   1;
            sol[next_x][next_y] = movei;
            if (solveKTUtil(next_x, next_y, movei   1, sol, xMove, yMove, plays) == 1)
                return play;
            else
                sol[next_x][next_y] = -1; // backtracking
        }
    }
    
    // return 0;
}
 
void main()
{
    solveKT();    
}

CodePudding user response:

The first problem is that your condition on backtracking isn't updated for the new algorithm : if (solveKTUtil(next_x, next_y, movei 1, sol, xMove, yMove, plays) == 1) is true only if the recursion returned exactly 1. You want to change that to > 0

The second problem, is that you don't return the maximum number of moves possibles : the variable play count the number of moves you tested for a particular step, that's totally different.

What you want to return at step movei is:

  • if no movement is valid, return 0
  • if a recursive call return N*N directly return that (it's not possible to do better)
  • else keep the maximum return value of the recursive calls, and return the max between that value and movei

CodePudding user response:

This apparently solved the problem I removed the if, start the play variable at 1 and did a count on the recursive calls

#include <stdio.h>
    #define N 3
     
    int solveKTUtil(int x, int y, int movei, int sol[N][N], int xMove[], int yMove[], int numJog);
     
    int isSafe(int x, int y, int sol[N][N])
    {
        return (x >= 0 && x < N && y >= 0 && y < N && sol[x][y] == -1);
    }
     
    void printSolution(int sol[N][N])
    {
        for (int x = 0; x < N; x  ) {
            for (int y = 0; y < N; y  )
                printf(" - ", sol[x][y]);
            printf("\n");
        }
    }
     
    void solveKT()
    {
        int sol[N][N];
     
        /* Initialization of solution matrix */
        for (int x = 0; x < N; x  )
            for (int y = 0; y < N; y  )
                sol[x][y] = -1;
     
        sol[0][0] = 0; // Since the Knight is initially at the first block
     
        /* xMove[] and yMove[] define next move of Knight. */
        int xMove[8] = { 2, 1, -1, -2, -2, -1, 1, 2 };
        int yMove[8] = { 1, 2, 2, 1, -1, -2, -2, -1 };
         
        /* Start from 0,0 and explore all tours using solveKTUtil() */
        printf("Numbers of Attempts %d\n" , solveKTUtil(0, 0, 1, sol, xMove, yMove, 0));
        printSolution(sol);            
     
    }
     
    /* A recursive utility function to solve Knight Tour problem */
    int solveKTUtil(int x, int y, int movei, int sol[N][N], int xMove[N], int yMove[N], int plays)
    {
        int play = 1;
        if (movei == N * N) 
            return movei;
     
        for (int k = 0; k < 8; k  ) {
            int next_x = x   xMove[k];
            int next_y = y   yMove[k];
            if (isSafe(next_x, next_y, sol)) 
            {
                
                sol[next_x][next_y] = movei;
                play = solveKTUtil(next_x, next_y, movei   1, sol, xMove, yMove, plays   1)   1;
                sol[next_x][next_y] = -1; // backtracking
                
            }
        }
    
        return play;
    }
     
    void main()
    {
        solveKT();    
    }
  • Related