2016-03-31 13 views
2

mein Code wie so würde, wenn getan arbeiteteine Variable in addConstraint mit erzeugt eine falsche Antwort, aber nicht mit Variablen funktioniert

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) 

die Antwort [{'a': (2, 0, 2, 0)}, {'a': (1, 2, 1, 0)}]

sein, aber wenn ich Variablen verwenden, geht es drunter und drüber

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) 

was zu einer leeren Liste führt. Ich möchte in der Lage sein, dies in eine Schleife zu bringen, aber ich weiß nicht, was los ist. Ich vermisse nur etwas sehr einfach, aber es funktioniert nur, wenn ich reelle Zahlen verwenden

Antwort

3

Das Problem ist, dass, wenn Sie "Variablen hinzufügen", die Werte mit den Lambda-Funktionen namens gesucht werden, nicht, wenn sie sind definiert. In diesem Fall schätze ich, dass sie nicht bis problem.getSolutions() angerufen werden, was bedeutet, dass der Wert x2 in jedem Ihrer Funktionsaufrufe ist (anstelle von 0, 1 und 2 jeweils wie im ursprünglichen Code).

Dies ist ein very common "gotcha" in Python-Code, und Sie können es reparieren, indem Sie ein Standardargument festlegen (wie diese einmal ausgewertet werden, wenn die Funktion erstellt wird).

lambda a, x=x: a[x] == a.count(0)