使用python-constraint求解n皇后问题返回None,求问题排查
n皇后问题python-constraint实现返回None的问题解决
你的代码无法得到解的核心问题在于循环中lambda表达式的变量捕获特性:Python的lambda不会在定义时绑定循环变量i和j的当前值,而是在约束实际被检查时才去读取这两个变量的最终值。当循环结束后,i和j都停留在最后一轮循环的数值,导致所有约束都错误地使用了这组最终值,相当于没有正确添加所有皇后之间的互斥约束,自然找不到合法解。
修正方案1:用lambda默认参数绑定当前循环值
修改约束添加的代码,通过默认参数将循环时的i、j值固定下来:
from constraint import * n = 8 problem = Problem() problem.addVariables(range(n), range(n)) for i in range(n): for j in range(i): # 通过默认参数i=i、j=j绑定当前循环的变量值 problem.addConstraint(lambda a, b, i=i, j=j: a != b, (i, j)) problem.addConstraint(lambda a, b, i=i, j=j: abs(a - b) != abs(i - j), (i, j)) print(problem.getSolution())
修正方案2:用functools.partial固定约束参数
如果觉得lambda默认参数不够直观,可以用functools.partial来预先绑定约束函数的参数:
from constraint import * from functools import partial n = 8 problem = Problem() problem.addVariables(range(n), range(n)) # 定义独立的约束函数 def no_same_row(a, b): return a != b def no_same_diagonal(a, b, i, j): return abs(a - b) != abs(i - j) for i in range(n): for j in range(i): problem.addConstraint(no_same_row, (i, j)) # 绑定当前循环的i、j到对角线约束函数 diag_constraint = partial(no_same_diagonal, i=i, j=j) problem.addConstraint(diag_constraint, (i, j)) print(problem.getSolution())
运行修正后的代码,getSolution()会返回一个合法的n皇后解(例如n=8时返回类似{0: 0, 1: 4, 2: 7, 3: 5, 4: 2, 5: 6, 6: 1, 7: 3}的字典,键表示列索引,值表示皇后所在的行索引)。
内容的提问来源于stack exchange,提问作者none none
相关产品推荐
相关产品推荐

