/******************************************************** Xpress-BCL C++ Example Problems =============================== file xbexpl3.cxx ```````````````` User error handling and output redirection. (c) 2008 Fair Isaac Corporation author: Y.Colombani, 2006, rev. Mar. 2011 ********************************************************/ #include #include #include #include "xprb_cpp.h" using namespace std; using namespace ::dashoptimization; /* This small, infeasible example shows how the error handling and all printed messages can be intercepted by the user's program. This is done by defining the corresponding BCL callback functions and changing the error handling flag. */ /***********************************************************************/ class bcl_exception { public: string msg; int code; bcl_exception(int c,const char *m) { code=c; msg=string(m); cout << "EXCP:" << msg << "\n"; } }; /***********************************************************************/ /**** User error handling function ****/ void XPRB_CC usererror(xbprob* prob, void *vp, int num, int type, const char *t) { throw bcl_exception(num, t); } /**** User printing function ****/ void XPRB_CC userprint(xbprob* prob, void *vp, const char *msg) { static int rtsbefore=1; /* Print 'BCL output' whenever a new output line starts, otherwise continue to print the current line. */ if(rtsbefore) cout << "BCL output: " << msg; else cout << msg; rtsbefore=(msg[strlen(msg)-1]=='\n'); } /***********************************************************************/ void modexpl3(XPRBprob &p) { XPRBvar x[3]; XPRBlinExp le; int i; for(i=0;i<2;i++) x[i]=p.newVar(XPRBnewname("x_%d",i), XPRB_UI, 0, 100); /* Create the constraints: C1: 2x0 + 3x1 >= 41 C2: x0 + 2x1 = 13 */ p.newCtr("C1", 2*x[0] + 3*x[1] >= 41); p.newCtr("C2", x[0] + 2*x[1] == 13); // Uncomment the following line to cause an error in the model that // triggers the user error handling: // x[2]=p.newVar("x_2", XPRB_UI, 10,1); // Objective: minimize x0+x1 le=0; for(i=0;i<2;i++) le += x[i]; p.setObj(le); // Select objective function p.setSense(XPRB_MINIM); // Set objective sense to minimization p.print(); // Print current problem definition p.lpOptimize(""); // Solve the LP XPRBprintf(p.getCRef(), "problem status: %d LP status: %d MIP status: %d\n", p.getProbStat(), p.getLPStat(), p.getMIPStat()); // This problem is infeasible, that means the following command will fail. // It prints a warning if the message level is at least 2 XPRBprintf(p.getCRef(), "Objective: %g\n", p.getObjVal()); for(i=0;i<2;i++) // Print solution values XPRBprintf(p.getCRef(), "%s:%g, ", x[i].getName(), x[i].getSol()); XPRBprintf(p.getCRef(), "\n"); } /***********************************************************************/ int main() { XPRBprob *p; XPRBseterrctrl(0); // Switch to error handling by the user's program XPRB::setMsgLevel(2); // Set the printing flag. Try other values: // 0 - no printed output, 1 - only errors, // 2 - errors and warnings, 3 - all messages // Define the callback functions: XPRBdefcbmsg(NULL, userprint, NULL); XPRBdefcberr(NULL, usererror, NULL); try { p=new XPRBprob("Expl3"); // Initialize a new problem in BCL } catch(bcl_exception &e) { cout << e.code << ":" << e.msg; return 1; } try { modexpl3(*p); // Formulate and solve the problem } catch(bcl_exception &e) { cout << e.code << ":" << e.msg << "\n"; // return 2; } catch(const char *m) { cout << m << "\n"; return 3; } catch(...) { cout << "other exception\n"; return 4; } return 0; }