K-out-of-N constraint in Z3Py

后端 未结 1 405
情话喂你
情话喂你 2020-12-06 10:25

I am using the Python bindings for the Z3 theorem prover (Z3Py). I have N boolean variables, x1,..,xN. I want to express the constraint that exactly K out of N of them sho

相关标签:
1条回答
  • 2020-12-06 10:36

    Yes, Z3Py has built-in support for this. There is an undocumented API for this, that isn't mentioned in the Z3Py docs: use PbEq. In particular, the expression

    PbEq(((x1,1),(x2,1),..,(xN,1)),K)
    

    will be true if exactly K out of the N boolean variables are set to true. There are some reports that this encoding will be faster than naive ways of manually expressing the constraint.

    To express a 1-out-of-N constraint, just set K=1 and use PbEq. To express an at-most-K-out-of-N constraint, use PbLe. To express an at-least-K-out-of-N constraint, use PbGe.

    You can express this in Python like this:

    import z3
    
    s = z3.Solver()
    bvars = [z3.Bool("Var {0}".format(x)) for x in range(10)]
    #Exactly 3 of the variables should be true
    s.add( z3.PbEq([(x,1) for x in bvars], 3) )
    s.check()
    m = s.model()
    
    s = z3.Solver()
    bvars = [z3.Bool("Var {0}".format(x)) for x in range(10)]
    #<=3 of the variables should be true
    s.add( z3.PbLe([(x,1) for x in bvars], 3) )
    s.check()
    m = s.model()
    
    s = z3.Solver()
    bvars = [z3.Bool("Var {0}".format(x)) for x in range(10)]
    #>=3 of the variables should be true
    s.add( z3.PbGe([(x,1) for x in bvars], 3) )
    s.check()
    m = s.model()
    
    0 讨论(0)
提交回复
热议问题