我试着用回溯法为骑士之旅问题编写代码。我的代码适用于4x4矩阵,但对于8x8矩阵,它不会在输出屏幕上显示任何内容。
我不知道我做错了什么。
我的代码就是这样工作的:
如果所有的广场都参观过
print the solution
其他的
>
向solution vector添加下一步动作之一,并递归检查该动作是否会导致解决方案。(一个骑士最多可以走八步。我们在这一步的八步中选择一步)。
如果在上述步骤中选择的移动没有导致解决方案,则从解决方案向量中删除此移动,然后尝试其他替代移动。
如果所有替代方案都不起作用,则返回false(返回false将删除递归中先前添加的项,如果通过递归的初始调用返回false,则“不存在解决方案”)
以下是我写的代码:
#include<iostream>
using namespace std;
#define n 8
int safe(int c[n][n],int i, int j)
{
if((i>=0&&i<n)&&(j>=0&&j<n))
{
if(c[i][j])
return 0;
else
return 1;
}
return 0;
}
int knightstour(int c[n][n],int i,int j,int k)
{
if(k==n*n)
{
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
cout<<c[i][j]<<" ";
cout<<endl;
}
return 1;
}
else
{
c[i][j]=k;
if(safe(c,i+2,j+1))
{
if(knightstour(c,i+2,j+1,k+1))
return 1;
}
if(safe(c,i+2,j-1))
{
if(knightstour(c,i+2,j-1,k+1))
return 1;
}
if(safe(c,i-2,j+1))
{
if(knightstour(c,i-2,j+1,k+1))
return 1;
}
if(safe(c,i-2,j-1))
{
if(knightstour(c,i-2,j-1,k+1))
return 1;
}
if(safe(c,i+1,j+2))
{
if(knightstour(c,i+1,j+2,k+1))
return 1;
}
if(safe(c,i-1,j+2))
{
if(knightstour(c,i-1,j+2,k+1))
return 1;
}
if(safe(c,i+1,j-2))
{
if(knightstour(c,i+1,j-2,k+1))
return 1;
}
if(safe(c,i-1,j-2))
{
if(knightstour(c,i-1,j-2,k+1))
return 1;
}
c[i][j]=0;
return 0;
}
}
int main()
{
int c[n][n]={0};
if(!knightstour(c,0,0,0))
cout<<"solution doesn't exist";
return 1;
}
让我们暂时假设您的算法是正确的,因为它似乎产生了至少对n==6
有用的东西:
0 13 20 23 34 11
21 30 35 12 19 24
14 1 22 31 10 33
29 4 7 16 25 18
6 15 2 27 32 9
3 28 5 8 17 26
以下是使用不同的n
值运行代码的时钟时间结果:
===== 1 0m 0.001s
===== 2 0m 0.001s
===== 3 0m 0.003s
===== 4 0m 0.002s
===== 5 0m 0.070s
===== 6 0m 35.997s
===== 7 ...
你会注意到,我还没有n=7
的数字,它仍然在运行,在5.5小时后开始计数:-)
因为它将持续至少那么长时间(大约330分钟),我们可能可以使用回归分析计算8号的最小数字(使用仅使用5号、6号和尚不完整的7号的数据的二次多项式)(a)。根据这些计算,这一最低数字约为16.5小时。
然而,即使它不是二次的,对于6x6的板,它跳到了36秒,对于7x7,它跳到了(至少)5.5小时,这意味着你使用的算法不能很好地扩展。所以你可能会发现它正在工作,你可能只需要等一会儿。可能很长一段时间:-)
(a)如果你感兴趣(或者想检查/批评我的方法),这是我的分析。警告:数学超前...
我们有数据集:
x (value of n) y (seconds taken)
-------------- -----------------
5 0.07
6 36.00
7 600.00 (when it had been running ten minutes)
使用以下公式:
y = ax^2 + bx + c
我们得到联立方程:
0.07 = 25a + 5b + c (1)
36 = 36a + 6b + c (2)
600 = 49a + 7b + c (3)
减去配对可以得到:
(2) - (1): 35.93 = 11a + b (4)
(3) - (2): 564 = 13a + b (5)
(5) - (4): 528.07 = 2a
所以a=264.035
。将其替换回(5)
,得到b=-2868.455
,将a
和b
替换为(3)
,得到c=7741.47
。将这三个值放入方程(1)
,(2)
和(3)
中,得到了期望值。
这是我高中时使用的方法,但是,当然,如果有一个快速而肮脏的Python程序,当600
图形发生变化时,该程序可以快速工作,这样做会更好:
import sys
y5 = 0.07 ; y6 = 36 ; y7 = int(sys.argv[1]) * 60
a = ((y7 - y6) - (y6 - y5)) / 2
b = (y7 - y6) - 13 * a
c = y7 - 49 * a - 7 * b
y8 = 64 * a + 8 * b + c
print(y8, y8 / 3600)
你只需运行它,提供7号的当前值,它就会推出最小值(以秒和小时为单位)。
我正在尝试编写一个骑士之旅算法,它有两个数组,访问和板。ACCESS是我用来判断下一步是什么的数组,board是用户将看到的最终结果的数组。我的算法通过检查找到可用移动次数最少的正方形,然后到达那里。如果恰好有两个可能的移动,并且可用的移动次数相同,我会找到哪一个离中心最远(离边界最近),然后移动到该点。这个算法应该会一直提供一个完美的64步骑士巡演程序,但我通常只得到大约60步,有人能告诉我为什
我制作了这段代码来完成骑士之旅,你必须和一个没有重复的骑士一起到达棋盘上的每一个方块,但我有一些问题。它只会打印一个没有移动的空棋盘,我不知道如何修复它。 测试人员: 如果您有任何建议,我将不胜感激,我正在为一门课做这件事,所以我需要尽快完成。
DreamChess 是一款开放源码、跨平台(可在 Windows、Mac OS X 及 Linux 上运行)的 3D 国际象棋游戏。该游戏包含自身的引擎 Dreamer,提供各种国际象棋棋盘,并具有背景音乐及声效等其他附属功能。
我对我的象棋游戏的最小极大算法的实现有问题。它的大部分似乎都起作用了,但它要么从来没有做出好的动作,要么对它们的评估(基于两个玩家的活动棋子的分数)出了问题。例如,如果我设置了check(例如,傻瓜的伴侣),ai会做一些随机的事情,而不是杀死国王。我真的找不出我做错了什么。 评估电路板的类StandardBoardEvaluator在经过一些测试后似乎可以工作,因此问题很可能出现在MiniMax实
我已经有一个Board对象,包含一个碎片列表。Piece是一个抽象类,有一个位置(x,y)和一个颜色(黑色或白色)。然后是King、Queen、Knight这三个类,实现了Piece类。 谢谢