问题描述
旨在解决下面的简单线性优化,使用barrier内点法.
要求:在迭代过程中,把第一次目标大于1的迭代轮数和具体目标值保存并显示出来.
代码
# include "gurobi_c++.h"
# include <fstream>
# include <cmath>
using namespace std;
class mycallback : public GRBCallback
{
public:
int numvars;
double tempResult = 0;
int tempIter = 0;
bool onceFlag = true;
GRBVar* vars;
mycallback(int xnumvars, GRBVar* xvars) {
numvars = xnumvars;
vars = xvars;
}
protected:
void callback() {
try {
if (where == GRB_CB_POLLING) {
// Ignore polling callback
}
else if (where == GRB_CB_PRESOLVE) {
// Presolve callback
// Ignore
}
else if (where == GRB_CB_BARRIER) {
// Barrier callback
int itcnt = getIntInfo(GRB_CB_BARRIER_ITRCNT);
// Current primal objection in the iteration
double primobj = getDoubleInfo(GRB_CB_BARRIER_PRIMOBJ);
// If the primal is the first one to above 1
if (primobj > 1 && onceFlag) {
tempIter = itcnt;
tempResult = primobj;
onceFlag = false;
}
}
}
catch (GRBException e) {
cout << " Error number : " << e.getErrorCode() << endl;
cout << e.getMessage() << endl;
}
catch (...) {
cout << " Error during callback " << endl;
}
}
};
int main(int argc,
char* argv[])
{
GRBEnv env = GRBEnv();
env.set(GRB_IntParam_Method, 2); //Set barrier method
env.set(GRB_IntParam_Crossover, 0); //disable crossover
GRBModel model = GRBModel(env);
// Create variables
GRBVar x = model.addVar(0.0, 1.0, 0.0, GRB_CONTINUOUS, "x");
GRBVar y = model.addVar(0.0, 1.0, 0.0, GRB_CONTINUOUS, "y");
GRBVar z = model.addVar(0.0, 1.0, 0.0, GRB_CONTINUOUS, "z");
// Set objective: maximize x + y + 2 z
model.setObjective(x + y + 2 * z, GRB_MAXIMIZE);
// Add constraint: x + 2 y + 3 z <= 4
model.addConstr(x + 2 * y + 3 * z <= 4, "c0");
// Add constraint: x + y >= 1
model.addConstr(x + y >= 1, "c1");
model.update();
int numvars = model.get(GRB_IntAttr_NumVars);
GRBVar* vars = model.getVars();
mycallback cb = mycallback(numvars, vars);
model.setCallback(&cb);
try{
// Optimize model
model.optimize();
cout << "First iteration count whose obj > 1: " << cb.tempIter << "\nTemp obj value: " << cb.tempResult << endl;
cout << x.get(GRB_StringAttr_VarName) << " "
<< x.get(GRB_DoubleAttr_X) << endl;
cout << y.get(GRB_StringAttr_VarName) << " "
<< y.get(GRB_DoubleAttr_X) << endl;
cout << z.get(GRB_StringAttr_VarName) << " "
<< z.get(GRB_DoubleAttr_X) << endl;
cout << "Obj: " << model.get(GRB_DoubleAttr_ObjVal) << endl;
}
catch (GRBException e) {
cout << "Error code = " << e.getErrorCode() << endl;
cout << e.getMessage() << endl;
}
catch (...) {
cout << "Exception during optimization" << endl;
}
return 0;
}
结果如下:
总结
- 自定义myCallback函数,继承于GRBCallback
- 在model.optimize()过程中,where的值会自动生成和改变。比如polling,presolve, 根据你设置的解法跳入到相应的if语句中。where的值不能人为强制修改,不然会报错.