static int CPXPUBLIC usersolve (CPXCENVptr env, void *cbdata, int wherefrom, void *cbhandle, int *useraction_p) { int status = 0; CPXCNT nodecount; CPXLPptr nodelp; *useraction_p = CPX_CALLBACK_DEFAULT; /* Get pointer to LP subproblem */ status = CPXXgetcallbacknodelp (env, cbdata, wherefrom, &nodelp); if ( status ) goto TERMINATE; /* Find out what node is being processed */ status = CPXXgetcallbackinfo (env, cbdata, wherefrom, CPX_CALLBACK_INFO_NODE_COUNT_LONG, &nodecount); if ( status ) goto TERMINATE; /* Solve initial node with primal, others with dual */ if ( nodecount < 1 ) status = CPXXprimopt (env, nodelp); else status = CPXXdualopt (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; CPXDIM 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 = CPXXgetcallbacknodelp (env, cbdata, wherefrom, &nodelp); if ( status ) goto TERMINATE; cols = CPXXgetnumcols (env, nodelp); prex = malloc (cols * sizeof (*prex)); 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 = CPXXgetprestat (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 = CPXXcrushx (env, mip, relx, prex); if ( status ) goto TERMINATE; } else { memcpy (prex, relx, cols * sizeof (*relx)); } /* Feed the crushed solution into 'nodelp' */ status = CPXXcopystart (env, nodelp, NULL, NULL, prex, NULL, NULL, NULL); /* Use primal to reoptimize, since we only have a primal solution */ status = CPXXprimopt (env, nodelp); if ( status ) goto TERMINATE; lpstatus = CPXXgetstat (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 */