Answers to: XOR constraint in CPLEXhttp://www.or-exchange.com/questions/10111/xor-constraint-in-cplex<p>I'd like to add the following simple but conditional constraints in CPLEX using CPLEX's native indicator constraint method (c.indicator_constraints.add()).</p>
<pre><code>x1 + x2 = 50
OR
x1 + x2 = 0
</code></pre>
<p>I read the CPLEX documentation <a href="http://pic.dhe.ibm.com/infocenter/cosinfoc/v12r2/index.jsp?topic=%2Filog.odms.cplex.help%2FContent%2FOptimization%2FDocumentation%2FCPLEX%2F_pubskel%2FCPLEX682.html">here</a> but can't find an appropriate example with <strong>cplex.Or</strong>. For Python, I assume it must be something like:</p>
<pre><code>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)
</code></pre>
<p>What is the correct way to do this?</p>enTue, 26 Aug 2014 14:31:10 -0400Comment by Paul Rubin on johnclarke's questionhttp://www.or-exchange.com/questions/10111/xor-constraint-in-cplex#10123<p>For this particular case, I would say Gilead's approach is best practice.</p>Paul RubinTue, 26 Aug 2014 14:31:10 -0400http://www.or-exchange.com/questions/10111/xor-constraint-in-cplex#10123Comment by johnclarke on fbahr's answerhttp://www.or-exchange.com/questions/10111/xor-constraint-in-cplex#10121<p><a href="/users/25/fbahr">@fbahr</a> 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.</p>johnclarkeTue, 26 Aug 2014 11:26:34 -0400http://www.or-exchange.com/questions/10111/xor-constraint-in-cplex#10121Answer by fbahrhttp://www.or-exchange.com/questions/10111/xor-constraint-in-cplex/10120<p>If you read carefully, you'll notice that the documentation states:</p>
<blockquote>
<p>In <strong>Concert Technology</strong> applications, CPLEX automatically uses indicator constraints for you when it encounters a constraint [...] which can be linearized, including the following:<br>
- <code>IloAnd</code> or <code>Cplex.And</code><br>
- <code>IloOr</code> or <code>Cplex.Or</code><br>
- etc.</p>
</blockquote>
<p>Simply put, <code>Ilo*</code> and <code>Cplex.*</code> are <code>Concert Technology</code> "concepts" – but, as also noted by <del>IBM's</del> <a href="/users/182/philip-starhill">@Philip Starhill</a> <a href="https://www.or-exchange.org/questions/673/cplex-concert-with-c-vs-cplex-python-api?page=1&focusedAnswerId=677#677">here</a>, the Python API is more of a Callable Library-esque interface.</p>
<p>Hence, while C++, .NET, & Java APIs provide "sophisticated" means to model logical constraints (e.g., c.f. <a href="http://pic.dhe.ibm.com/infocenter/cosinfoc/v12r2/topic/ilog.odms.cplex.help/Content/Optimization/Documentation/CPLEX/_pubskel/CPLEX674.html">Logical constraints in the C++ API</a>), all that Python API users have is: indicator constraints of the form</p>
<p><code></code></p><div align="center"><code><ind_var> = {0,1} → <constraint></code></div><p></p>
<p>The indicator constraint "equivalent" of <a href="/users/153/gilead"><a href="/users/153/gilead">@Gilead</a></a>'s (Big-M) formulation could look sth. like:</p>
<pre><code>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)
</code></pre>fbahrTue, 26 Aug 2014 11:11:44 -0400http://www.or-exchange.com/questions/10111/xor-constraint-in-cplex/10120Comment by johnclarke on Gilead's answerhttp://www.or-exchange.com/questions/10111/xor-constraint-in-cplex#10119<p>Thanks Gilead -- that looks perfect. I didn't realize it was that simple.</p>johnclarkeTue, 26 Aug 2014 09:46:55 -0400http://www.or-exchange.com/questions/10111/xor-constraint-in-cplex#10119Answer by Gileadhttp://www.or-exchange.com/questions/10111/xor-constraint-in-cplex/10117<p>XOR is one of those constructs that is naturally modeled using binary variables. Your example can be easily rewritten as:</p>
<p>x1 + x2 = 50*b, where b in {0,1}</p>
<p>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.</p>GileadMon, 25 Aug 2014 18:22:41 -0400http://www.or-exchange.com/questions/10111/xor-constraint-in-cplex/10117Comment by johnclarke on johnclarke's questionhttp://www.or-exchange.com/questions/10111/xor-constraint-in-cplex#10116<p>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.</p>johnclarkeMon, 25 Aug 2014 15:24:02 -0400http://www.or-exchange.com/questions/10111/xor-constraint-in-cplex#10116Comment by Paul Rubin on johnclarke's questionhttp://www.or-exchange.com/questions/10111/xor-constraint-in-cplex#10114<p>Any particular reason to prefer indicator constraints over explicitly introducing a binary variable?</p>Paul RubinMon, 25 Aug 2014 15:20:52 -0400http://www.or-exchange.com/questions/10111/xor-constraint-in-cplex#10114