2016-03-31 13 views
2

我的代码工作,如果喜欢这样做使用addConstraint变量产生错误的答案,但没有使用变量工作正常

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) 

其结果为空列表。我想能够把它放在一个循环中,但我不知道发生了什么。我可能只是错过了一些非常基本的东西,但它只适用于我使用实际数字

回答

3

问题是,当您“添加变量”时,使用lambda函数查找值是,调用,而不是当它们是定义。在这种情况下,我猜他们直到problem.getSolutions()才会被调用,这意味着在每个函数调用中(而不是像初始代码中的0,12),x的值将是2

这是一个在python代码中的very common "gotcha",你可以通过设置一个默认参数来修复它(因为那些函数被创建时会被评估一次)。

lambda a, x=x: a[x] == a.count(0) 
相关问题