0
$\begingroup$

from docplex.mp.model import Model

from cplex.callbacks import LazyConstraintCallback

from docplex.mp.callbacks.cb_mixin import *


p_id is the list of lists of customers,

n is the set of vehicles,

dth is the fixed parameter, and

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))}

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

Adding constraints using Callback (lazyconstrainrts)

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

\sum(x_ind[i,d+dth] for i in n_id if x_^*ind[i,d+dth]==0)+ \sum(1-x_ind[i,d+dth] for i in n_id if x_^*ind[i,d+dth]==1) >= 1 \forall d.

For that, I have written callback code as

class NonLinearConstraintCallback(ConstraintCallbackMixin, LazyConstraintCallback):

        def __init__(self, env, trial_mod, x_ind, dic_nurse_avail_remaining_days):
            LazyConstraintCallback.__init__(self, env)
            ConstraintCallbackMixin.__init__(self)
            self.trial_mod = trial_mod
            self.x_ind = x_ind
            self.dic_nurse_avail_remaining_days = dic_nurse_avail_remaining_days

        def __call__(self):
          sol = self.make_solution_from_vars(self.x_ind.values())
          for d in range(1,len(p_id)):
                prob_product = 1.0
                    for i in n_id:
                       ind_vars_value = sol.get_value(x_ind[i,d+dth])
                       prob_product *= (1 - (1 self.dic_nurse_avail_remaining_days['nurse_{}_day_{}_planned_{}'.format(i,day-1+1,d+dth)])*ind_vars_value)                    
                    if prob_product < threshold:
                       lhs_terms = []
                       for i in n_id:
                          ind_vars_value2 = sol.get_value(x_ind[i,d+dth])
                          if round(ind_vars_value2, 2) <= 0.2:
                             lhs_terms.append(self.x_ind[i,d+dth])
                          elif round(ind_vars_value2, 2) >= 0.9:
                             lhs_terms.append(1 - self.x_ind[i,d+dth])
                       lhs = sum(lhs_terms)
                       self.trial_mod.add_constraint(lhs >= 1)

          
cb = trial_mod.register_callback(NonLinearConstraintCallback)

cb.x_ind = x_ind

cb.dic_nurse_avail_remaining_days = dic_nurse_avail_remaining_days

trial_mod.lazy_callback = cb

When I solve using command trial_mod.solve(log_output=True) I can see that callback is adding violated cut correctly. But when it comes to the solution printing command i.e. trial_mod.print_solution() it gives the error as

docplex.mp.utils.DOcplexException: Model did not solve successfully.

When I tried to print the status of the solution using command print(trial_mod.solve_details), it tells the status as

status = Unknown status value.

I am not able to visualize the reasons for such errors.

This post is in continuation of Getting error in callback (lazy constraints) for docplex with Python to solve MILP.

$\endgroup$

0

Your Answer

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