// lazy constaint callback int callback (CPXCENVptr env, void *cbdata, int wherefrom, void *cbhandle, int *useraction_p) { int status; CPXLPptr lp = malloc(0); status = CPXgetcallbacknodelp (env, cbdata, wherefrom, &lp); fprintf(stdout,"lazy: "); // char s[50]; // sprintf(s,"%f", objval); // printf("%s\n", s); double x[3]; CPXgetcallbacknodex (env, cbdata, wherefrom, x, 0, 3-1); printf("\n"); for(int i = 0; i < 3; i++) { char xs[10]; sprintf(xs,"%f, ", x[i]); printf("%s", xs); } printf("\n"); // if(x[0] > 20) // { // x[0]--; // *isfeas_p = 0; // } int cmatbeg[1] = {0}; int cmatind[3] = {0,1,2}; double cmatval[3] = {0,1,0}; char csense[1] = {'L'}; double crhs[1] = {20}; // CPXaddusercuts doesnt work for some f*****g reason if(x[2] > 20) { //*isfeas_p = 0; //status = CPXaddlazyconstraints(env, lp, 1, 3, crhs, csense, cmatbeg, cmatind, cmatval, NULL ); status = CPXcutcallbackadd(env, cbdata, wherefrom, 3, 20, 'L', cmatind, cmatval, CPX_USECUT_FORCE); } // if ( status ) { fprintf (stderr, "Some f*****g error, status = %d.\n", status); } //*useraction_p = CPX_CALLBACK_SET; return 0; }
int CPXPUBLIC CPX_CutCallback(CPXCENVptr xenv, void *cbdata, int wherefrom, void *cbhandle, int *useraction_p) { // cout << "Entering CPX Callback\n" << flush; CPXLPptr nodelp; CPXgetcallbacknodelp(xenv, cbdata, wherefrom, &nodelp); CoinCallbacks* ccc = (CoinCallbacks*)cbhandle; int length = CPXgetnumcols(xenv,nodelp) - 1; //hey, don't ask me! some VERY WIERD PHENOMENON... crap double objVal; double* solution = new double[length]; CPXgetcallbacknodeobjval(xenv, cbdata, wherefrom, &objVal); CPXgetcallbacknodex(xenv, cbdata, wherefrom, solution, 0, length-1); OsiCuts* cuts = new OsiCuts(); CoinCallbacks::CutReturn ret = ccc->cutCallback(objVal, solution, cuts); if(ret == CoinCallbacks::CR_AddCuts) { for(int i = cuts->sizeRowCuts(); i-->0;) { const OsiRowCut& c = cuts->rowCut(i); const CoinPackedVector& vec = c.row(); if(c.globallyValid()) /* Old Cplex-Versions did NOT have the last parameter (now set to "false"). * If you compile agains an older CPLEX version, simple *REMOVE* * ", false" * from the calls to CPXcutscallbackadd */ CPXcutcallbackadd(xenv, cbdata, wherefrom, vec.getNumElements(), c.rhs(), c.sense(), vec.getIndices(), vec.getElements(), false); //default to non-purgable cuts else CPXcutcallbackaddlocal(xenv, cbdata, wherefrom, vec.getNumElements(), c.rhs(), c.sense(), vec.getIndices(), vec.getElements()); cuts->eraseRowCut(i); } if(cuts->sizeColCuts() > 0) { cerr << "ColCuts currently not supported...\n"; OGDF_THROW_PARAM(LibraryNotSupportedException, lnscFunctionNotImplemented); } } *useraction_p = ( ret == CoinCallbacks::CR_Error) ? CPX_CALLBACK_FAIL : ( ret == CoinCallbacks::CR_AddCuts ) ? CPX_CALLBACK_SET : CPX_CALLBACK_DEFAULT; delete cuts; delete[] solution; // cout << "Leaving CPX Callback\n" << flush; return 0; // success }
static int CPXPUBLIC usersolve (CPXCENVptr env, void *cbdata, int wherefrom, void *cbhandle, int *useraction_p) { int status = 0; int nodecount; CPXLPptr nodelp; *useraction_p = CPX_CALLBACK_DEFAULT; /* Get pointer to LP subproblem */ status = CPXgetcallbacknodelp (env, cbdata, wherefrom, &nodelp); if ( status ) goto TERMINATE; /* Find out what node is being processed */ status = CPXgetcallbackinfo (env, cbdata, wherefrom, CPX_CALLBACK_INFO_NODE_COUNT, &nodecount); if ( status ) goto TERMINATE; /* Solve initial node with primal, others with dual */ if ( nodecount < 1 ) status = CPXprimopt (env, nodelp); else status = CPXdualopt (env, nodelp); /* If the solve was OK, set return to say optimization has been done in callback, otherwise return the CPLEX error code */ if ( !status ) *useraction_p = CPX_CALLBACK_SET; TERMINATE: return (status); } /* END usersolve */
static int CPXPUBLIC solvecallback (CPXCENVptr env, void *cbdata, int wherefrom, void *userinfo, int *useraction_p) { int status = 0; int lpstatus = 0; CPXLPptr nodelp = NULL; double *prex = NULL; MYCBptr mycbinfo = (MYCBptr) userinfo; CPXLPptr mip = mycbinfo->mip; double *relx = mycbinfo->relx; int cols; int prestat; *useraction_p = CPX_CALLBACK_DEFAULT; /* Only use callback for solving the root relaxation (node 0) */ if ( mycbinfo->count > 0 ) { goto TERMINATE; } mycbinfo->count++; /* Extract the LP to be solved */ status = CPXgetcallbacknodelp (env, cbdata, wherefrom, &nodelp); if ( status ) goto TERMINATE; cols = CPXgetnumcols (env, nodelp); prex = (double *) malloc (cols * sizeof (double)); if ( prex == NULL ) { status = CPXERR_NO_MEMORY; goto TERMINATE; } /* Use MIP presolve to crush the original solution. Note that MIP presolve can only crush primal solutions */ status = CPXgetprestat (env, mip, &prestat, NULL, NULL, NULL, NULL); if ( status ) goto TERMINATE; /* If a presolved model exists, then relx is crushed down to prex, the corresponding solution for the presolved model; otherwise, prex is just a copy of relx */ if ( prestat ) { status = CPXcrushx (env, mip, relx, prex); if ( status ) goto TERMINATE; } else { memcpy (prex, relx, cols * sizeof (double)); } /* Feed the crushed solution into 'nodelp' */ status = CPXcopystart (env, nodelp, NULL, NULL, prex, NULL, NULL, NULL); /* Use primal to reoptimize, since we only have a primal solution */ status = CPXprimopt (env, nodelp); if ( status ) goto TERMINATE; lpstatus = CPXgetstat (env, nodelp); if ( lpstatus == CPX_STAT_OPTIMAL || lpstatus == CPX_STAT_OPTIMAL_INFEAS || lpstatus == CPX_STAT_INFEASIBLE ) { *useraction_p = CPX_CALLBACK_SET; } TERMINATE: free_and_null ((char **) &prex); return (status); } /* END solvecallback */