我写了一个代码来解决knight's tour problem,问题是有时输出错误。
尤其是在板子尺寸奇数不多的情况下:例如,从[0,1]
位置开始并以5X5的板子给我:
[[0, 1], [2, 0], [4, 1], [3, 3], [1, 4], [0, 2], [1, 0], [3, 1], [4, 3], [2, 2], [0, 3], [2, 4], [1, 2], [0, 0], [2, 1], [4, 0], [3, 2], [1, 3], [3, 4], [4, 2], [3, 0], [1, 1], [2, 3], [2, 3], [4, 4]]
如您所见,存在重复的[2,3]
。我检查了给定电路板尺寸后算法得到多少错误输出,我发现在奇数尺寸下,正确的输出仅占50%的时间,而偶数尺寸则在大约99%的时间。怎么可能呢?
def rule(start , size):
moves = [start ,]
plus = [(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]
while 1 == 1 :
d = 7
for x in plus:
s = list(plus)
c = 0
q = [ start[0]+x[0] , start[1]+x[1] ]
if valid(q , size , moves):
if len(moves) == size ** 2 -1 :
moves.append(q)
return moves
s.remove((-x[0] , -x[1]))
for y in s :
p = [ q[0]+y[0] , q[1]+y[1] ]
if valid(p , size , moves):
c = c+1
if 0 < c <= d :
l = q
d = c
start = l
moves.append(start)
def valid(q , size , moves):
if 0 <= q[0] < size and 0 <= q[1] < size :
if q not in moves:
return True
return False
答案 0 :(得分:0)
当所选路径遇到“死角”时会发生这种情况。
在您提到的示例中,起始点为[0,1],大小为5x5,这是在选择正方形[2,3]时(第一次)发生的。届时,仅需再访问2个正方形。它们是[0,4]和[4,4]。但是这些广场都没有邻居。
因此,c
对于这两个有效的q
移动都保持为0。这意味着l
的值将不被设置-保留其先前的值,仍然是[2,3]。因此,当您执行start = l
Warnsdorff的规则并不能绝对保证实现此次旅行。在算法执行过程中的几个点上,都有联系-动作具有相等的c
值。在这种情况下,您采用的最后一个值为c
。但这可能是您需要从这些联系中选择另一个来获得成功。
因此,您要么必须实施回溯算法,即可检测到此类“死胡同”,然后回溯到出现平局的位置,然后从那里找到另一条路径。
或者您应该做一些更复杂的事情,因为似乎存在从关系中选择“正确”行动的方法。请参阅Wikipedia,以获得对两篇描述成功打破平局方法的文章的引用。