这是我写的代码。
#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计数器)访问的方格,并从那里(并且对于骑士可以采取的所有合法移动)进行递归调用以找到路径(目标是访问每个正方形一次)。
一旦计数器击中64,函数bool knighttour(square start,int &counter,int cb[][8])
必须返回true,然后主程序应显示“骑士之旅”,因为它在[8] [8]棋盘上标记。
我相信我提供的上述代码在无限循环上运行。我让它运行3分钟。
答案 0 :(得分:3)
......重要的是要注意一个彻底的蛮力方法(一个遍历所有可能的移动序列的方法)永远不能应用于Knight's Tour问题(除了非常小的电路板尺寸)。对于常规的8x8棋盘,大约有4×1051个可能的移动序列,[9]并且需要花费不可思议的时间来迭代这么多的移动。
因此,为了确保您的程序有效,请尝试使用较小的电路板尺寸(例如4x4)。
为确保您的程序在合理的时间内适用于8x8,您必须更改算法。除了here列出的内容之外,还有许多其他内容。
- 编辑 -
为了确保您的程序正在执行某些操作,在您开发它时添加一些跟踪始终是一个好主意。
E.g。
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;
}
答案 1 :(得分:1)
此代码可能会尝试在骑士之旅中找到所有可能的路线,并将返回最后找到的路线。
而不是
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;
}
}
}
答案 2 :(得分:0)
我看到的一件事是,虽然你return true
在骑士时counter==64
,但是没有传播,调用它的函数会返回false ..所以你永远不会注意到它()。
尽管如此,即使您修复了算法,它也可能无法在您的生命周期内完成。