Status Code 1: Model Loaded

174 views
Skip to first unread message

Connor Riley

unread,
Jun 26, 2018, 4:47:48 PM6/26/18
to Gurobi Optimization
The attached LP file results in a Status Code 1 after optimizing with Gurobi. I believe this is because it is pre-solved without any simplex iterations. While it is a simple model with an obvious solution, I am using it to initialize a column generation algorithm, and therefore need the information provided by the dual. I can certainly compute the dual using the strong duality theorem, but I'd rather avoid the extra programming if I can make Gurobi do the work for me.

My questions are:

1. Why is the status code 1 returned, when in fact the console output suggests the problem has been solved?
(my suspicion is that it is because there are no simplex iterations performed and therefore there will not be any dual information)

2. Is there a way I can change my model or a gurobi parameter such that I get a status code 2 (for optimal)?

The console output:

Optimize a model with 73 rows, 73 columns and 73 nonzeros
Coefficient statistics:
  Matrix range     [1e+00, 1e+00]
  Objective range  [2e+03, 2e+03]
  Bounds range     [1e+00, 1e+00]
  RHS range        [1e+00, 1e+00]
Presolve removed 73 rows and 73 columns
Presolve time: 0.00s
Presolve: All rows and columns removed
Iteration    Objective       Primal Inf.    Dual Inf.      Time
       0    3.8400000e+03   0.000000e+00   0.000000e+00      0s

Solved in 0 iterations and 0.00 seconds
Optimal objective  3.840000000e+03

The method which calls the optimization:

 bool ILP::optimizeRelaxation() {
   
try {
      _model
->write("test.lp");
     
GRBModel relaxation = _model->relax();
      relaxation
.write("relax.lp");
      relaxation
.optimize();
     
int model_status = _model->get(GRB_IntAttr_Status);

     
// If the model timed out, exit.
     
if (model_status == GRB_OPTIMAL) {
       
double objval = _model->get(GRB_DoubleAttr_ObjVal);
       
assert(objval >= 0);
        std
::cout << "Optimal objective: " << objval << std::endl;
       
return true;
     
} else if (model_status == GRB_INF_OR_UNBD) {
        std
::cout << "Model is infeasible or unbounded" << std::endl;
     
} else if (model_status == GRB_INFEASIBLE) {
        std
::cout << "Model is infeasible" << std::endl;
     
} else if (model_status == GRB_UNBOUNDED) {
        std
::cout << "Model is unbounded" << std::endl;
     
} else {
        std
::cout << "Optimization was stopped with status = "
                 
<< model_status << std::endl;
     
}
   
} catch(GRBException e) {
      std
::cout << "Error code = " << e.getErrorCode() << std::endl;
      std
::cout << e.getMessage() <<std::endl;
   
} catch(...) {
      std
::cout << "Exception during optimization" << std::endl;
   
}
   
return false;
 
}


relax.lp

Tobias Achterberg

unread,
Jun 26, 2018, 5:28:13 PM6/26/18
to gur...@googlegroups.com
You are solving "relaxation", but then you are querying the status of "_model", which has
not yet been solved.

Note that _model->relax() produces a new, independent model, which happens to be a
relaxation of "_model". But if you call relaxation.optimize(), this does not affect at all
your "_model". Hence, the status of "_model" will still be LOADED (1).

Best regards,

Tobias

Connor Riley

unread,
Jun 27, 2018, 12:48:50 AM6/27/18
to Gurobi Optimization
Hi Tobias,

Thanks for your reply. That seemed to fix my issue. Is there a way to associate constraints of the original MIP to constraints of the LP so that I can retrieve the dual variable values?

Right now, I have a vector of constraints from the original model, so when I try to access the dual variable value, there is none.

pi[i] = constraints_from_mip_model[i].get(GRB_DoubleAttr_Pi);
^^ Throws an error.

What I really want is:
pi[i] = constraints_from_relaxation[i].get(GRB_DoubleAttr_Pi);

The issue here is I'm unsure how to obtain the constraint from the relaxation and ensure that it corresponds to the correct constraint in the original model.

Tobias Achterberg

unread,
Jun 27, 2018, 12:59:53 AM6/27/18
to gur...@googlegroups.com
The constraints will be in the same order in the two models, so if you query your
constraints with

mcons = _model.getConstrs()
rcons = relaxation.getConstrs()

then you have rcons[i] being the copy of mcons[i] for i = 0,...,len(mcons)-1. But this is
not really a perfect solution.

Maybe it is easier if you just relax your problem manually and "in-place". So, modify your
original "_model" by setting the "VType" attribute of all variables to CONTINUOUS. Then,
do whatever you need to do with this relaxation (including solving and querying the
duals), and finally change the "VType" attributes back to their original setting to get
back your MIP model.


Regards,

Tobias

Connor Riley

unread,
Jun 27, 2018, 4:30:20 PM6/27/18
to Gurobi Optimization
Thanks for the suggestions Tobias! I appreciate your help!
Reply all
Reply to author
Forward
0 new messages