在 addConstraint 中使用变量会产生错误的答案,但不使用变量可以正常工作
using a variable in addConstraint produces a wrong answer but not using variables works fine
如果这样做,我的代码可以正常工作
from constraint import *
import itertools
def main():
problem = Problem()
x = [0,1,2,3]
f = list(itertools.product(x,x,x,x))
problem.addVariable("a", f)
problem.addConstraint(lambda a: a[0] == a.count(0), "a",)
problem.addConstraint(lambda a: a[1] == a.count(1), "a",)
problem.addConstraint(lambda a: a[2] == a.count(2), "a",)
problem.addConstraint(lambda a: a[3] == a.count(3), "a",)
solutions = problem.getSolutions()
print "Found %d solutions!" % len(solutions)
答案是[{'a': (2, 0, 2, 0)}, {'a': (1, 2, 1, 0)}]
但如果我使用变量,它就会变得混乱
from constraint import *
import itertools
def main():
problem = Problem()
x = [0,1,2,3]
f = list(itertools.product(x,x,x,x))
problem.addVariable("a", f)
x = 0
problem.addConstraint(lambda a: a[x] == a.count(0), "a",)
x = 1
problem.addConstraint(lambda a: a[x] == a.count(1), "a",)
x = 2
problem.addConstraint(lambda a: a[x] == a.count(2), "a",)
problem.addConstraint(lambda a: a[3] == a.count(3), "a",)
solutions = problem.getSolutions()
print "Found %d solutions!" % len(solutions)
结果是一个空列表。我希望能够将其置于循环中,但我不知道发生了什么。我可能只是遗漏了一些非常基本的东西,但它只有在我使用实数时才有效
问题是,当您 "add variables" 时,使用 lambda 函数查找的值是 调用的 ,而不是在定义它们时调用的。在这种情况下,我猜他们直到 problem.getSolutions()
才会被调用,这意味着 x
的值在您的每个函数调用中都将是 2
(而不是 0
、1
和 2
分别与初始代码相同)。
这是 python 代码中的 very common "gotcha",您可以通过设置默认参数来修复它(因为在创建函数时对这些参数进行一次评估)。
lambda a, x=x: a[x] == a.count(0)
如果这样做,我的代码可以正常工作
from constraint import *
import itertools
def main():
problem = Problem()
x = [0,1,2,3]
f = list(itertools.product(x,x,x,x))
problem.addVariable("a", f)
problem.addConstraint(lambda a: a[0] == a.count(0), "a",)
problem.addConstraint(lambda a: a[1] == a.count(1), "a",)
problem.addConstraint(lambda a: a[2] == a.count(2), "a",)
problem.addConstraint(lambda a: a[3] == a.count(3), "a",)
solutions = problem.getSolutions()
print "Found %d solutions!" % len(solutions)
答案是[{'a': (2, 0, 2, 0)}, {'a': (1, 2, 1, 0)}]
但如果我使用变量,它就会变得混乱
from constraint import *
import itertools
def main():
problem = Problem()
x = [0,1,2,3]
f = list(itertools.product(x,x,x,x))
problem.addVariable("a", f)
x = 0
problem.addConstraint(lambda a: a[x] == a.count(0), "a",)
x = 1
problem.addConstraint(lambda a: a[x] == a.count(1), "a",)
x = 2
problem.addConstraint(lambda a: a[x] == a.count(2), "a",)
problem.addConstraint(lambda a: a[3] == a.count(3), "a",)
solutions = problem.getSolutions()
print "Found %d solutions!" % len(solutions)
结果是一个空列表。我希望能够将其置于循环中,但我不知道发生了什么。我可能只是遗漏了一些非常基本的东西,但它只有在我使用实数时才有效
问题是,当您 "add variables" 时,使用 lambda 函数查找的值是 调用的 ,而不是在定义它们时调用的。在这种情况下,我猜他们直到 problem.getSolutions()
才会被调用,这意味着 x
的值在您的每个函数调用中都将是 2
(而不是 0
、1
和 2
分别与初始代码相同)。
这是 python 代码中的 very common "gotcha",您可以通过设置默认参数来修复它(因为在创建函数时对这些参数进行一次评估)。
lambda a, x=x: a[x] == a.count(0)