我尝试使用回溯来解决这个问题,并打印出所有可能的解决方案。
出现了两个问题:
1. 我可以使用其他技术实现n queen吗?
2. 是否可以让以下代码仅打印第一个解决方案然后终止?
我目前的代码使用回溯:
n = 8
x = [-1 for x in range(n)]
def safe(k,i):
for j in xrange(k):
if x[j] == i or abs(x[j] - i) == abs(k - j) :
return False
return True
def nqueen(k):
for i in xrange(n):
if safe(k,i):
x[k] = i
if k == n-1:
print "SOLUTION", x
else:
nqueen(k+1)
nqueen(0)
注意:我对不依赖于特定编程语言的技术感兴趣。
答案 0 :(得分:3)
根据Wikipedia,您可以使用启发式方法:
这种启发式解决了任何N≥4的N个皇后。它形成了水平位置(列)简单增加的皇后垂直位置(行)的数字列表。八个女王之谜的N是8。
这种启发式方法是O(n)
,因为它只是在一些if
语句之后打印结果。
关于你的第二个问题:“是否可以在下面制作代码,只打印第一个解决方案然后终止?”
您可以在打印后致电sys.exit(0)
:
import sys n = 8 x = [-1 for x in range(n)] def safe(k,i): for j in xrange(k): if x[j] == i or abs(x[j] - i) == abs(k - j) : return False return True def nqueen(k): for i in xrange(n): if safe(k,i): x[k] = i if k == n-1: print "SOLUTION", x sys.exit(0) else: nqueen(k+1) nqueen(0)
或者,您可以返回一个值,然后传播该值,如果它指示终止:
n = 8 x = [-1 for x in range(n)] def safe(k,i): for j in xrange(k): if x[j] == i or abs(x[j] - i) == abs(k - j) : return False return True def nqueen(k): for i in xrange(n): if safe(k,i): x[k] = i if k == n-1: print "SOLUTION", x return True # Found a solution, send this good news! else: if nqueen(k+1): # Good news! return True # Share the good news to parent! return False # We have searched every possible combinations, and I regret to tell you that I could not find any solution. nqueen(0)
至于时间复杂度,因为它是一个完整的搜索,它是n^n
。虽然由于修剪(使用safe(k,i)
,但在实践中它更快。
答案 1 :(得分:2)
在没有回溯的情况下解决N级皇后的问题还有另一个有趣的问题。是否有几乎完美的女王放置启发式,以便在回溯框架中,您几乎总能找到有效的配置?这相当于说启发式几乎总是告诉你将下一个女王放在棋盘上的正确方格。这种启发式方法比已知的封闭式解决方案更有趣,它为所有N值提供了有效的配置(显然N = 2和3除外)。
几乎完美的最小回溯启发式分析是一个已在文献中研究过的问题。最重要的参考文献是[Kalé 90]和 [San Segundo 2011]。将下一个女王置于回溯框架中的最佳启发式似乎如下:
此处关闭对角线指的是取消所有可用的正方形。