I'd like to add the following simple but conditional constraints in CPLEX using CPLEX's native indicator constraint method (c.indicator_constraints.add()).

x1 + x2 = 50
OR
x1 + x2 = 0

I read the CPLEX documentation here but can't find an appropriate example with cplex.Or. For Python, I assume it must be something like:

row = [["x1","x2'], [1,1]]
rhs = [50 cplex.Or 0]
prob.indicator_constraints.add(lin_expr = row, senses = my_sense, rhs = rhs, names = my_rownames)

What is the correct way to do this?

asked 25 Aug '14, 14:00

johnclarke's gravatar image

johnclarke
2417
accept rate: 0%

edited 25 Aug '14, 14:08

Any particular reason to prefer indicator constraints over explicitly introducing a binary variable?

(25 Aug '14, 15:20) Paul Rubin ♦♦

Paul -- No reason -- it just seemed like the best practice was to use CPLEX's internal mechanism. Also, it would more convenient to have CPLEX take care of these extra binary variables.

(25 Aug '14, 15:24) johnclarke

For this particular case, I would say Gilead's approach is best practice.

(26 Aug '14, 14:31) Paul Rubin ♦♦

If you read carefully, you'll notice that the documentation states:

In Concert Technology applications, CPLEX automatically uses indicator constraints for you when it encounters a constraint [...] which can be linearized, including the following:
- IloAnd or Cplex.And
- IloOr or Cplex.Or
- etc.

Simply put, Ilo* and Cplex.* are Concert Technology "concepts" – but, as also noted by IBM's @Philip Starhill here, the Python API is more of a Callable Library-esque interface.

Hence, while C++, .NET, & Java APIs provide "sophisticated" means to model logical constraints (e.g., c.f. Logical constraints in the C++ API), all that Python API users have is: indicator constraints of the form

<ind_var> = {0,1} → <constraint>

The indicator constraint "equivalent" of @Gilead's (Big-M) formulation could look sth. like:

var_names = ["b", "x1", "x2"]
obj_vals  = [0.0, 1.0, 1.0]
lbounds   = [0.0 for v in var_names]
ubounds   = [50.0 if v.startswith("x") else 1.0 for v in var_names]

prob.variables.add(obj=obj_vals, \
                   lb=lbounds, \
                   ub=ubounds, \
                   types=[solver.variables.type.integer for v in var_names], \
                   names=var_names)

ic_dict = {}
ic_dict["lin_expr"]     = SparsePair(ind=["x1", "x2"], val=[1.0, 1.0])
ic_dict["rhs"]          = 0.0
ic_dict["sense"]        = "E"
ic_dict["indvar"]       = "b"
ic_dict["complemented"] = 1
prob.indicator_constraints.add(**ic_dict)

ic_dict["rhs"]          = 50.0
ic_dict["complemented"] = 0
prob.indicator_constraints.add(**ic_dict)
link

answered 26 Aug '14, 11:11

fbahr's gravatar image

fbahr ♦
4.6k716
accept rate: 13%

edited 27 Aug '14, 07:44

@fbahr Thank you! I had to look up "Concert Technologies" to understand the nuances there. Also, the example you give is very helpful for me to understand an alternative way of formulating the constraint. I had trouble finding examples such as this.

(26 Aug '14, 11:26) johnclarke

XOR is one of those constructs that is naturally modeled using binary variables. Your example can be easily rewritten as:

x1 + x2 = 50*b, where b in {0,1}

Indicator constraints are useful in some situations, but generally they get reformulated as Big-M constraints with some good guesses for M. If you are modeling something from scratch and have a good idea of what your bounds are, you can generally do better than CPLEX's heuristics.

link

answered 25 Aug '14, 18:22

Gilead's gravatar image

Gilead ♦
2.3k513
accept rate: 15%

edited 25 Aug '14, 18:23

Thanks Gilead -- that looks perfect. I didn't realize it was that simple.

(26 Aug '14, 09:46) johnclarke
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "Title")
  • image?![alt text](/path/img.jpg "Title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×191
×21
×2

Asked: 25 Aug '14, 14:00

Seen: 2,910 times

Last updated: 27 Aug '14, 07:44

OR-Exchange! Your site for questions, answers, and announcements about operations research.