0

这是我写的代码。

#include "genlib.h"
#include <iostream>
#include <math.h>
#include "vector.h"

struct square
{
    int x;
    int y;

};


bool knighttour(square start,int &counter,int cb[][8]);
Vector <square> generatemoves (square start);
void Marksquare(int &cb,int ctr);
void Unmarksquare(int &cb);
bool IsLegal(square a,int cb[][8]);




int main() 
{
    int chessboard[8][8];

    for (int i=0;i<8;i++)
        for (int j=0;j<8;j++)
            chessboard[i][j]=-1;

    int counter=1;

    for (int i=0;i<8;i++){
        for (int j=0;j<8;j++){
            square temp;
            temp.x=i;
            temp.y=j;
            if (knighttour(temp,counter,chessboard))
            {
                for (int k=0;k<8;k++){
                    cout<<chessboard[k][0]<<chessboard[k][1]<<chessboard[k][2]<<chessboard[k][3]<<chessboard[k][4]<<chessboard[k][5];
                    cout<<chessboard[k][6]<<chessboard[k][7]<<endl;}


            }

        }
    }


    return 0;
}


bool knighttour(square pt,int &counter,int cb[][8])
{

    Marksquare(cb[pt.x][pt.y],counter);
    if (counter==64)
        return true;

    counter++;

    Vector <square> temp = generatemoves(pt);

    for (int i=0;i<temp.size();i++)
    {
        if (IsLegal(temp[i],cb))
            knighttour(temp[i],counter,cb);
    }

    Unmarksquare(cb[pt.x][pt.y]);
    counter--;
    return false;

}



Vector <square> generatemoves (square start)
{
    Vector <square> temp;
    Vector <square> temp2;

        square mv1;
        mv1.x=start.x+2;
        mv1.y=start.y+1;
        temp.add(mv1);

        square mv2;
        mv2.x=mv1.x;
        mv2.y=start.y-1;
        temp.add(mv2);


        square mv3;
        mv3.y=start.y+2;
        mv3.x=start.x+1;
        temp.add(mv3);

        square mv4;
        mv4.y=start.y+2;
        mv4.x=start.x-1;
        temp.add(mv4);

        square mv5;
        mv5.x=start.x-2;
        mv5.y=start.y+1;
        temp.add(mv5);

        square mv6;
        mv6.x=start.x-2;
        mv6.y=start.y-1;
        temp.add(mv6);

        square mv7;
        mv7.y=start.y-2;
        mv7.x=start.x-1;
        temp.add(mv7);

        square mv8;
        mv8.y=start.y-2;
        mv8.x=start.x+1;
        temp.add(mv8);


        for (int i=0;i<temp.size();i++)
            if (temp[i].x>=0 && temp[i].x<=7 && temp[i].y>=0 && temp[i].y<=7)
                temp2.add(temp[i]);




        return temp2;
}



void Marksquare(int &a,int ctr)
{
    a=ctr;

}



void Unmarksquare(int &a)
{
    a=-1;
}


bool IsLegal(square a,int cb[][8])
{
    if (cb[a.x][a.y]==-1)
        return true;
    else 
        return false;
}

一点解释。我使用 int [8][8] 来表示棋盘,最初我在棋盘的每个方格中输入数字 -1。

当骑士移动时,它用计数器(int counter)标记他访问的方格,然后从那里(以及骑士可以采取的所有合法移动)进行递归调用以找到路径(目标是每个方格只访问一次)。

一旦计数器达到 64,该函数bool knighttour(square start,int &counter,int cb[][8]) 必须返回 true,然后主程序应该显示“骑士之旅”,因为它在 [8][8] 棋盘上被标记。

我相信我提供的上述代码在无限循环上运行。我让它运行了 3 分钟。

4

3 回答 3

3

理论说

...重要的是要注意,穷举的蛮力方法(一种遍历所有可能的移动序列的方法)永远不能应用于骑士巡回赛问题(除了非常小的棋盘尺寸)。对于一个常规的 8x8 棋盘,大约有 4×1051 个可能的移动序列,[9] 并且迭代如此大量的移动将花费不可思议的时间。

因此,为确保您的程序正常工作,请尝试使用较小的电路板尺寸(例如 4x4)。

为确保您的程序在合理的时间内以 8x8 运行,您必须更改算法。除了这里列出的还有很多。

- 编辑 -

同样为了确保您的程序正在做某事,在您仍在开发它时添加一些跟踪总是一个好主意。

例如

bool knighttour(square pt,int &counter,int cb[][8]) {

printf("\r%d    ", counter);  // <<<---
Marksquare(cb[pt.x][pt.y],counter);
if (counter==64)
    return true;

counter++;

Vector <square> temp = generatemoves(pt);

for (int i=0;i<temp.size();i++)
{
    if (IsLegal(temp[i],cb))
        knighttour(temp[i],counter,cb);
}

Unmarksquare(cb[pt.x][pt.y]);
counter--;
return false;

}
于 2011-09-20T20:39:28.867 回答
1

此代码可能会尝试在 Knights Tour 中查找所有可能的路线,并将返回最后找到的路线。

代替

for (int i=0;i<temp.size();i++)
{
    if (IsLegal(temp[i],cb))
        knighttour(temp[i],counter,cb);
}

尝试

for (int i=0;i<temp.size();i++)
{
    if (IsLegal(temp[i],cb))
    {
        if(knighttour(temp[i],counter,cb))
        { 
             return true;
        }
    }

}
于 2011-09-20T20:51:38.227 回答
0

我看到的一件事是,尽管您return truecounter==64knighttour 中并没有传播,但调用它的函数将返回 false .. 所以您永远不会在 main() 中注意到它。

也就是说,即使你修复了你的算法,它也可能不会在你的一生中完成。

于 2011-09-20T20:40:54.380 回答