简体   繁体   中英

Python CPLEX API: Conditional iteration on binary variables

I'm working on a graph-theoretical problem. Suppose we want to find a Graph G=(V,E), such that there exists a partition X of V containing at most k equivalence classes. A variable p_S takes value 1 exactly when S is a member of partition X, and zero otherwise. So we have a constraint that the sum over all variables p_S is at most k, for all subsets S of V.

So what I want to do is to iterate over all p_S that have value 1 and define more constraints based on the elements I draw out of S. These constraints would preserve that members of an equivalence class share some mutual property.

Is it possible to access the p_S variables that way and how could I do it?

ALternatively I know I can do without iterating on my binary variables if I'm allowed to use binary variables as coefficients in my constraints. Is that possible?

Thanks in advance!

The CPLEX Python API is index based. To iterate over all binary variables with a solution value set to 1 we need to query the variables types and the solution values and filter accordingly. Here is a simple example:

import sys
import cplex


def main(modelfile):
    # Read in a model file.
    c = cplex.Cplex()
    c.read(modelfile)

    # Solve the model and print the solution and status.
    c.solve()
    print("Solution value:", c.solution.get_objective_value())
    print("Solution status: {0} ({1})".format(
        c.solution.get_status_string(),
        c.solution.get_status()))

    # Display all binary variables that have a solution value of 1.
    types = c.variables.get_types()
    nvars = c.variables.get_num()
    binvars = [idx for idx, typ
               in zip(range(nvars), c.variables.get_types())
               if typ == c.variables.type.binary]
    inttol = c.parameters.mip.tolerances.integrality.get()
    binvars_at_one = [idx for idx, val
                      in zip(binvars, c.solution.get_values(binvars))
                      if abs(val - 1.0) <= inttol]
    print("Binary variables with a solution value equal to one:")
    for varname in c.variables.get_names(binvars_at_one):
        print("  ", varname)


if __name__ == "__main__":
    if len(sys.argv) != 2:
        raise ValueError("usage: {0} <model>".format(sys.argv[0]))
    main(sys.argv[1])

For more, see the documentation for Cplex.variables and Cplex.solution .

linearization example:

from docplex.mp.model import Model

mdl = Model(name='binaryproduct')

x = mdl.binary_var(name='x')
y = mdl.binary_var(name='y')

z = mdl.binary_var(name='z')
# z==x*y
mdl.add_constraint(x+y<=1+z, 'ct1')
mdl.add_constraint(z<=x, 'ct2')
mdl.add_constraint(z<=y, 'ct3')
#end of z==x*y

mdl.solve()



for v in mdl.iter_binary_vars():
    print(v," = ",v.solution_value)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM