繁体   English   中英

z3:解决八皇后拼图

[英]z3: solve the Eight Queens puzzle

我正在使用Z3解决八皇后拼图。 我知道在这个问题上每个女王可以用一个整数表示。 但是,当我用两个整数代表一个女王时如下:

from z3 import *

X = [[Int("x_%s_%s" % (i+1, j+1)) for j in range(8)] for i in range(8) ]

cells_c = [Or(X[i][j] == 0, X[i][j] == 1) for i in range(8) for j in range(8) ]

rows_c = [Sum(X[i]) == 1 for i in range(8)]

cols_c = [Sum([X[i][j] for i in range(8)]) == 1 for j in range(8) ]

diagonals_c = [Implies(And(X[i][j] == 1, X[k][h] == 1), abs(k - i) != abs(j - h))
           for i in range(8) for j in range(8) 
           for k in range(8) for h in range(8)]

eight_queens_c = cells_c + rows_c + cols_c + diagonals_c

s = Solver()
s.add(eight_queens_c)
if s.check() == sat:
    m = s.model()
    r = [[m.evaluate(X[i][j]) for j in range(8)] for i in range(8)]
    print_matrix(r)
else:
    print "failed to solve"

它返回:

failed to solve

代码有什么问题?

谢谢!

由于以下代码,您的问题过度约束

diagonals_c = [Implies(And(X[i][j] == 1, X[k][h] == 1), abs(k - i) != abs(j - h))
           for i in range(8) for j in range(8) 
           for k in range(8) for h in range(8)]

每当对i, j等于k, h

 abs(k - i) = 0 = abs(j - h)

并且暗示结论是False

只有当它的前提是False时候才会满足对False结论的含义。 在你的问题的表述中,只有当对i, j等于k, h时, X[i][j] == 1X[k][h] == 1的情况绝不是这样的情况才有可能也就是说,如果对于任何i, jX[i][j] = 1的情况永远不会发生。 但是后一规则违反了基数约束,这些约束要求对于每个 / 存在至少一个单元X_i_j st X_i_j = 1 因此,该公式是不unsat


为了解决这个问题,最小的修复是简单地排除X[i][j]X[k][h]指向同一个单元格的情况:

diagonals_c = [Implies(And(X[i][j] == 1, X[k][h] == 1,
            i != k, j != h), abs(k - i) != abs(j - h))
            for i in range(8) for j in range(8) 
            for k in range(8) for h in range(8)]

在此更改后,找到解决方案。

例如

~$ python queens.py 
[[0, 0, 0, 0, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 0],
 [0, 0, 0, 1, 0, 0, 0, 0],
 [1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1],
 [0, 0, 0, 0, 0, 1, 0, 0],
 [0, 1, 0, 0, 0, 0, 0, 0]]

注意:在你的diagonals_c编码中,你为每个单元格引入了n*n约束,你的问题中有n*n单元格。 此外,由于索引空间中的对称性,每个约束生成“完全相同”两次。 但是,每个单元格与少于2*n其他单元格冲突(有些冲突少于n ),因此引入如此多的条款看起来有点过分,这些条款不会在搜索中提供任何有用的贡献,除了放慢速度 也许更可扩展的方法是使用基数约束(即Sum ),不仅用于 ,还用于对角线

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM