Knight Tour Problem

哈密顿图

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

骑士巡逻(Knight's tour)

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

Knight's_tour_anim_2.gif

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

转载于:https://www.cnblogs.com/chunzhulovefeiyue/p/8443343.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值