Knight Tour Problem

哈密顿图

它是一个无向图,由天文学家哈密顿提出,由指定的起点前往指定的终点,途中经过所有其他节点且只经过一次。在图论中是指含有哈密顿回路的图,闭合的哈密顿路径称作为哈密顿回路,含有图中所有顶点的路径称作为哈密顿路径。

骑士巡逻(Knight's tour)

骑士巡逻是指按照国际象棋中骑士的规定走法走遍整个棋盘的每一个方格,而且每一个网格只能经过一次。假若骑士能够重新走回最初的位置,则称此巡逻为封闭巡逻,否则,称为开巡逻。

Knight's Tour Problem

Description :

The knight is placed on the first block of an empty board and , moving according to the rules of chess, must visit each square exactly once

Following is chessboard with 8 * 8 cells. Numbers in cells indicate move number of Knight.

注: 上面8 * 8 的表格表明一条路径,由 0 -> 1 -> 2 …… -> 63, 即由左上角->右上角

Backtracking Algorithm for Knight's tour

If all squares are visited 
	print the solution 
Else 
	a) Add one of the next moves to solution vector and recursively
	check if this move leads to a solution.(国际象棋中骑士只有8中走法,每次选择其中的一种)
	b) If the move chosen in the above step doesn't lead to a solution then remove this move from the solution vector and try other alternative moves
	c) If none of the alternatives work then return false("No solution exists")

Source code

#include <stdio.h>
#include <stdbool.h>

#define N 8

int solveKTUtil(int x, int y, int movi, int sol[N][N], int xMove[], int yMove[]);

/*
 * A utility function to check if i,j are valid indexes
 * for N * N chessboard
 */
bool isSafe(int x, int y, int sol[N][N])
{
    return (x >= 0 && x < N && y >= 0 && y < N && sol[x][y] == -1);
}

/*
 * A utility function to print solution matrix sol[N][N]
 */
void printSolution(int sol[N][N])
{
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            printf(" %2d", sol[i][j]);
        }
        printf("\n");

    }
}

/*
 * This function solves the Knight tour problem using Backtracking
 * This function mainly uses solveKTUtil() to solve the problem
 * It return false if no complete tour is possible
 * otherwise return true and prints the tour
 * Note: this function prints one of the feasible solutions.
 */
bool solveKT()
{
    int sol[N][N];
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            sol[i][j] = -1;
        }
    }
    /* xMove[] and yMove[] define next move of Knight.
       xMove[] is for next value of x coordinate
       yMove[] is for next value of y coordinate */
    int xMove[8] = {  2, 1, -1, -2, -2, -1,  1,  2 };
    int yMove[8] = {  1, 2,  2,  1, -1, -2, -2, -1 };

    // Since the Knight is initially at the first block
    sol[0][0]  = 0;

    /* Start from 0,0 and explore all tours using
       solveKTUtil() */
    if (solveKTUtil(0, 0, 1, sol, xMove, yMove) == false)
    {
        printf("Solution does not exist");
        return false;
    }
    else
        printSolution(sol);

    return true;
}

/* 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 k, next_x, next_y;
    if (movei == N*N)
        return true;

    /* Try all next moves from the current coordinate x, y */
    for (k = 0; k < 8; k++)
    {
        next_x = x + xMove[k];
        next_y = y + yMove[k];
        if (isSafe(next_x, next_y, sol))
        {
            sol[next_x][next_y] = movei;
            if (solveKTUtil(next_x, next_y, movei+1, sol,
                            xMove, yMove) == true)
                return true;
            else
                sol[next_x][next_y] = -1;// backtracking
        }
    }

    return false;
}

int main(int argc, char *argv[]){
    solveKT();
    return 0;
}

Output

  0  59  38  33  30  17   8  63
 37  34  31  60   9  62  29  16
 58   1  36  39  32  27  18   7
 35  48  41  26  61  10  15  28
 42  57   2  49  40  23   6  19
 47  50  45  54  25  20  11  14
 56  43  52   3  22  13  24   5
 51  46  55  44  53   4  21  12

主要内容源自https://www.geeksforgeeks.org/?p=12916

posted @ 2018-02-11 22:13  一棵球和一枝猪  阅读(770)  评论(0编辑  收藏