First thing first, if you are solving mixed-integer programs (MIP), including mixed-integer linear programs (MILP), you are out of luck, because Gurobi does not support getting dual values for mixed-integer problems. You could only get dual values if your problem is a continuous problem (Reference: https://support.gurobi.com/hc/en-us/articles/360034305272-Why-can-t-I-get-the-Pi-values-for-a-MIP-problem-).
If your problem is a continuous problem, congrats! Let’s see how you can get the dual values.
-
Define the constraints with a name. What does this mean?
- If you didn’t want to get the dual, you would not need to name the constraint and could just use
Model.addConstr(Your_Constraint_Here). - But if you wanted to get the dual, you need to define the constraint as follows:
GRBConstr MyConst = Model.addConstr(Your_Constraint_Here). In this code,GRBConstris the type of the variable (Gurobi Constraint) andMyConstis the name of the variable (the name of the constraint).
- If you didn’t want to get the dual, you would not need to name the constraint and could just use
-
Get the value of the dual using
MyConst.get(GRB_DoubleAttr_Pi). In this case,MyConstis the name of the constraint. -
At last, output the dual value. You have a few options:
- You could print out the dual value directly using
std::cout << "Dual = " << MyConst.get(GRB_DoubleAttr_Pi) << endl;
- Or save it into a txt file:
ofstream results;
results.open ("results.txt");
results << "Dual: " << MyConst.get(GRB_DoubleAttr_Pi) << endl;
results.close();
- You could also save the dual value into a variable for later use:
double DualValue = MyConst.get(GRB_DoubleAttr_Pi);
The following is a complete example code for a linear program, which prints the value of the dual at the end.
#include "gurobi_c++.h"
#include<iostream>
using namespace std;
int main()
{
try {
GRBEnv env = GRBEnv(); // Set up the Gurobi environment
GRBModel SimpleExample = GRBModel(env); // Define the model as "SimpleExample" - but you could name the model whatever you like
GRBVar x = SimpleExample.addVar(0, 50, 20, GRB_CONTINUOUS, "x"); // Define variable x in the model and its range (0-50)
GRBVar y = SimpleExample.addVar(0, 100, 30, GRB_CONTINUOUS, "y"); // Define variable y in the model and its range (0-100)
SimpleExample.set(GRB_IntAttr_ModelSense, GRB_MINIMIZE); // Define the objective function as to minimize 20x+30y
GRBConstr MyConst = SimpleExample.addConstr(x + y == 70); // Define the third constraint (x+y=70)
SimpleExample.optimize(); // Solve the model
std::cout << "Objective value: " << SimpleExample.get(GRB_DoubleAttr_ObjVal) << endl; // Output the objective value
std::cout << "x = " << x.get(GRB_DoubleAttr_X) << endl; // Output the value of x
std::cout << "y = " << y.get(GRB_DoubleAttr_X) << endl; // Output the value of y
std::cout << "Dual = " << MyConst.get(GRB_DoubleAttr_Pi) << endl;
} catch(GRBException e) {
cout << "Error code = " << e.getErrorCode() << endl;
cout << e.getMessage() << endl;
} catch (...) {
cout << "Error during optimization" << endl;
}
return 0;
}