1
$\begingroup$

I am trying to use lazy constraints to solve my MILP problem. The details are given as follows.

from docplex.mp.model import Model
from cplex.callbacks import LazyConstraintCallback
from docplex.mp.callbacks.cb_mixin import *

where:

  • p_id: is the list of lists of customers,
  • n: is the set of vehicles,
  • dth: is the fixed parameter
  • q_prob: is the dictionary representing the probability of availability of vehicles (day-wise)

Creating Model

trial_mod=Model('My Trial Model',log_output=True)

Defining decision variables

x_ind={(i,d+dth):trial_mod.binary_var(name='x_{0}_{1}'.format(i,d+dth)) for i in n_id for d in range(len(p_id))}

Other decision variables are also defined but they are not relevant here.

Adding constraints using Callback (lazy constraints)

At integer node (means whenever we obtain the candidate solution), I want to check that ($ \prod_{i\in n} (1-q_i^dx_i^d) \geq threshold, \quad \forall d$). If not then I want to add a cut as:

self.trial_mod.sum(self.x_ind[i,d+dth] for i in n_id if self.get_values(self.x_ind[i,d+dth])==0)+self.trial_mod.sum(1 - self.x_ind[i,d+dth] for i in n_id if self.get_values(self.x_ind[i,d+dth])==1)

For that, I have written the callback code as

class NonLinearConstraintCallback(ConstraintCallbackMixin, LazyConstraintCallback):

    def __init__(self, env)

        LazyConstraintCallback.__init__(self, env)

        ConstraintCallbackMixin.__init__(self)

   def __call__(self):

        for d in range(1,len(p_id)):
            prob_product = 1.0
            for i in n_id:
                ind_vars_value = self.get_values(self.x_ind[i,d+dth])
                prob_product *= (1 -self.q_prob['nurse_{}_day_{}'.format(i,d+dth)])*ind_vars_value)                   
                if product < threshold:
                    lhs = self.trial_mod.sum(self.x_ind[i,d+dth] for i in n_id if self.get_values(self.x_ind[i,d+dth])==0)+self.trial_mod.sum(1 - self.x_ind[i,d+dth] for i in n_id if self.get_values(self.x_ind[i,d+dth])==1)
                    self.add(lhs >= 1)
    
    cb = trial_mod.register_callback(NonLinearConstraintCallback)
    cb.x_ind = x_ind
    cb. q_prob   = q_prob
    trial_mod.lazy_callback = cb
    trial_mod.solve(log_output=True)

when I solve the model, It gives errors as:

CPLEX Error  1006: Error during callback.
Error: Internal error in CPLEX solve: TypeError: expecting name or index.

I request the community please help me to fix this callback issue.

$\endgroup$
8
  • $\begingroup$ For a better diagnosis, try to get the proper exception and share it with us: stackoverflow.com/a/59245194/10836939. $\endgroup$ Commented May 27 at 10:59
  • 1
    $\begingroup$ Thanks, Matheus Diógenes Andrade for your prompt response. I did what you suggested (modify the code into a try/except block). But still gives the same error information: CPLEX Error 1006: Error during callback. Error: Internal error in CPLEX solve: TypeError: expecting name or index. $\endgroup$ Commented May 27 at 11:45
  • 2
    $\begingroup$ self.get_values(self.x_ind[i,d+dth]) doesn't look right to me. Name or index would be okay (as error indicates; see also SO Link). In your case it's of type docplex.mp.***.Var i guess (return-type during your dict-comprehension). General remark: exploit the fact, that your are using an interpreted language and do some quick experiments (even semantically invalid ones lile the following:) like e.g. putting a 0 as index there and see what changes. $\endgroup$
    – sascha
    Commented May 27 at 12:03
  • $\begingroup$ Cross-posted at community.ibm.com/community/user/ai-datascience/discussion/…. $\endgroup$
    – prubin
    Commented May 27 at 15:11
  • $\begingroup$ Thanks, sascha for your feedback. Since, coding syntax is different for cplex and docplex. Using incorrect syntax might be the source of error. I incorporate your suggestions and get back here if I face any issues. $\endgroup$ Commented May 27 at 18:16

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.