callback_c++.cpp
/* Copyright 2009, Gurobi Optimization, Inc. */
/* This example reads an LP or a MIP from a file, sets a callback
to monitor the optimization progress and to output some progress
information to the screen and to a log file. If it is a MIP and 10%
gap is reached, then it aborts */
#include "gurobi_c++.h"
#include <cmath>
using namespace std;
class mycallback: public GRBCallback
{
public:
GRBVar* vars;
int numvars;
int lastmsg;
mycallback(GRBVar* xvars, int xnumvars) {
vars = xvars;
numvars = xnumvars;
lastmsg = -100;
}
protected:
void callback () {
try {
if (where == GRB_CB_PRESOLVE) {
int cdels = getIntInfo(GRB_CB_PRE_COLDEL);
int rdels = getIntInfo(GRB_CB_PRE_ROWDEL);
cout << cdels << " columns and " << rdels
<< " rows are removed" << endl;
} else if (where == GRB_CB_SIMPLEX) {
int itcnt = (int) getDoubleInfo(GRB_CB_SPX_ITRCNT);
if (itcnt%100 == 0) {
double obj = getDoubleInfo(GRB_CB_SPX_OBJVAL);
double pinf = getDoubleInfo(GRB_CB_SPX_PRIMINF);
double dinf = getDoubleInfo(GRB_CB_SPX_DUALINF);
int ispert = getIntInfo(GRB_CB_SPX_ISPERT);
char ch;
if (ispert == 0) ch = ' ';
else if (ispert == 1) ch = 'S';
else ch = 'P';
cout << itcnt << " " << obj << ch << " " << pinf
<< " " << dinf << endl;
}
} else if (where == GRB_CB_MIP) {
int nodecnt = (int) getDoubleInfo(GRB_CB_MIP_NODCNT);
if (nodecnt - lastmsg >= 100) {
lastmsg = nodecnt;
double objbst = getDoubleInfo(GRB_CB_MIP_OBJBST);
double objbnd = getDoubleInfo(GRB_CB_MIP_OBJBND);
if (fabs(objbst - objbnd) < 0.1 * (1.0 + fabs(objbst)))
abort();
int actnodes = (int) getDoubleInfo(GRB_CB_MIP_NODLFT);
int itcnt = (int) getDoubleInfo(GRB_CB_MIP_ITRCNT);
int solcnt = getIntInfo(GRB_CB_MIP_SOLCNT);
int cutcnt = getIntInfo(GRB_CB_MIP_CUTCNT);
cout << nodecnt << " " << actnodes << " " << itcnt << " "
<< objbst << " " << objbnd << " " << solcnt << " "
<< cutcnt << endl;
}
} else if (where == GRB_CB_MIPSOL) {
double obj = getDoubleInfo(GRB_CB_MIPSOL_OBJ);
int nodecnt = (int) getDoubleInfo(GRB_CB_MIPSOL_NODCNT);
double* x = getSolution(vars, numvars);
cout << "**** New solution at node " << nodecnt << ", obj "
<< obj << ", x[0] = " << x[0] << "****" << endl;
delete[] x;
}
} 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[])
{
if (argc < 2) {
cout << "Usage: callback_c++ filename" << endl;
return 1;
}
GRBEnv *env = 0;
GRBVar *vars = 0;
try {
env = new GRBEnv();
GRBModel model = GRBModel(*env, argv[1]);
int numvars = model.get(GRB_IntAttr_NumVars);
vars = model.getVars();
mycallback cb = mycallback(vars, numvars);
model.setCallback(&cb);
model.optimize();
for (int j = 0; j < numvars; j++) {
GRBVar v = vars[j];
cout << v.get(GRB_StringAttr_VarName) << " "
<< v.get(GRB_DoubleAttr_X) << endl;
}
} catch (GRBException e) {
cout << "Error number: " << e.getErrorCode() << endl;
cout << e.getMessage() << endl;
} catch (...) {
cout << "Error during optimization" << endl;
}
delete[] vars;
delete env;
return 0;
}
