The "toehold problem" is named after a tech support response. The nature of the problem is that in order to take advantage of the algebraic constraint modeling provided by docplex
, then the Model.add_constraint
function needs a "toehold" with which to build a LinearConstraint
.
Or, at least that's what I thought I'd find. Turns out the docplex
guys outfoxed me, and anticipated this problem. But lets go through the notebook anyway.
(Note that LinearConstraint
is not part of the public package. You shouldn't try to build it directly, but instead let docplex
create it for you as part of writing out algebraic constraints).
So what do I mean, specifically? To begin, let's make a function that captures exceptions, since I'm going to be making mistakes and deliberately throwing exceptions.
In [1]:
def exception_thrown(f):
try:
f()
except Exception as e:
return str(e)
Let's make a constraint without creating any problems. (You'll need to understand lambda
to understand this code).
In [2]:
from docplex.mp.model import Model
m = Model()
v = m.continuous_var(name = "goodstuff")
exception_thrown(lambda : m.add_constraint(v <= 100, ctname = "c1"))
In [4]:
m.get_constraint_by_index(0)
Out[4]:
Ok, now let's screw up and make a bad constraint. This might happen to you, so pay attention please.
In [5]:
exception_thrown(lambda : m.add_constraint(0 <= 300, ctname = "not_going_to_be_added_to_model"))
Hey wait! It didn't throw an exception. What happened?
In [6]:
[m.get_constraint_by_index(_) for _ in range(2)]
Out[6]:
Hey, this is cool! It looks like it's really in the model! Let's double check.
In [7]:
m.get_constraint_by_name("not_going_to_be_added_to_model")
Out[7]:
Well, never mind then. The toehold problem doesn't exist if you're using docplex
. Good job, docplex
developers!