benders.c
Go to the documentation of this file.
31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
56#define SCIP_DEFAULT_TRANSFERCUTS FALSE /** should Benders' cuts generated in LNS heuristics be transferred to the main SCIP instance? */
58#define SCIP_DEFAULT_LNSCHECK TRUE /** should the Benders' decomposition be used in LNS heuristics */
60#define SCIP_DEFAULT_LNSMAXCALLS 10 /** the maximum number of Benders' decomposition calls in LNS heuristics */
61#define SCIP_DEFAULT_LNSMAXCALLSROOT 0 /** the maximum number of root node Benders' decomposition calls in LNS heuristics */
62#define SCIP_DEFAULT_SUBPROBFRAC 1.0 /** fraction of subproblems that are solved in each iteration */
63#define SCIP_DEFAULT_UPDATEAUXVARBOUND FALSE /** should the auxiliary variable lower bound be updated by solving the subproblem */
64#define SCIP_DEFAULT_AUXVARSIMPLINT FALSE /** set the auxiliary variables as implint if the subproblem objective is integer */
65#define SCIP_DEFAULT_CUTCHECK TRUE /** should cuts be generated during the checking of solutions? */
66#define SCIP_DEFAULT_STRENGTHENMULT 0.5 /** the convex combination multiplier for the cut strengthening */
67#define SCIP_DEFAULT_NOIMPROVELIMIT 5 /** the maximum number of cut strengthening without improvement */
68#define SCIP_DEFAULT_STRENGTHENPERTURB 1e-06 /** the amount by which the cut strengthening solution is perturbed */
69#define SCIP_DEFAULT_STRENGTHENENABLED FALSE /** enable the core point cut strengthening approach */
70#define SCIP_DEFAULT_STRENGTHENINTPOINT 'r' /** where should the strengthening interior point be sourced from ('l'p relaxation, 'f'irst solution, 'i'ncumbent solution, 'r'elative interior point, vector of 'o'nes, vector of 'z'eros) */
71#ifdef SCIP_DISABLED_CODE /* temporarily disabling support for multiple threads in Benders' decomposition */
72#define SCIP_DEFAULT_NUMTHREADS 1 /** the number of parallel threads to use when solving the subproblems */
74#define SCIP_DEFAULT_EXECFEASPHASE FALSE /** should a feasibility phase be executed during the root node processing */
75#define SCIP_DEFAULT_SLACKVARCOEF 1e+6 /** the initial objective coefficient of the slack variables in the subproblem */
76#define SCIP_DEFAULT_MAXSLACKVARCOEF 1e+9 /** the maximal objective coefficient of the slack variables in the subproblem */
77#define SCIP_DEFAULT_CHECKCONSCONVEXITY TRUE /** should the constraints of the subproblem be checked for convexity? */
80#define BENDERS_MAXPSEUDOSOLS 5 /** the maximum number of pseudo solutions checked before suggesting
85#define AUXILIARYVAR_NAME "##bendersauxiliaryvar" /** the name for the Benders' auxiliary variables in the master problem */
86#define SLACKVAR_NAME "##bendersslackvar" /** the name for the Benders' slack variables added to each
95#define MIPNODEFOCUS_EVENTHDLR_DESC "node focus event handler for the MIP solve method for Benders' decomposition"
98#define UPPERBOUND_EVENTHDLR_DESC "found solution event handler to terminate subproblem solve for a given upper bound"
237 /* sending an interrupt solve signal to return the control back to the Benders' decomposition plugin.
241 SCIP_CALL( SCIPdropEvent(scip, SCIP_EVENTTYPE_NODEFOCUSED, eventhdlr, NULL, eventhdlrdata->filterpos) );
247/** solving process initialization method of event handler (called when branch and bound process is about to begin) */
261/** solving process deinitialization method of event handler (called before branch and bound process data is freed) */
315 SCIP_STRINGEQ( SCIPeventhdlrGetName(eventhdlr), MIPNODEFOCUS_EVENTHDLR_NAME, SCIP_INVALIDCALL );
325 SCIP_CALL( SCIPdropEvent(scip, SCIP_EVENTTYPE_NODEFOCUSED, eventhdlr, NULL, eventhdlrdata->filterpos) );
333/** solving process initialization method of event handler (called when branch and bound process is about to begin) */
340 SCIP_STRINGEQ( SCIPeventhdlrGetName(eventhdlr), MIPNODEFOCUS_EVENTHDLR_NAME, SCIP_INVALIDCALL );
347/** solving process deinitialization method of event handler (called before branch and bound process data is freed) */
354 SCIP_STRINGEQ( SCIPeventhdlrGetName(eventhdlr), MIPNODEFOCUS_EVENTHDLR_NAME, SCIP_INVALIDCALL );
368 SCIP_STRINGEQ( SCIPeventhdlrGetName(eventhdlr), MIPNODEFOCUS_EVENTHDLR_NAME, SCIP_INVALIDCALL );
382 SCIP_STRINGEQ( SCIPeventhdlrGetName(eventhdlr), MIPNODEFOCUS_EVENTHDLR_NAME, SCIP_INVALIDCALL );
408 if( SCIPisLT(scip, SCIPgetSolOrigObj(scip, bestsol)*(int)SCIPgetObjsense(scip), eventhdlrdata->upperbound) )
416/** solving process initialization method of event handler (called when branch and bound process is about to begin) */
430/** solving process deinitialization method of event handler (called before branch and bound process data is freed) */
486 eventhdlr = SCIPfindEventhdlr(SCIPbendersSubproblem(benders, probnumber), UPPERBOUND_EVENTHDLR_NAME);
500 * This function solves the master problem with only the auxiliary variables in the objective function.
592/** solving process initialization method of event handler (called when branch and bound process is about to begin) */
606 /* The event is only caught if there is an active Benders' decomposition, the integer subproblem are solved and
609 if( SCIPbendersIsActive(benders) && !SCIPbendersOnlyCheckConvexRelax(benders, SCIPgetSubscipsOff(scip))
619/* ---------------- Methods for the parallelisation of Benders' decomposition ---------------- */
708 /* this is a workaround for GCG. GCG expects that the variable has vardata when added. So a dummy vardata is created */
715 /* if the current Benders is the highest priority Benders, then we need to create the auxiliary variables.
716 * Otherwise, if the shareauxvars flag is set, then the auxiliary variables from the highest priority Benders' are
722 /* creating the auxiliary variable objective sum constraint. If the auxiliary variables are shared, then the constraint
723 * is only added to the top Benders. Otherwise, it is created for each Benders implementation. */
732 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_%s", AUXILIARYVAR_NAME, SCIPbendersGetName(benders) );
749 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "master_%s_%s", AUXILIARYVAR_NAME, SCIPbendersGetName(benders) );
750 SCIP_CALL( SCIPcreateVarBasic(scip, &benders->masterauxvar, varname, -SCIPinfinity(scip), SCIPinfinity(scip),
771 /* if the auxiliary variables are shared, then a pointer to the variable is retrieved from topbenders,
772 * otherwise the auxiliaryvariable is created. The auxiliary variable constraint is also copied from the
793 * NOTE: It is only possible to determine if the objective function is integral if the subproblem is defined as
805 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "%s_%d_%s", AUXILIARYVAR_NAME, i, SCIPbendersGetName(benders) );
806 SCIP_CALL( SCIPcreateVarImpl(scip, &auxiliaryvar, varname, benders->subproblowerbound[i], SCIPinfinity(scip), 0.0,
816 /* if the objective type is minimax, then we need to create the auxiliary variable constraints and add the
817 * auxiliary variable to them. If the objective type is sum, then the auxiliary variables are added to the
822 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_%d_%s", AUXILIARYVAR_NAME, i, SCIPbendersGetName(benders) );
823 SCIP_CALL( SCIPcreateConsBasicLinear(scip, &cons, consname, 0, NULL, NULL, 0.0, SCIPinfinity(scip)) );
846 SCIP_CALL( SCIPchgVarImplType(scip, benders->masterauxvar, SCIP_IMPLINTTYPE_WEAK, &infeasible) );
856/** finds the Benders' auxiliary variable for a given sub-SCIP. If probnumber is -1, then the master auxiliary variable
878 /* the prefix for the variable names is required for UG, since we don't know how many copies have been made. To
879 * find the target variable, we start with an empty prefix. Then t_ is prepended until the target variable is
885 /* when probnumber == -1, we are searching for the master auxiliary variable. Otherwise, we are searching for the
889 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "%smaster_%s_%s", prefix, AUXILIARYVAR_NAME, SCIPbendersGetName(benders));
891 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "%s%s_%d_%s", prefix, AUXILIARYVAR_NAME, probnumber, SCIPbendersGetName(benders));
893 /* finding the variable in the copied problem that has the same name as the auxiliary variable */
908/** assigns the copied auxiliary variables in the target SCIP to the target Benders' decomposition data */
925 /* this is a workaround for GCG. GCG expects that the variable has vardata when added. So a dummy vardata is created */
932 /* if the auxiliary variable are shared, then the variable name will have a suffix of the highest priority Benders'
1015 return strcmp(SCIPbendersGetName((SCIP_BENDERS*)elem1), SCIPbendersGetName((SCIP_BENDERS*)elem2));
1033/** creates a variable mapping between the master problem variables of the source scip and the sub scip */
1056 /* creating the hashmap for the mapping between the master variable of the target and source scip */
1061 /* getting the variable pointer for the target SCIP variables. The variable mapping returns the target SCIP
1085 SCIP_BENDERS* targetbenders; /* the copy of the Benders' decomposition struct in the target set */
1095 if( benders->benderscopy != NULL && targetset->benders_copybenders && SCIPbendersIsActive(benders) )
1097 SCIPsetDebugMsg(targetset, "including Benders' decomposition %s in subscip %p\n", SCIPbendersGetName(benders), (void*)targetset->scip);
1125 /* When the Benders' decomposition is copied then a variable mapping between the master problem variables is
1126 * required. This variable mapping is used to transfer the cuts generated in the target SCIP to the source SCIP.
1127 * The variable map is stored in the target Benders' decomposition. This will be freed when the sub-SCIP is freed.
1158 SCIP_DECL_BENDERSCOPY ((*benderscopy)), /**< copy method of Benders' decomposition or NULL if you don't want to copy your plugin into sub-SCIPs */
1162 SCIP_DECL_BENDERSINITPRE((*bendersinitpre)),/**< presolving initialization method for Benders' decomposition */
1163 SCIP_DECL_BENDERSEXITPRE((*bendersexitpre)),/**< presolving deinitialization method for Benders' decomposition */
1164 SCIP_DECL_BENDERSINITSOL((*bendersinitsol)),/**< solving process initialization method of Benders' decomposition */
1165 SCIP_DECL_BENDERSEXITSOL((*bendersexitsol)),/**< solving process deinitialization method of Benders' decomposition */
1166 SCIP_DECL_BENDERSGETVAR((*bendersgetvar)),/**< returns the master variable for a given subproblem variable */
1167 SCIP_DECL_BENDERSCREATESUB((*benderscreatesub)),/**< creates a Benders' decomposition subproblem */
1168 SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve)),/**< called prior to the subproblem solving loop */
1169 SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex)),/**< the solving method for convex Benders' decomposition subproblems */
1170 SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub)),/**< the solving method for the Benders' decomposition subproblems */
1171 SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve)),/**< called after the subproblems are solved. */
1172 SCIP_DECL_BENDERSFREESUB((*bendersfreesub)),/**< the freeing method for the Benders' decomposition subproblems */
1183 /* Checking whether the benderssolvesub and the bendersfreesub are both implemented or both are not implemented */
1187 SCIPerrorMessage("Benders' decomposition <%s> requires that if bendersFreesub%s is implemented, then at least "
1188 "one of bendersSolvesubconvex%s or bendersSolvesub%s are implemented.\n", name, name, name, name);
1224 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of Benders' decomposition <%s>", name);
1231 "should Benders' cuts be generated for LP solutions?", &(*benders)->cutlp, FALSE, cutlp, NULL, NULL) ); /*lint !e740*/
1235 "should Benders' cuts be generated for pseudo solutions?", &(*benders)->cutpseudo, FALSE, cutpseudo, NULL, NULL) ); /*lint !e740*/
1239 "should Benders' cuts be generated for relaxation solutions?", &(*benders)->cutrelax, FALSE, cutrelax, NULL, NULL) ); /*lint !e740*/
1241 /* These parameters are left for the user to decide in a settings file. This departs from the usual SCIP convention
1246 "should Benders' cuts from LNS heuristics be transferred to the main SCIP instance?", &(*benders)->transfercuts,
1251 "should Benders' decomposition be used in LNS heurisics?", &(*benders)->lnscheck, FALSE, SCIP_DEFAULT_LNSCHECK,
1256 "maximum depth at which the LNS check is performed (-1: no limit)", &(*benders)->lnsmaxdepth, TRUE,
1261 "the maximum number of Benders' decomposition calls in LNS heuristics (-1: no limit)", &(*benders)->lnsmaxcalls,
1266 "the maximum number of root node Benders' decomposition calls in LNS heuristics (-1: no limit)",
1281 "should the auxiliary variable bound be updated by solving the subproblem?", &(*benders)->updateauxvarbound,
1286 "if the subproblem objective is integer, then define the auxiliary variables as implicit integers?",
1301 "the maximum number of cut strengthening without improvement", &(*benders)->noimprovelimit, TRUE,
1306 "the constant use to perturb the cut strengthening core point", &(*benders)->perturbeps, FALSE,
1311 "should the core point cut strengthening be employed (only applied to fractional solutions or continuous subproblems)?",
1312 &(*benders)->strengthenenabled, FALSE, SCIP_DEFAULT_STRENGTHENENABLED, NULL, NULL) ); /*lint !e740*/
1316 "where should the strengthening interior point be sourced from ('l'p relaxation, 'f'irst solution, 'i'ncumbent solution, 'r'elative interior point, vector of 'o'nes, vector of 'z'eros)",
1317 &(*benders)->strengthenintpoint, FALSE, SCIP_DEFAULT_STRENGTHENINTPOINT, "lfiroz", NULL, NULL) ); /*lint !e740*/
1319#ifdef SCIP_DISABLED_CODE /* temporarily disabling support for multiple threads in Benders' decomposition */
1328 "should a feasibility phase be executed during the root node, i.e. adding slack variables to constraints to ensure feasibility",
1333 "the initial objective coefficient of the slack variables in the subproblem", &(*benders)->slackvarcoef, FALSE,
1338 "the maximal objective coefficient of the slack variables in the subproblem", &(*benders)->maxslackvarcoef, FALSE,
1343 "should the constraints of the subproblems be checked for convexity?", &(*benders)->checkconsconvexity, FALSE,
1356 * To use the Benders' decomposition for solving a problem, it first has to be activated with a call to SCIPactivateBenders().
1370 SCIP_DECL_BENDERSCOPY ((*benderscopy)), /**< copy method of Benders' decomposition or NULL if you don't want to copy your plugin into sub-SCIPs */
1374 SCIP_DECL_BENDERSINITPRE((*bendersinitpre)),/**< presolving initialization method for Benders' decomposition */
1375 SCIP_DECL_BENDERSEXITPRE((*bendersexitpre)),/**< presolving deinitialization method for Benders' decomposition */
1376 SCIP_DECL_BENDERSINITSOL((*bendersinitsol)),/**< solving process initialization method of Benders' decomposition */
1377 SCIP_DECL_BENDERSEXITSOL((*bendersexitsol)),/**< solving process deinitialization method of Benders' decomposition */
1378 SCIP_DECL_BENDERSGETVAR((*bendersgetvar)),/**< returns the master variable for a given subproblem variable */
1379 SCIP_DECL_BENDERSCREATESUB((*benderscreatesub)),/**< creates a Benders' decomposition subproblem */
1380 SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve)),/**< called prior to the subproblem solving loop */
1381 SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex)),/**< the solving method for convex Benders' decomposition subproblems */
1382 SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub)),/**< the solving method for the Benders' decomposition subproblems */
1383 SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve)),/**< called after the subproblems are solved. */
1384 SCIP_DECL_BENDERSFREESUB((*bendersfreesub)),/**< the freeing method for the Benders' decomposition subproblems */
1392 SCIP_CALL_FINALLY( doBendersCreate(benders, set, messagehdlr, blkmem, name, desc, priority, cutlp, cutpseudo,
1393 cutrelax, shareauxvars, benderscopy, bendersfree, bendersinit, bendersexit, bendersinitpre, bendersexitpre,
1394 bendersinitsol, bendersexitsol, bendersgetvar, benderscreatesub, benderspresubsolve, benderssolvesubconvex,
1395 benderssolvesub, benderspostsolve, bendersfreesub, bendersdata), (void) SCIPbendersFree(benders, set) );
1455 /* if the Benders' decomposition is a copy and a varmap has been passed to SCIP_BENDERS, then the variable map
1499 SCIP_ALLOC( BMSreallocMemoryArray(&benders->submastervars[probnumber], newsize) ); /*lint !e866*/
1545 /* if mastervar is not NULL, then the subproblem variable has a corresponding master problem variable */
1581 /* checking whether the constraint is a linear constraint. If so, we add a coefficient to the constraint */
1594 "This is not supported and the slack variable will not be added to the constraint. Feasibility cuts may be invalid.\n",
1614 /* if the right hand side is finite, then we need to add a slack variable with a negative coefficient */
1619 SCIP_CALL( SCIPcreateVarBasic(scip, &var, name, 0.0, SCIPinfinity(scip), objcoef, SCIP_VARTYPE_CONTINUOUS) );
1638 /* if the left hand side if finite, then we need to add a slack variable with a positive coefficient */
1643 SCIP_CALL( SCIPcreateVarBasic(scip, &var, name, 0.0, SCIPinfinity(scip), objcoef, SCIP_VARTYPE_CONTINUOUS) );
1665/** adds the slack variables to each of the constraints for the generation of feasibility cuts for the given non-linear
1705 SCIP_CALL( addSlackVars(subproblem, benders, cons, linearconshdlrs, nlconshdlr, NLINEARCONSHDLRS) );
1711/** initialises a MIP subproblem by putting the problem into SCIP_STAGE_SOLVING. This is achieved by calling SCIPsolve
1713 * The LP subproblem is also initialised using this method; however, a different event handler is added. This event
1715 * The MIP solving function is called to initialise the subproblem because this function calls SCIPsolve with the
1741 SCIP_CALL( SCIPbendersSolveSubproblemCIP(set->scip, benders, probnumber, &solvestatus, FALSE) );
1758/** initialises an LP subproblem by putting the problem into probing mode. The probing mode is invoked in a node focus
1759 * event handler. This event handler is added just prior to calling the initialise subproblem function.
1786 SCIP_CALL( SCIPincludeEventhdlrBasic(subproblem, &eventhdlr, NODEFOCUS_EVENTHDLR_NAME, NODEFOCUS_EVENTHDLR_DESC,
1800/** checks whether the convex relaxation of the subproblem is sufficient to solve the original problem to optimality
1803 * To do this, we check that all variables are of continuous type and that every constraint is either handled by known
1804 * linear constraint handler (knapsack, linear, logicor, setppc, varbound) or the nonlinear constraint handler.
1806 * Further, nonlinear constraints are only considered if an NLP solver interface is available, i.e., and NLP could
1808 * If constraints are present that cannot be identified as linear or convex nonlinear, then we assume that the
1852 SCIP_CALL( SCIPgetVarsData(subproblem, &vars, &nvars, &nbinvars, &nintvars, &nimplintvars, NULL) );
1854 /* if there are any binary, integer or implicit integer variables, then the subproblems is marked as non-convex */
1867 /* Get pointer to the nonlinear constraint handler if we also have an NLP solver to solve NLPs.
1868 * If there is no NLP solver, but there are (convex) nonlinear constraints, then the LP relaxation of subproblems
1869 * will (currently) not be sufficient to solve subproblems to optimality. Thus, we also take the presence of convex
1870 * nonlinear constraints as signal for having to solve the CIP eventually, thus, by abuse of notation,
1871 * return not-convex here. In summary, we do not need to have a special look onto non-linear constraints
1872 * if no NLP solver is present, and can treat them as any other constraint that is not of linear type.
1879 /* if the nonlinear constraint handler exists, then we create a hashmap of variables that can be assumed to be fixed.
1886 SCIP_CALL( SCIPhashmapCreate(&assumevarfixed, SCIPblkmem(set->scip), SCIPgetNVars(subproblem)) );
1915 SCIPdebugMsg(subproblem, "subproblem <%s>: constraint <%s> is linear\n", SCIPgetProbName(subproblem), SCIPconsGetName(cons));
1947 /* make sure activities are up to date. SCIPhasExprCurvature currently assumes that this is already the case */
1950 SCIP_CALL( SCIPhasExprCurvature(subproblem, SCIPgetExprNonlinear(cons), havelhs ? SCIP_EXPRCURV_CONCAVE : SCIP_EXPRCURV_CONVEX, &isconvex, assumevarfixed) );
1957 SCIPdebugMsg(subproblem, "subproblem <%s>: nonlinear constraint <%s> is convex\n", SCIPgetProbName(subproblem), SCIPconsGetName(cons));
1964 SCIPdebugMsg(subproblem, "subproblem <%s>: nonlinear constraint <%s> not convex\n", SCIPgetProbName(subproblem), SCIPconsGetName(cons));
1971 SCIPdebugMsg(subproblem, "subproblem <%s>: potentially nonconvex constraint <%s>\n", SCIPgetProbName(subproblem), SCIPconsGetName(cons));
1980 /* setting the flag for the convexity of the subproblem. If convexity doesn't need to be checked, then it is assumed
1981 * that the subproblems are convex. However, if there are discrete variables, then the problem must be set as
1982 * non-convex. The discrete master variables will be changed to continuous, but this will happen at the first call to
2003 SCIPsetDebugMsg(set, "subproblem <%s> has been found to be of type %d\n", SCIPgetProbName(subproblem),
2037 /* if the subproblems have already been created, then they will not be created again. This is the case if the
2038 * transformed problem has been freed and then retransformed. The subproblems should only be created when the problem
2053 /* the subproblem SCIP instance could be set to NULL. This is because user defined subproblem solving methods
2054 * could be used that don't solve a SCIP instance. Thus, the following setup of the subproblem SCIP instance is
2057 * NOTE: since the subproblems are supplied as NULL pointers, the internal convexity check can not be performed.
2062 /* stores the master problem variables that are in the subproblem. This is helpful for all instances where the
2073 /* The objective function coefficients of the master problem are set to zero. This is necessary for the Benders'
2074 * decomposition algorithm, since the cut methods and the objective function check assumes that the objective
2077 * This only occurs if the Benders' decomposition is not a copy. It is assumed that the correct objective
2080 * If the subproblems were copied, then the master variables will be checked to ensure that they have a zero
2093 /* if mastervar is not NULL, then the subproblem variable has a corresponding master problem variable */
2096 SCIPverbMessage(subproblem, SCIP_VERBLEVEL_FULL, NULL, "Benders' decomposition: Changing the objective "
2108 SCIPverbMessage(subproblem, SCIP_VERBLEVEL_FULL, NULL, "Benders' decomposition: Objective coefficients of "
2116 /* checking the convexity of the subproblem. The convexity of the subproblem indicates whether the convex
2121 /* if the problem is convex and has nonlinear constraints, then slack variables must be added to each of the
2128 /* the slack variables are only added to the subproblem once. If the initialisation methods are called from a
2129 * copy, then the slack variables are not re-added. Alternatively, if the copy must be threadsafe, then the
2137 /* setting the flag to indicate that slack variables have been added to the subproblem constraints. This is only
2144 /* after checking the subproblem for convexity, if the subproblem has convex constraints and continuous variables,
2149 /* if the user has not implemented a solve subproblem callback, then the subproblem solves are performed
2157 /* if the initialisation process indicates that the LP is infeasible, then the complete problem is
2158 * infeasible. The subprobsinfeasible flag is set so that SCIP can be informed at the correct point
2170 /* because the subproblems could be reused in the copy, the event handler is not created again. If the
2172 * NOTE: This currently works with the benders_default implementation. It may not be very general. */
2207 SCIPerrorMessage("If the subproblem is set to NULL, then the subproblem type must be specified.\n");
2208 SCIPerrorMessage("In the subproblem creation callback, call SCIPbendersSetSubproblemType with the appropriate problem type.\n");
2215 /* checking the convexity of the master problem. This information is useful for the cut generation methods, such as
2263 /* if the Benders' decomposition is a copy, then the auxiliary variables already exist. So they are registered with
2264 * the Benders' decomposition struct during the init stage. If the Benders' decomposition is not a copy, then the
2273 /* creates the subproblems and sets up the probing mode for LP subproblems. This function calls the benderscreatesub
2283 SCIP_ALLOC( BMSallocBlockMemoryArray(SCIPblkmem(set->scip), &benders->storedcuts, BENDERS_ARRAYSIZE) );
2302/** Transfers Benders' cuts that were generated while solving a sub-SCIP to the original SCIP instance. This involves
2303 * creating a constraint/cut that is equivalent to the generated cut in the sub-SCIP. This new constraint/cut is then
2318 SCIP_CONSHDLR* consbenders; /* a helper variable for the Benders' decomposition constraint handler */
2319 SCIP_CONS* transfercons = NULL; /* the constraint that is generated to transfer the constraints/cuts */
2345 * SCIPcreateConsBasicLinear/SCIPcreateEmptyRowConshdlr. This should be implemented to improve the performance of the
2352 SCIP_CALL( SCIPcreateConsBasicLinear(sourcescip, &transfercons, cutname, 0, NULL, NULL, lhs, rhs) );
2357 SCIP_CALL( SCIPcreateEmptyRowConshdlr(sourcescip, &transfercut, consbenders, cutname, lhs, rhs, FALSE,
2373 /* if the source variable is not found, then the mapping in incomplete. So the constraint can not be
2496 /* if the Benders' decomposition is a copy, then is a variable mapping was provided, then the generated cuts will
2507 SCIPfreeBlockMemoryArray(set->scip, &benders->storedcuts[i]->vals, benders->storedcuts[i]->nvars);
2508 SCIPfreeBlockMemoryArray(set->scip, &benders->storedcuts[i]->vars, benders->storedcuts[i]->nvars);
2520 /* it is possible that the master problem is not solved. As such, the auxiliary variables will not be created. So
2523 if( benders->objectivetype == SCIP_BENDERSOBJTYPE_MAX && benders->auxiliaryvarcons[i] != NULL )
2530 /* we need to remove the locks from the auxiliary variables. This will be called always for the highest priority
2534 SCIP_CALL( SCIPaddVarLocksType(set->scip, benders->auxiliaryvars[i], SCIP_LOCKTYPE_MODEL, -1, 0) );
2540 if( benders->objectivetype == SCIP_BENDERSOBJTYPE_SUM && benders->auxiliaryvarcons[0] != NULL )
2547 /* we need to remove the locks from the auxiliary variables. This will be called always for the highest priority
2552 SCIP_CALL( SCIPaddVarLocksType(set->scip, benders->masterauxvar, SCIP_LOCKTYPE_MODEL, -1, 0) );
2602 /* looping over all subproblems to check whether there exists at least one master problem variable */
2605 /* if there are user defined solving or freeing functions, then it is not possible to declare the independence of
2620 /* if the subporblem variable is not NULL, then the subproblem depends on the master problem */
2647 /* the arrays for the auxiliary variables and constraints are not allocated at the activate stage. This is because
2648 * SCIPbendersActivate can be called during SCIP_STAGE_PROBLEM. As such, the user may still change the objective type
2649 * after the Benders' decomposition has been activated. The memory allocation occurs immediately before the variables
2662 /* if the Benders' decomposition is the original, then the auxiliary variables need to be created. If the Benders'
2663 * decomposition is a copy, then the auxiliary variables already exist. The assignment of the auxiliary variables
2668 /* check the subproblem independence. This check is only performed if the user has not implemented a solve
2766 /* freeing all subproblems that are independent, this is because they have not bee freed during the subproblem
2793 /* sorting the Benders' decomposition cuts in order of priority. Only a single cut is generated for each subproblem
2794 * per solving iteration. This is particularly important in the case of the optimality and feasibility cuts. Since
2795 * these work on two different solutions to the subproblem, it is not necessary to generate both cuts. So, once the
2863 SCIP_ALLOC( BMSallocMemoryArray(&benders->submastervars[i], BENDERS_MASTERVARARRAYSIZE) ); /*lint !e866*/
2899 SCIP_CALL( SCIPincludeEventhdlrBasic(set->scip, &eventhdlr, NODESOLVED_EVENTHDLR_NAME, NODESOLVED_EVENTHDLR_DESC,
2934 /* if the subproblems were created by the Benders' decomposition core, then they need to be freed */
3017/** updates the lower bound for all auxiliary variables. This is called if the first LP enforced is unbounded. */
3044 SCIP_CALL( SCIPbendersComputeSubproblemLowerbound(benders, set, i, &lowerbound, &infeasible) );
3059 SCIPsetDebugMsg(set, "Tightened lower bound of <%s> to %g\n", SCIPvarGetName(auxiliaryvar), lowerbound);
3072/** sets the core point used for cut strengthening. If the strenghtenintpoint is set to 'i', then the core point is
3086 /* if the core point is not NULL and the interior point is not reinitialised, then nothing is done */
3092 /* if the core point should be updated, then this only happens if the incumbent solution has been updated */
3125 /* if there is time remaining, then compute the relative interior point. Otherwise, return the LP solution */
3128 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, 0, "Computing relative interior point (time limit: %g, iter limit: %d) ...\n", timelimit, INT_MAX);
3129 SCIP_CALL( SCIPcomputeLPRelIntPoint(scip, TRUE, FALSE, timelimit, INT_MAX, &benders->corepoint) );
3169 SCIP_Bool* auxviol, /**< set to TRUE only if the solution is feasible but the aux vars are violated */
3170 SCIP_Bool* infeasible, /**< is the master problem infeasible with respect to the Benders' cuts? */
3171 SCIP_Bool* skipsolve, /**< should the main solve be skipped as a result of this strengthening? */
3187 /* the cut stabilisation is only performed when enforcing LP solutions. The solution is not NULL if the stabilisation
3204 /* if the number of iterations without improvement exceeds 3*noimprovelimit, then the no stabilisation is performed
3209 /* if there is no incumbent solution, then it is not possible to create the core point and hence the strengthening
3215 /* if no LP iterations have been performed since the last call of the cut strenghtening, then the strengthening is
3223 /* if the separation point solution is NULL, then we create the solution using the current LP relaxation. */
3227 * TODO: This could be a little to memory heavy, it may be better just to create the separation point once and then
3236 /* creating a solution that is a convex combination of the LP solution and the separation point */
3258 /* if the variable is a linking variable and it is not fixed, then a convex combination with the corepoint is
3263 /* if the number of iterations without improvement exceeds noimprovelimit, then no convex combination is
3274 /* if the number of iterations without improvement is less than 2*noimprovelimit, then perturbation is
3292 SCIP_CALL( SCIPsolveBendersSubproblems(set->scip, benders, sepapoint, result, infeasible, auxviol, type, checkint) );
3294 SCIPsetDebugMsg(set, "solved Benders' decomposition subproblems with stabilised point. noimprovecount %d result %d\n",
3317 * when Benders' is used in the LNS heuristics, only the convex relaxations of the master/subproblems are checked,
3318 * i.e. no integer cuts are generated. In this case, then Benders' decomposition is performed under the assumption
3341 return (int) SCIPsetCeil(set, (SCIP_Real) SCIPbendersGetNSubproblems(benders)*benders->subprobfrac);
3424 solvestat->avgiter = (SCIP_Real)(solvestat->avgiter*solvestat->ncalls + SCIPgetNLPIterations(subproblem))
3438/** Solves each of the Benders' decomposition subproblems for the given solution. All, or a fraction, of subproblems are
3440 * Since a convex relaxation of the subproblem could be solved to generate cuts, a parameter nverified is used to
3441 * identified the number of subproblems that have been solved in their "original" form. For example, if the subproblem
3442 * is a MIP, then if the LP is solved to generate cuts, this does not constitute a verification. The verification is
3456 SCIP_Bool** subprobsolved, /**< an array indicating the subproblems that were solved in this loop. */
3458 SCIP_Bool* infeasible, /**< is the master problem infeasible with respect to the Benders' cuts? */
3472 /* in the case of an LNS check, only the convex relaxations of the subproblems will be solved. This is a performance
3473 * feature, since solving the convex relaxation is typically much faster than solving the corresponding CIP. While
3474 * the CIP is not solved during the LNS check, the solutions are still of higher quality than when Benders' is not
3479 SCIPsetDebugMsg(set, "Performing the subproblem solving process. Number of subproblems to check %d\n", nsolveidx);
3485 /* TODO: Check whether this is absolutely necessary. I think that this if statment can be removed. */
3491 /* TODO: ensure that the each of the subproblems solve and update the parameters with the correct return values
3509 /* for the second solving loop, if the problem is an LP, it is not solved again. If the problem is a MIP,
3510 * then the subproblem objective function value is set to infinity. However, if the subproblem is proven
3512 * If the solve loop is SCIP_BENDERSSOLVELOOP_USERCIP, then nothing is done. It is assumed that the user will
3526 /* if the subproblem is independent, then it does not need to be solved. In this case, the nverified flag will
3531 /* NOTE: There is no need to update the optimal flag. This is because optimal is always TRUE until a
3534 /* if the auxiliary variable value is infinity, then the subproblem has not been solved yet. Currently the
3546 SCIPsetDebugMsg(set, "Benders' decomposition: subproblem %d is not active, but has not been solved."
3554 SCIPbendersSetSubproblemObjval(benders, i, SCIPbendersGetAuxiliaryVarVal(benders, set, sol, i));
3563 SCIPsetDebugMsg(set, "Benders' decomposition: subproblem %d is not active, setting status to OPTIMAL\n", i);
3569 if( solveloop == SCIP_BENDERSSOLVELOOP_CONVEX || solveloop == SCIP_BENDERSSOLVELOOP_USERCONVEX )
3574 retcode = SCIPbendersExecSubproblemSolve(benders, set, sol, i, solveloop, FALSE, &solved, &subinfeas, type);
3593 /* if the subproblems are solved to check integer feasibility, then the optimality check must be performed.
3594 * This will only be performed if checkint is TRUE and the subproblem was solved. The subproblem may not be
3599 /* if the subproblem is feasible, then it is necessary to update the value of the auxiliary variable to the
3613 /* It is only possible to determine the optimality of a solution within a given subproblem in four
3616 * ii) solveloop == SCIP_BENDERSOLVELOOP_CONVEX and only the convex relaxations will be checked.
3617 * iii) solveloop == SCIP_BENDERSSOLVELOOP_USERCIP and the subproblem was solved, since the user has
3632 SCIPbendersGetAuxiliaryVarVal(benders, set, sol, i), SCIPbendersGetSubproblemObjval(benders, i));
3637 SCIPbendersGetAuxiliaryVarVal(benders, set, sol, i), SCIPbendersGetSubproblemObjval(benders, i));
3642 /* the nverified variable is only incremented when the original form of the subproblem has been solved.
3643 * What is meant by "original" is that the LP relaxation of CIPs are solved to generate valid cuts. So
3644 * if the subproblem is defined as a CIP, then it is only classified as checked if the CIP is solved.
3648 * ii) solveloop == SCIP_BENDERSSOLVELOOP_CIP or USERCIP and the CIP for the subproblem has been
3652 if( ((solveloop == SCIP_BENDERSSOLVELOOP_CONVEX || solveloop == SCIP_BENDERSSOLVELOOP_USERCONVEX)
3677 * The priority of the results are: SCIP_CONSADDED (SCIP_SEPARATED), SCIP_DIDNOTFIND, SCIP_FEASIBLE, SCIP_DIDNOTRUN. In
3694 SCIP_Bool* subprobsolved, /**< an array indicating the subproblems that were solved in this loop. */
3722 /* in the case of an LNS check, only the convex relaxations of the subproblems will be solved. This is a performance
3723 * feature, since solving the convex relaxation is typically much faster than solving the corresponding CIP. While
3724 * the CIP is not solved during the LNS check, the solutions are still of higher quality than when Benders' is not
3731 && SCIPsetGetStage(set) != SCIP_STAGE_TRANSFORMED && SCIPsetGetStage(set) != SCIP_STAGE_PRESOLVED
3744 /* cuts can only be generated if the subproblem is not independent and if it has been solved. Additionally, the
3762 /* the result is updated only if a Benders' cut is generated or one was not found. However, if a cut has
3763 * been found in a previous iteration, then the result is returned as SCIP_CONSADDED or SCIP_SEPARATED.
3764 * This result is permitted because if a constraint was added, the solution that caused the error in the cut
3769 || (!SCIPbenderscutIsLPCut(benderscuts[j]) && ((solveloop == SCIP_BENDERSSOLVELOOP_CIP && !convexsub)
3796 /* the highest priority for the results is CONSADDED and SEPARATED. The solveloopresult will always be
3815 /* since a cut was not found, then merging could be useful to avoid this in subsequent iterations. The
3826 /* if the subproblem is infeasible and no cut generation methods were run, then the infeasibility will
3827 * never be resolved. As such, the subproblem will be merged into the master problem. If the subproblem
3866 if( addedcuts == 0 && SCIPbendersGetNConvexSubproblems(benders) < SCIPbendersGetNSubproblems(benders)
3875 * The checkint flag indicates whether integer feasibility can be assumed. If it is not assumed, i.e. checkint ==
3876 * FALSE, then only the convex relaxations of the subproblems are solved. If integer feasibility is assumed, i.e.
3877 * checkint == TRUE, then the convex relaxations and the full CIP are solved to generate Benders' cuts and check
3880 * TODO: consider allowing the possibility to pass solution information back from the subproblems instead of the scip
3881 * instance. This would allow the use of different solvers for the subproblems, more importantly allowing the use of an
3889 SCIP_Bool* infeasible, /**< is the master problem infeasible with respect to the Benders' cuts? */
3890 SCIP_Bool* auxviol, /**< set to TRUE only if the solution is feasible but the aux vars are violated */
3928 SCIPsetDebugMsg(set, "Starting Benders' decomposition subproblem solving; type: %d, checkint: %u\n", type, checkint);
3939 /* It is assumed that the problem is optimal, until a subproblem is found not to be optimal. However, not all
3940 * subproblems could be checked in each iteration. As such, it is not possible to state that the problem is optimal
3941 * if not all subproblems are checked. Situations where this may occur is when a subproblem is a MIP and only the LP
3942 * is solved. Also, in a distributed computation, then it may be advantageous to only solve some subproblems before
3943 * resolving the master problem. As such, for a problem to be optimal, then (optimal && allverified) == TRUE
3949 /* if the Benders' decomposition is called from a sub-SCIP and the sub-SCIPs have been deactivated, then it is
3950 * assumed that this is an LNS heuristic. As such, the check is not performed and the solution is assumed to be
3957 || (type != SCIP_BENDERSENFOTYPE_CHECK && SCIPgetDepth(set->scip) == 0 && benders->lnsmaxcallsroot > -1
3964 /* it is not necessary to check all primal solutions by solving the Benders' decomposition subproblems.
3966 * If the solution is non-improving, the result FEASIBLE is returned. While this may be incorrect w.r.t to the
3967 * Benders' subproblems, this solution will never be the optimal solution. A non-improving solution may be used
3968 * within LNS primal heuristics. If this occurs, the improving solution, if found, will be checked by the solving
3972 if( checkint && SCIPsetIsLE(set, SCIPgetPrimalbound(set->scip)*(int)SCIPgetObjsense(set->scip),
3979 /* if the enforcement type is SCIP_BENDERSENFOTYPE_LP and the LP is currently unbounded. This could mean that there
3980 * is no lower bound on the auxiliary variables. In this case, we try to update the lower bound for the auxiliary
3983 if( type == SCIP_BENDERSENFOTYPE_LP && SCIPgetLPSolstat(set->scip) == SCIP_LPSOLSTAT_UNBOUNDEDRAY
4002 SCIP_CALL( benders->benderspresubsolve(set->scip, benders, sol, type, checkint, infeasible, auxviol, &skipsolve,
4012 SCIPerrorMessage("the user-defined pre subproblem solving method for the Benders' decomposition <%s> returned "
4017 /* if the solve must be skipped, then the solving loop is exited and the user defined result is returned */
4026 /* the cut strengthening is performed before the regular subproblem solve is called. To avoid recursion, the flag
4027 * strengthenround is set to TRUE when the cut strengthening is performed. The cut strengthening is not performed as
4030 * NOTE: cut strengthening is only applied for fractional solutions and integer solutions if there are no CIP
4034 && (!checkint || SCIPbendersGetNConvexSubproblems(benders) == SCIPbendersGetNSubproblems(benders)) )
4039 /* if the user has not requested the solve to be skipped, then the cut strengthening is performed */
4040 SCIP_CALL( performInteriorSolCutStrengthening(benders, set, sol, type, checkint, FALSE, infeasible, auxviol,
4044 /* if the solve must be skipped, then the solving loop is exited and the user defined result is returned */
4069 /* only a subset of the subproblems are initially solved. Both solving loops are executed for the subproblems to
4070 * check whether any cuts are generated. If a cut is generated, then no further subproblems are solved. If a cut is
4078 /* by default the number of solve loops is 1. This is the case if all subproblems are LP or the user has defined a
4079 * benderssolvesub callback. If there is a subproblem that is not an LP, then 2 solve loops are performed. The first
4086 SCIP_BENDERSSOLVELOOP solveloop; /* identifies what problem type is solve in this solve loop */
4088 /* if either benderssolvesubconvex or benderssolvesub are implemented, then the user callbacks are invoked */
4103 /* if the solving has been stopped, then the subproblem solving and cut generation must terminate */
4107 /* Generating cuts for the subproblems. Cuts are only generated when the solution is from primal heuristics,
4112 SCIP_CALL( generateBendersCuts(benders, set, sol, result, type, solveloop, checkint, subprobsolved,
4117 /* The first solving loop solves the convex subproblems and the convex relaxations of the CIP subproblems. The
4118 * second solving loop solves the CIP subproblems. The second solving loop is only called if the integer
4119 * feasibility is being checked and if the convex subproblems and convex relaxations are not infeasible.
4121 if( !(*infeasible) && checkint && !SCIPbendersOnlyCheckConvexRelax(benders, SCIPsetGetSubscipsOff(set))
4133 /* if the result is CONSADDED or SEPARATED, then a cut is generated and no further subproblem processing is
4148 SCIPsetDebugMsg(set, "End Benders' decomposition subproblem solve. result %d infeasible %u auxviol %u nverified %d\n",
4158 /* if the number of checked pseudo solutions exceeds a set limit, then all subproblems are passed as merge
4159 * candidates. Currently, merging subproblems into the master problem is the only method for resolving numerical
4162 * We are only interested in the pseudo solutions that have been checked completely for integrality. This is
4163 * identified by checkint == TRUE. This means that the Benders' decomposition constraint is one of the last
4164 * constraint handlers that must resolve the infeasibility. If the Benders' decomposition framework can't resolve the
4173 /* if a priority merge candidate already exists, then no other merge candidates need to be added.*/
4176 /* all subproblems are added to the merge candidate list. The first active subproblem is added as a
4191 SCIPverbMessage(set->scip, SCIP_VERBLEVEL_HIGH, NULL, " The number of checked pseudo solutions exceeds the "
4192 "limit of %d. All active subproblems are merge candidates, with subproblem %d a priority candidate.\n",
4200 /* if the result is SCIP_DIDNOTFIND, then there was a error in generating cuts in all subproblems that are not
4201 * optimal. This result does not cutoff any solution, so the Benders' decomposition algorithm will fail.
4203 * It could happen that the cut strengthening approach causes an error the cut generation. In this case, an error
4205 * TODO: Work out a way to ensure Benders' decomposition does not terminate due to a SCIP_DIDNOTFIND result.
4214 SCIPerrorMessage("An error was found when generating cuts for non-optimal subproblems of Benders' "
4215 "decomposition <%s>. Consider merging the infeasible subproblems into the master problem.\n", SCIPbendersGetName(benders));
4217 /* since no other cuts are generated, then this error will result in a crash. It is possible to avoid the error,
4220 * NOTE: If the error occurs while checking solutions, i.e. SCIP_BENDERSENFOTYPE_CHECK, then it is valid to set
4237 /* if the subproblems are not infeasible, but they are also not optimal. This means that there is a violation
4238 * in the auxiliary variable values. In this case, a feasible result is returned with the auxviol flag set to
4247 /* if the subproblems are being solved as part of conscheck, then the results flag must be returned after the solving
4256 /* if the subproblems are not infeasible, but they are also not optimal. This means that there is a violation
4257 * in the auxiliary variable values. In this case, a feasible result is returned with the auxviol flag set to
4265 /* calling the post-solve call back for the Benders' decomposition algorithm. This allows the user to work directly
4273 SCIP_CALL( benders->benderspostsolve(set->scip, benders, sol, type, mergecands, npriomergecands, nmergecands,
4280 /* since subproblems have been merged, then constraints have been added. This could resolve the unresolved
4287 SCIPerrorMessage("An error occurred during Benders' decomposition cut generations and no merging had been "
4326 SCIPsetDebugMsg(set, "End Benders' decomposition execution method. result %d infeasible %u auxviol %u\n", *result,
4339 /* if there was an error in generating cuts and merging was not performed, then the solution is perturbed in an
4350 /* if the user has not requested the solve to be skipped, then the cut strengthening is performed */
4351 SCIP_CALL( performInteriorSolCutStrengthening(benders, set, sol, type, checkint, TRUE, infeasible, auxviol,
4361 /* if the Benders' decomposition subproblem check stopped, then we don't have a valid result. In this case, the
4367 /* if the subproblem verification identifies the solution as feasible, then a check whether slack variables have been
4368 * used is necessary. If any slack variables are non-zero, then the solution is reverified after the objective
4389 SCIPmessagePrintVerbInfo(SCIPgetMessagehdlr(set->scip), set->disp_verblevel, SCIP_VERBLEVEL_HIGH, "Increasing the slack variable coefficient to %g.\n", benders->slackvarcoef);
4393 SCIPmessagePrintVerbInfo(SCIPgetMessagehdlr(set->scip), set->disp_verblevel, SCIP_VERBLEVEL_HIGH, "Fixing the slack variables to zero.\n");
4397 SCIP_CALL( SCIPsolveBendersSubproblems(set->scip, benders, sol, result, infeasible, auxviol, type, checkint) );
4408 SCIP_CALL( SCIPsolveBendersSubproblems(set->scip, benders, sol, result, infeasible, auxviol, type, checkint) );
4426 SCIP_BENDERSSOLVELOOP solveloop, /**< the solve loop iteration. The first iter is for LP, the second for IP */
4436 assert(solveloop == SCIP_BENDERSSOLVELOOP_USERCONVEX || solveloop == SCIP_BENDERSSOLVELOOP_USERCIP);
4440 /* calls the user defined subproblem solving method. Only the convex relaxations are solved during the Large
4468 SCIPerrorMessage("the user-defined solving method for the Benders' decomposition <%s> returned invalid result <%d>\n",
4479 SCIPerrorMessage("the user-defined solving method for the Benders' decomposition <%s> returned objective value %g\n",
4497 SCIP_BENDERSSOLVELOOP solveloop, /**< the solve loop iteration. The first iter is for LP, the second for IP */
4519 if( subproblem == NULL && (benders->benderssolvesubconvex == NULL || benders->benderssolvesub == NULL) )
4521 SCIPerrorMessage("The subproblem %d is set to NULL, but both bendersSolvesubconvex%s and bendersSolvesub%s "
4530 /* if the subproblem solve callback is implemented, then that is used instead of the default setup */
4531 if( solveloop == SCIP_BENDERSSOLVELOOP_USERCONVEX || solveloop == SCIP_BENDERSSOLVELOOP_USERCIP )
4533 /* calls the user defined subproblem solving method. Only the convex relaxations are solved during the Large
4535 SCIP_CALL( executeUserDefinedSolvesub(benders, set, sol, probnumber, solveloop, infeasible, &objective, &result) );
4547 /* if the limits of the master problem were hit during the setup process, then the subproblem will not have
4559 SCIP_CALL( updateEventhdlrUpperbound(benders, probnumber, SCIPbendersGetAuxiliaryVarVal(benders, set, sol, probnumber)) );
4568 SCIP_CALL( SCIPbendersSolveSubproblemLP(set->scip, benders, probnumber, &solvestatus, &objective) );
4581 SCIP_CALL( SCIPbendersSolveSubproblemCIP(set->scip, benders, probnumber, &solvestatus, FALSE) );
4586 /* if the generic subproblem solving methods are used, then the CIP subproblems are always solved. */
4604 * If a subproblem is unbounded, then the auxiliary variables are set to -infinity and the unbounded flag is
4619 SCIPverbMessage(set->scip, SCIP_VERBLEVEL_FULL, NULL, " Benders' decomposition: Error solving "
4625 SCIPerrorMessage("The Benders' decomposition subproblem %d is unbounded. This should not happen.\n",
4631 SCIPerrorMessage("Invalid status returned from solving Benders' decomposition subproblem %d. Solution status: %d\n",
4638 assert(solveloop == SCIP_BENDERSSOLVELOOP_USERCONVEX || solveloop == SCIP_BENDERSSOLVELOOP_USERCIP);
4645 SCIPerrorMessage("The Benders' decomposition subproblem %d is unbounded. This should not happen.\n",
4651 SCIPerrorMessage("Invalid result <%d> from user-defined subproblem solving method. This should not happen.\n",
4685 SCIPerrorMessage("The subproblem %d is NULL. Thus, the subproblem setup must be performed manually in either "
4694 /* if the Benders' decomposition subproblem is convex and has continuous variables, then probing mode
4696 * If the subproblem contains non-convex constraints or discrete variables, then the problem must be initialised,
4697 * and then put into SCIP_STAGE_SOLVING to be able to change the variable bounds. The probing mode is entered once
4712 /* if the problem is identified as infeasible, this means that the underlying LP is infeasible. Since no variable
4713 * fixings have been applied at this stage, this means that the complete problem is infeasible. It is only
4731 /* looping over all variables in the subproblem to find those corresponding to the master problem variables. */
4732 /* TODO: It should be possible to store the pointers to the master variables to speed up the subproblem setup */
4739 /* It is possible due to numerics that the solution value exceeds the upper or lower bounds. When this
4740 * happens, it causes an error in the LP solver as a result of inconsistent bounds. So the following statements
4741 * are used to ensure that the bounds are not exceeded when applying the fixings for the Benders'
4767 /* if the slack variables have been added to help improve feasibility, then they remain unfixed with a large
4768 * objective coefficient. Once the root node has been solved to optimality, then the slack variables are
4771 if( benders->feasibilityphase && SCIPgetDepth(set->scip) == 0 && type != SCIP_BENDERSENFOTYPE_CHECK )
4773 /* The coefficient update or variable fixing can only be performed if the subproblem is in probing mode.
4790 /* if the subproblem is non-linear and convex, then slack variables have been added to the subproblem. These
4791 * need to be fixed to zero when first solving the subproblem. However, if the slack variables have been added
4805 /* if the subproblem contain non-convex constraints or discrete variables, then the probing mode is entered after
4819/** Solve a Benders' decomposition subproblems. This will either call the user defined method or the generic solving
4820 * methods. If the generic method is called, then the subproblem must be set up before calling this method. */
4839 if( SCIPbendersSubproblem(benders, probnumber) != NULL && !SCIPbendersSubproblemIsSetup(benders, probnumber)
4842 SCIPerrorMessage("Benders' decomposition subproblem %d must be set up before calling SCIPbendersSolveSubproblem(). Call SCIPsetupSubproblem() first.\n", probnumber);
4846 /* if the subproblem solve callback is implemented, then that is used instead of the default setup */
4858 SCIP_CALL( executeUserDefinedSolvesub(benders, set, sol, probnumber, solveloop, infeasible, &subobj, &result) );
4871 if( solvecip && SCIPbendersGetSubproblemType(benders, probnumber) != SCIP_BENDERSSUBTYPE_CONVEXCONT )
4875 SCIP_CALL( SCIPbendersSolveSubproblemCIP(set->scip, benders, probnumber, &solvestatus, solvecip) );
4880 (*objective) = SCIPgetSolOrigObj(subproblem, SCIPgetBestSol(subproblem))*(int)SCIPgetObjsense(subproblem);
4886 /* if the subproblem has convex constraints and continuous variables, then it should have been initialised and
4891 /* if the subproblem is not in probing mode, then it must be put into that mode for the LP solve. */
4910 SCIP_CALL( SCIPbendersSolveSubproblemLP(set->scip, benders, probnumber, &solvestatus, &lpobjective) );
4944 /* setting the time limit for the Benders' decomposition subproblems. It is set to 102% of the remaining time. */
4954 submemorylimit = mastermemorylimit - (SCIPgetMemUsed(scip) + SCIPgetMemExternEstim(scip))/1048576.0;
4978 SCIP_CALL( SCIPgetBoolParam(subproblem, "lp/alwaysgetduals", &origparams->lp_alwaysgetduals) );
4981 SCIP_CALL( SCIPgetIntParam(subproblem, "propagating/maxrounds", &origparams->prop_maxrounds) );
4982 SCIP_CALL( SCIPgetIntParam(subproblem, "propagating/maxroundsroot", &origparams->prop_maxroundsroot) );
4983 SCIP_CALL( SCIPgetIntParam(subproblem, "constraints/linear/propfreq", &origparams->cons_linear_propfreq) );
5060 SCIP_CALL( SCIPsetIntParam(subproblem, "propagating/maxroundsroot", origparams->prop_maxroundsroot) );
5061 SCIP_CALL( SCIPsetIntParam(subproblem, "constraints/linear/propfreq", origparams->cons_linear_propfreq) );
5097 /* TODO: This should be solved just as an LP, so as a MIP. There is too much overhead with the MIP.
5102 /* only solve the NLP relaxation if the NLP has been constructed and there exists an NLPI. If it is not possible to
5138 if( nlptermstat == SCIP_NLPTERMSTAT_OKAY && (nlpsolstat == SCIP_NLPSOLSTAT_LOCINFEASIBLE || nlpsolstat == SCIP_NLPSOLSTAT_GLOBINFEASIBLE) )
5158 SCIPerrorMessage("The NLP of Benders' decomposition subproblem %d is unbounded. This should not happen.\n",
5169 SCIPwarningMessage(scip, "The NLP solver stopped due to an iteration limit for Benders' decomposition subproblem %d. Consider increasing benders/%s/nlpiterlimit.\n", probnumber, SCIPbendersGetName(benders));
5178 SCIPerrorMessage("Invalid solution status: %d. Termination status: %d. Solving the NLP relaxation of Benders' decomposition subproblem %d.\n",
5208 SCIPerrorMessage("The LP of Benders' decomposition subproblem %d is unbounded. This should not happen.\n",
5232 SCIPerrorMessage("Invalid status: %d. Solving the LP relaxation of Benders' decomposition subproblem %d.\n",
5273 /* If the solve has been stopped for the subproblem, then we need to restart it to complete the solve. The subproblem
5277 /* the subproblem should be in probing mode. Otherwise, the event handler did not work correctly */
5283 /* the problem was interrupted in the event handler, so SCIP needs to be informed that the problem is to be restarted */
5301 /* if the problem is not in probing mode, then we need to solve the LP. That requires all methods that will
5326 SCIPerrorMessage("Invalid status: %d. Solving the CIP of Benders' decomposition subproblem %d.\n",
5349 || (benders->bendersfreesub == NULL && benders->benderssolvesubconvex == NULL && benders->benderssolvesub == NULL));
5365 /* ending probing mode to reset the current node. The probing mode will be restarted at the next solve */
5373 /* if the subproblems were solved as part of an enforcement stage, then they will still be in probing mode. The
5409 SCIPsetDebugMsg(set, "Subproblem %d - Auxiliary Variable: %g Subproblem Objective: %g Reldiff: %g Soltol: %g\n",
5411 SCIPrelDiff(SCIPbendersGetSubproblemObjval(benders, probnumber), auxiliaryvarval), benders->solutiontol);
5413 if( SCIPrelDiff(SCIPbendersGetSubproblemObjval(benders, probnumber), auxiliaryvarval) < benders->solutiontol )
5438/** Solves an independent subproblem to identify its lower bound. The lower bound is then used to update the bound on
5467 SCIPinfoMessage(set->scip, NULL, "Benders' decomposition: a bendersSolvesub or bendersSolvesubconvex has been "
5470 "SCIPbendersUpdateSubproblemLowerbound in bendersCreatesub. The auxiliary variable %d will remain as %g\n",
5477 SCIPverbMessage(set->scip, SCIP_VERBLEVEL_FULL, NULL, "Benders' decomposition: Computing a lower bound for"
5498 /* if the subproblem is independent, then the default SCIP settings are used. Otherwise, only the root node is solved
5509 /* if the subproblem not independent and is convex, then the probing LP is solved. Otherwise, the MIP is solved */
5533 if( nlptermstat == SCIP_NLPTERMSTAT_OKAY && (nlpsolstat == SCIP_NLPSOLSTAT_LOCINFEASIBLE || nlpsolstat == SCIP_NLPSOLSTAT_GLOBINFEASIBLE) )
5557 /* if the subproblem is not convex, then event handlers have been added to interrupt the solve. These must be
5560 eventhdlrdata = SCIPeventhdlrGetData(SCIPfindEventhdlr(subproblem, MIPNODEFOCUS_EVENTHDLR_NAME));
5583 /* the subproblem must be freed so that it is reset for the subsequent Benders' decomposition solves. If the
5584 * subproblems are independent, they are not freed. SCIPfreeBendersSubproblem must still be called, but in this
5585 * function the independent subproblems are not freed. However, they will still be freed at the end of the
5593/** Merges a subproblem into the master problem. This process just adds a copy of the subproblem variables and
5594 * constraints to the master problem, but keeps the subproblem stored in the Benders' decomposition data structure. The reason for
5595 * keeping the subproblem available is for when it is queried for solutions after the problem is solved.
5597 * Once the subproblem is merged into the master problem, then the subproblem is flagged as disabled. This means that
5600 * The associated auxiliary variables are kept in the master problem. The objective function of the merged subproblem
5606 SCIP_HASHMAP* varmap, /**< a hashmap to store the mapping of subproblem variables corresponding
5633 SCIPverbMessage(set->scip, SCIP_VERBLEVEL_HIGH, NULL, " Benders' decomposition: Infeasibility of subproblem %d can't "
5634 "be resolved. Subproblem %d is being merged into the master problem.\n", probnumber, probnumber);
5636 /* freeing the subproblem because it will be flagged as independent. Since the subproblem is flagged as independent,
5657 SCIP_CALL( SCIPhashmapCreate(&localconsmap, SCIPblkmem(set->scip), SCIPgetNConss(subproblem)) );
5669 SCIP_CALL( SCIPcreateConsBasicLinear(set->scip, &objcons, consname, 0, NULL, NULL, -SCIPsetInfinity(set), 0.0) );
5679 /* if the master problem variable is not NULL, then there is a corresponding variable in the master problem for
5688 /* This is following the same process as in createVariableMappings. The original variable is used to map
5714 /* creating the mapping betwen the subproblem var and the master var for the constraint copying */
5735 /* NOTE: adding all subproblem constraints appears to cause an error when resolving the LP, which results in the
5736 * current incumbent being reported as optimal. To avoid this, only half of the subproblem constraints are added
5741 SCIP_CALL( SCIPgetConsCopy(subproblem, set->scip, conss[i], &targetcons, SCIPconsGetHdlr(conss[i]),
5743 SCIPconsIsEnforced(conss[i]), SCIPconsIsChecked(conss[i]), SCIPconsIsPropagated(conss[i]), FALSE,
5776 /* the merged subproblem is no longer solved. This is indicated by setting the subproblem as disabled. The
5802 /* if the variable name matches the auxiliary variable, then the master variable is returned as NULL */
5879 SCIP_DECL_BENDERSINITPRE((*bendersinitpre))/**< initialize presolving for Benders' decomposition */
5890 SCIP_DECL_BENDERSEXITPRE((*bendersexitpre))/**< deinitialize presolving for Benders' decomposition */
5901 SCIP_DECL_BENDERSINITSOL((*bendersinitsol))/**< solving process initialization callback of Benders' decomposition */
5912 SCIP_DECL_BENDERSEXITSOL((*bendersexitsol))/**< solving process deinitialization callback of Benders' decomposition */
5923 SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve))/**< called prior to the subproblem solving loop */
5934 SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex))/**< solving method for the convex Benders' decomposition subproblem */
5945 SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub))/**< solving method for a Benders' decomposition subproblem */
5956 SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve))/**< solving process deinitialization callback of Benders' decomposition */
5967 SCIP_DECL_SORTPTRCOMP((*benderssubcomp)) /**< a comparator for defining the solving order of the subproblems */
6052/** gets the number of times, the Benders' decomposition was called and tried to find a variable with negative reduced costs */
6062/** gets the number of optimality cuts found by the collection of Benders' decomposition subproblems */
6122/** enables or disables all clocks of the Benders' decomposition, depending on the value of the flag */
6124 SCIP_BENDERS* benders, /**< the Benders' decomposition for which all clocks should be enabled or disabled */
6184/** adds a subproblem to the Benders' decomposition data. If a custom subproblem solving method is used, then the
6195 /* if the subproblem pointer is NULL, then the subproblem solving callback functions must be set. */
6198 SCIPerrorMessage("The subproblem can only be set to NULL if both bendersSolvesubconvex%s and bendersSolvesub%s "
6354 /* if the slack variables have not been added, then we can immediately state that no slack variables are active */
6367 /* if the subproblem is convex and an NLP, then we need to create the NLP solution. Otherwise, the solution can be
6457 * It is possible that this can change during the solving process. One example is when the three-phase method is
6458 * employed, where the first phase solves the convex relaxation of both the master and subproblems, the second phase
6459 * reintroduces the integrality constraints to the master problem and the third phase then reintroduces integrality
6510 SCIP_Bool isnonlinear /**< flag to indicate whether the subproblem contains non-linear constraints */
6523 assert(benders->nnonlinearsubprobs >= 0 && benders->nnonlinearsubprobs <= benders->nsubproblems);
6551 SCIP_Bool isnonlinear /**< flag to indicate whether the subproblem contains non-linear constraints */
6631 /* only set the master problem variable to continuous if they have not already been changed. */
6664 /* if all of the integer variables have been changed to continuous, then the subproblem could now be a convex
6665 * problem. This must be checked and if TRUE, then the LP subproblem is initialised and then put into probing
6673 /* if the subproblem has convex constraints and continuous variables, then it is initialised and put into
6680 /* if the initialisation process indicates that the LP is infeasible, then the complete problem is
6681 * infeasible. The subprobsinfeasible flag is set so that SCIP can be informed at the correct point
6730 /* if the user has defined solving or freeing functions, then it is not possible to declare a subproblem as
6731 * independent. This is because declaring a subproblem as independent changes the solving loop, so it would change
6732 * the expected behaviour of the user defined plugin. If a user calls this function, then an error will be returned.
6734 if( benders->benderssolvesubconvex != NULL || benders->benderssolvesub != NULL || benders->bendersfreesub != NULL )
6736 SCIPerrorMessage("The user has defined either bendersSolvesubconvex%s, bendersSolvesub%s or bendersFreesub%s. "
6737 "Thus, it is not possible to declare the independence of a subproblem.\n", benders->name, benders->name,
6745 /* if the active status of the subproblem changes, then we must update the activesubprobs counter */
6756 assert(benders->nactivesubprobs >= 0 && benders->nactivesubprobs <= SCIPbendersGetNSubproblems(benders));
6772/** Sets whether the subproblem is enabled or disabled. A subproblem is disabled if it has been merged into the master
6786 /* if the active status of the subproblem changes, then we must update the activesubprobs counter */
6797 assert(benders->nactivesubprobs >= 0 && benders->nactivesubprobs <= SCIPbendersGetNSubproblems(benders));
6800/** returns whether the subproblem is enabled, i.e. the subproblem is still solved in the solving loop. */
6822 /* if the master variables were all continuous and now are not, then the subproblem must exit probing mode and be
6834 assert(subtype == SCIP_BENDERSSUBTYPE_CONVEXCONT || subtype == SCIP_BENDERSSUBTYPE_NONCONVEXCONT);
6859/** sets the objective type for the aggregation of the Benders' decomposition subproblem objectives. This is either the
6860 * summation of the objective values or a minimax of the objective values (such as for a makespan objective)
6872/** returns the objective type for the aggregation of the Benders' decomposition subproblem objectives */
6892/** updates the lower bound for the subproblem. If the lower bound is not greater than the previously stored lowerbound,
6908 SCIPdebugMessage("The lowerbound %g for subproblem %d is less than the currently stored lower bound %g\n",
6963/** returns the original problem data for the cuts that have been added by the Benders' cut plugin. The stored
6964 * variables and values will populate the input vars and vals arrays. Thus, memory must be allocated for the vars and
7118/** returns the array of currently available Benders' cuts; active Benders' decomposition are in the first slots of
SCIP_RETCODE SCIPbenderscutExit(SCIP_BENDERSCUT *benderscut, SCIP_SET *set)
Definition: benderscut.c:268
SCIP_RETCODE SCIPbenderscutFree(SCIP_BENDERSCUT **benderscut, SCIP_SET *set)
Definition: benderscut.c:203
SCIP_RETCODE SCIPbenderscutInitsol(SCIP_BENDERSCUT *benderscut, SCIP_SET *set)
Definition: benderscut.c:298
SCIP_RETCODE SCIPbenderscutExitsol(SCIP_BENDERSCUT *benderscut, SCIP_SET *set)
Definition: benderscut.c:322
SCIP_RETCODE SCIPbenderscutExec(SCIP_BENDERSCUT *benderscut, SCIP_SET *set, SCIP_BENDERS *benders, SCIP_SOL *sol, int probnumber, SCIP_BENDERSENFOTYPE type, SCIP_RESULT *result)
Definition: benderscut.c:346
SCIP_RETCODE SCIPbenderscutCopyInclude(SCIP_BENDERS *benders, SCIP_BENDERSCUT *benderscut, SCIP_SET *set)
Definition: benderscut.c:86
SCIP_RETCODE SCIPbenderscutInit(SCIP_BENDERSCUT *benderscut, SCIP_SET *set)
Definition: benderscut.c:229
internal methods for Benders' decomposition cuts
void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
Definition: clock.c:260
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:170
internal methods for clocks and timing issues
Constraint handler for linear constraints in their most general form, .
constraint handler for nonlinear constraints specified by algebraic expressions
internal methods for decompositions and the decomposition store
common defines and data types used in all packages of SCIP
SCIP_RETCODE SCIPaddLinearVarNonlinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real coef)
Definition: cons_nonlinear.c:14309
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:18076
SCIP_RETCODE SCIPcreateConsBasicLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
Definition: cons_linear.c:17924
SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
Definition: cons_nonlinear.c:14039
SCIP_EXPRCURV SCIPgetCurvatureNonlinear(SCIP_CONS *cons)
Definition: cons_nonlinear.c:14120
SCIP_RETCODE SCIPgetConsCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_CONS *sourcecons, SCIP_CONS **targetcons, SCIP_CONSHDLR *sourceconshdlr, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *name, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode, SCIP_Bool global, SCIP_Bool *valid)
Definition: scip_copy.c:1581
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip_prob.c:2115
void * SCIPhashmapEntryGetImage(SCIP_HASHMAPENTRY *entry)
Definition: misc.c:3613
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3284
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:3143
SCIP_HASHMAPENTRY * SCIPhashmapGetEntry(SCIP_HASHMAP *hashmap, int entryidx)
Definition: misc.c:3592
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3061
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:225
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_RETCODE SCIPhasExprCurvature(SCIP *scip, SCIP_EXPR *expr, SCIP_EXPRCURV curv, SCIP_Bool *success, SCIP_HASHMAP *assumevarfixed)
Definition: nlhdlr_convex.c:2630
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:250
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition: scip_param.c:545
SCIP_RETCODE SCIPsetHeuristics(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip_param.c:930
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip_param.c:487
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition: scip_param.c:307
SCIP_RETCODE SCIPsetPresolving(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip_param.c:956
SCIP_RETCODE SCIPsetCharParam(SCIP *scip, const char *name, char value)
Definition: scip_param.c:661
SCIP_RETCODE SCIPgetLongintParam(SCIP *scip, const char *name, SCIP_Longint *value)
Definition: scip_param.c:288
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition: scip_param.c:269
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition: scip_param.c:429
SCIP_RETCODE SCIPsetRealParam(SCIP *scip, const char *name, SCIP_Real value)
Definition: scip_param.c:603
SCIP_RETCODE SCIPgetCharParam(SCIP *scip, const char *name, char *value)
Definition: scip_param.c:326
SCIP_RETCODE SCIPpqueueInsert(SCIP_PQUEUE *pqueue, void *elem)
Definition: misc.c:1396
SCIP_RETCODE SCIPpqueueCreate(SCIP_PQUEUE **pqueue, int initsize, SCIP_Real sizefac, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), SCIP_DECL_PQUEUEELEMCHGPOS((*elemchgpos)))
Definition: misc.c:1297
SCIP_BENDERSOBJTYPE SCIPbendersGetObjectiveType(SCIP_BENDERS *benders)
Definition: benders.c:6871
SCIP_Real SCIPbendersGetSetupTime(SCIP_BENDERS *benders)
Definition: benders.c:6101
void SCIPbendersSetSubproblemObjval(SCIP_BENDERS *benders, int probnumber, SCIP_Real objval)
Definition: benders.c:6303
SCIP_RETCODE SCIPbendersSolSlackVarsActive(SCIP_BENDERS *benders, SCIP_Bool *activeslack)
Definition: benders.c:6332
SCIP_Bool SCIPbendersCutRelaxation(SCIP_BENDERS *benders)
Definition: benders.c:6163
int SCIPbendersGetNTransferredCuts(SCIP_BENDERS *benders)
Definition: benders.c:6881
SCIP_Bool SCIPbendersSubproblemIsConvex(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:6483
int SCIPbendersGetNStrengthenFails(SCIP_BENDERS *benders)
Definition: benders.c:6091
int SCIPgetBendersNSubproblems(SCIP *scip, SCIP_BENDERS *benders)
Definition: scip_benders.c:747
SCIP_RETCODE SCIPbendersGetStoredCutOrigData(SCIP_BENDERS *benders, int cutidx, SCIP_VAR ***vars, SCIP_Real **vals, SCIP_Real *lhs, SCIP_Real *rhs, int *nvars, int varssize)
Definition: benders.c:6965
void SCIPbendersSetSubproblemIsNonlinear(SCIP_BENDERS *benders, int probnumber, SCIP_Bool isnonlinear)
Definition: benders.c:6505
void SCIPbendersSetMasterIsNonlinear(SCIP_BENDERS *benders, SCIP_Bool isnonlinear)
Definition: benders.c:6547
SCIP_BENDERS * SCIPfindBenders(SCIP *scip, const char *name)
Definition: scip_benders.c:493
void SCIPbendersSetData(SCIP_BENDERS *benders, SCIP_BENDERSDATA *bendersdata)
Definition: benders.c:5820
SCIP_Bool SCIPbendersOnlyCheckConvexRelax(SCIP_BENDERS *benders, SCIP_Bool subscipsoff)
Definition: benders.c:3319
SCIP_Bool SCIPbendersSubproblemIsNonlinear(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:6525
SCIP_VAR * SCIPbendersGetAuxiliaryVar(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:6231
SCIP_BENDERSCUT * SCIPfindBenderscut(SCIP_BENDERS *benders, const char *name)
Definition: benders.c:7097
int SCIPbendersGetNConvexSubproblems(SCIP_BENDERS *benders)
Definition: benders.c:6495
SCIP_BENDERSSUBTYPE SCIPbendersGetSubproblemType(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:6442
SCIP_VAR ** SCIPbendersGetSubproblemMasterVars(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:6253
SCIP_RETCODE SCIPbendersSolveSubproblemCIP(SCIP *scip, SCIP_BENDERS *benders, int probnumber, SCIP_STATUS *solvestatus, SCIP_Bool solvecip)
Definition: benders.c:5248
int SCIPbendersGetNNonlinearSubproblems(SCIP_BENDERS *benders)
Definition: benders.c:6537
void SCIPsetBendersPriority(SCIP *scip, SCIP_BENDERS *benders, int priority)
Definition: scip_benders.c:590
SCIP_NLPPARAM SCIPbendersGetNLPParam(SCIP_BENDERS *benders)
Definition: benders.c:5065
SCIP_Bool SCIPbendersSubproblemIsEnabled(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:6799
SCIP_RETCODE SCIPgetBendersMasterVar(SCIP *scip, SCIP_BENDERS *benders, SCIP_VAR *var, SCIP_VAR **mappedvar)
Definition: scip_benders.c:685
int SCIPbendersGetNStrengthenCalls(SCIP_BENDERS *benders)
Definition: benders.c:6081
SCIP_RETCODE SCIPgetBendersSubproblemVar(SCIP *scip, SCIP_BENDERS *benders, SCIP_VAR *var, SCIP_VAR **mappedvar, int probnumber)
Definition: scip_benders.c:721
int SCIPbendersGetNStoredCuts(SCIP_BENDERS *benders)
Definition: benders.c:6924
SCIP_RETCODE SCIPbendersSolveSubproblemLP(SCIP *scip, SCIP_BENDERS *benders, int probnumber, SCIP_STATUS *solvestatus, SCIP_Real *objective)
Definition: benders.c:5078
int SCIPbendersGetNBenderscuts(SCIP_BENDERS *benders)
Definition: benders.c:7136
void SCIPbendersSetSubproblemIsConvex(SCIP_BENDERS *benders, int probnumber, SCIP_Bool isconvex)
Definition: benders.c:6460
SCIP_Bool SCIPbendersSubproblemsAreInfeasible(SCIP_BENDERS *benders)
Definition: benders.c:6596
void SCIPbendersSetSubproblemIsSetup(SCIP_BENDERS *benders, int probnumber, SCIP_Bool issetup)
Definition: benders.c:6694
SCIP_BENDERSDATA * SCIPbendersGetData(SCIP_BENDERS *benders)
Definition: benders.c:5810
SCIP_VAR ** SCIPbendersGetAuxiliaryVars(SCIP_BENDERS *benders)
Definition: benders.c:6243
int SCIPbendersGetNSubproblems(SCIP_BENDERS *benders)
Definition: benders.c:6029
void SCIPbendersSetSubproblemType(SCIP_BENDERS *benders, int probnumber, SCIP_BENDERSSUBTYPE subprobtype)
Definition: benders.c:6417
int SCIPbendersGetNStrengthenCutsFound(SCIP_BENDERS *benders)
Definition: benders.c:6071
void SCIPbendersUpdateSubproblemLowerbound(SCIP_BENDERS *benders, int probnumber, SCIP_Real lowerbound)
Definition: benders.c:6893
SCIP * SCIPbendersSubproblem(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:6039
void SCIPbendersGetSubproblemMasterVarsData(SCIP_BENDERS *benders, int probnumber, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars)
Definition: benders.c:6277
SCIP_Bool SCIPbendersMasterIsNonlinear(SCIP_BENDERS *benders)
Definition: benders.c:6558
SCIP_RETCODE SCIPbendersGetStoredCutData(SCIP_BENDERS *benders, int cutidx, SCIP_VAR ***vars, SCIP_Real **vals, SCIP_Real *lhs, SCIP_Real *rhs, int *nvars)
Definition: benders.c:6934
SCIP_Bool SCIPbendersIsInitialized(SCIP_BENDERS *benders)
Definition: benders.c:6133
int SCIPbendersGetNCutsFound(SCIP_BENDERS *benders)
Definition: benders.c:6061
SCIP_Bool SCIPbendersShareAuxVars(SCIP_BENDERS *benders)
Definition: benders.c:6173
SCIP_RETCODE SCIPbendersSetBenderscutPriority(SCIP_BENDERS *benders, SCIP_BENDERSCUT *benderscut, int priority)
Definition: benders.c:7146
SCIP_Bool SCIPbendersSubproblemIsIndependent(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:6759
SCIP_RETCODE SCIPsolveBendersSubproblems(SCIP *scip, SCIP_BENDERS *benders, SCIP_SOL *sol, SCIP_RESULT *result, SCIP_Bool *infeasible, SCIP_Bool *auxviol, SCIP_BENDERSENFOTYPE type, SCIP_Bool checkint)
Definition: scip_benders.c:647
SCIP_BENDERSCUT ** SCIPbendersGetBenderscuts(SCIP_BENDERS *benders)
Definition: benders.c:7119
SCIP_VAR * SCIPbenderGetMasterAuxiliaryVar(SCIP_BENDERS *benders)
Definition: benders.c:6221
SCIP_Real SCIPbendersGetSubproblemObjval(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:6320
void SCIPbendersSetSubproblemIsIndependent(SCIP_BENDERS *benders, int probnumber, SCIP_Bool isindep)
Definition: benders.c:6719
SCIP_Bool SCIPbendersInStrengthenRound(SCIP_BENDERS *benders)
Definition: benders.c:6568
SCIP_Bool SCIPbendersSubproblemIsSetup(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:6707
SCIP_Real SCIPbendersGetSubproblemLowerbound(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:6912
int SCIPbendersGetNSubproblemMasterVars(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:6265
SCIP_Bool SCIPbenderscutIsLPCut(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:583
const char * SCIPbenderscutGetName(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:492
SCIP_Longint SCIPbenderscutGetNFound(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:543
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:940
SCIP_RETCODE SCIPsetConsRemovable(SCIP *scip, SCIP_CONS *cons, SCIP_Bool removable)
Definition: scip_cons.c:1474
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1173
SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1138
SCIP_RETCODE SCIPsetEventhdlrInitsol(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTINITSOL((*eventinitsol)))
Definition: scip_event.c:199
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: scip_event.c:111
SCIP_EVENTHDLR * SCIPfindEventhdlr(SCIP *scip, const char *name)
Definition: scip_event.c:241
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:396
SCIP_EVENTHDLRDATA * SCIPeventhdlrGetData(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:406
SCIP_RETCODE SCIPsetEventhdlrExitsol(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXITSOL((*eventexitsol)))
Definition: scip_event.c:213
void SCIPeventhdlrSetData(SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: event.c:416
SCIP_RETCODE SCIPsetEventhdlrFree(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTFREE((*eventfree)))
Definition: scip_event.c:157
SCIP_RETCODE SCIPsetEventhdlrExit(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_DECL_EVENTEXIT((*eventexit)))
Definition: scip_event.c:185
SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip_event.c:293
SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip_event.c:333
SCIP_RETCODE SCIPevalExprActivity(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1742
SCIP_RETCODE SCIPcomputeLPRelIntPoint(SCIP *scip, SCIP_Bool relaxrows, SCIP_Bool inclobjcutoff, SCIP_Real timelimit, int iterlimit, SCIP_SOL **point)
Definition: scip_lp.c:1103
#define SCIPallocClearBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:97
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:105
SCIP_RETCODE SCIPsolveNLPParam(SCIP *scip, SCIP_NLPPARAM param)
Definition: scip_nlp.c:545
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:346
SCIP_RETCODE SCIPchgVarObjProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_probing.c:475
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:825
SCIP_RETCODE SCIPcreateEmptyRowConshdlr(SCIP *scip, SCIP_ROW **row, SCIP_CONSHDLR *conshdlr, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
Definition: scip_lp.c:1367
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition: scip_lp.c:1646
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:514
SCIP_RETCODE SCIPcreateSolCopy(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol)
Definition: scip_sol.c:882
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition: scip_sol.c:2351
SCIP_RETCODE SCIPcreateCurrentSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:747
SCIP_RETCODE SCIPcreateNLPSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:662
SCIP_RETCODE SCIPcreateLPSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:606
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition: scip_sol.c:1569
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1763
SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:2003
SCIP_Real SCIPretransformObj(SCIP *scip, SCIP_Real obj)
Definition: scip_sol.c:2134
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
Definition: scip_solvingstats.c:503
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip_numerics.c:475
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip_numerics.c:436
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip_numerics.c:449
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:18365
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:5697
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:5875
SCIP_RETCODE SCIPchgVarImplType(SCIP *scip, SCIP_VAR *var, SCIP_IMPLINTTYPE impltype, SCIP_Bool *infeasible)
Definition: scip_var.c:10218
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:5118
SCIP_RETCODE SCIPcreateVarImpl(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_IMPLINTTYPE impltype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip_var.c:225
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:10113
SCIP_RETCODE SCIPcreateVarBasic(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype)
Definition: scip_var.c:184
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:5372
void SCIPsortPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
internal methods for LP management
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:458
void SCIPmessagePrintVerbInfo(SCIP_MESSAGEHDLR *messagehdlr, SCIP_VERBLEVEL verblevel, SCIP_VERBLEVEL msgverblevel, const char *formatstr,...)
Definition: message.c:678
SCIP_Real SCIPconsGetLhs(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
Definition: misc_linear.c:112
SCIP_RETCODE SCIPconsAddCoef(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: misc_linear.c:675
SCIP_Real SCIPconsGetRhs(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
Definition: misc_linear.c:48
Definition: multiprecision.hpp:66
internal methods for handling parameter settings
internal methods for storing priced variables
internal methods for storing and manipulating the main problem
public methods for Benders' decomposition
public methods for message output
public data structures and miscellaneous methods
SCIP callable library.
default SCIP plugins
SCIP_RETCODE SCIPsetAddIntParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: set.c:3235
SCIP_RETCODE SCIPsetAddCharParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, char *valueptr, SCIP_Bool isadvanced, char defaultvalue, const char *allowedvalues, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: set.c:3307
SCIP_RETCODE SCIPsetAddBoolParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: set.c:3213
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6583
SCIP_RETCODE SCIPsetAddRealParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: set.c:3283
SCIP_BENDERS * SCIPsetFindBenders(SCIP_SET *set, const char *name)
Definition: set.c:4061
SCIP_RETCODE SCIPsetGetRealParam(SCIP_SET *set, const char *name, SCIP_Real *value)
Definition: set.c:3416
SCIP_Bool SCIPsetIsGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6603
SCIP_EVENTHDLR * SCIPsetFindEventhdlr(SCIP_SET *set, const char *name)
Definition: set.c:5017
internal methods for global SCIP settings
SCIP_RETCODE SCIPbendersGetVar(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_VAR *var, SCIP_VAR **mappedvar, int probnumber)
Definition: benders.c:5784
void SCIPbendersSetSolvesubconvex(SCIP_BENDERS *benders, SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex)))
Definition: benders.c:5930
static void createSolveSubproblemIndexList(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_BENDERSENFOTYPE type, int **solveidx, int *nsolveidx)
Definition: benders.c:3355
SCIP_Bool SCIPbendersSubproblemIsOptimal(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, int probnumber)
Definition: benders.c:5389
void SCIPbendersSetPresubsolve(SCIP_BENDERS *benders, SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve)))
Definition: benders.c:5919
void SCIPbendersSetObjectiveType(SCIP_BENDERS *benders, SCIP_BENDERSOBJTYPE objectivetype)
Definition: benders.c:6860
SCIP_RETCODE SCIPbendersActivate(SCIP_BENDERS *benders, SCIP_SET *set, int nsubproblems)
Definition: benders.c:2808
SCIP_RETCODE SCIPbendersComputeSubproblemLowerbound(SCIP_BENDERS *benders, SCIP_SET *set, int probnumber, SCIP_Real *lowerbound, SCIP_Bool *infeasible)
Definition: benders.c:5439
void SCIPbendersRemoveSubproblems(SCIP_BENDERS *benders)
Definition: benders.c:6209
static SCIP_RETCODE executeUserDefinedSolvesub(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, int probnumber, SCIP_BENDERSSOLVELOOP solveloop, SCIP_Bool *infeasible, SCIP_Real *objective, SCIP_RESULT *result)
Definition: benders.c:4419
static SCIP_RETCODE initsolEventhandler(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTTYPE eventtype)
Definition: benders.c:134
static SCIP_RETCODE storeSubproblemMasterVars(SCIP_BENDERS *benders, SCIP_SET *set, int probnumber)
Definition: benders.c:1517
static SCIP_RETCODE performInteriorSolCutStrengthening(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, SCIP_BENDERSENFOTYPE type, SCIP_Bool checkint, SCIP_Bool perturbsol, SCIP_Bool *auxviol, SCIP_Bool *infeasible, SCIP_Bool *skipsolve, SCIP_RESULT *result)
Definition: benders.c:3160
void SCIPbendersSetExit(SCIP_BENDERS *benders, SCIP_DECL_BENDERSEXIT((*bendersexit)))
Definition: benders.c:5864
SCIP_RETCODE SCIPbendersFreeSubproblem(SCIP_BENDERS *benders, SCIP_SET *set, int probnumber)
Definition: benders.c:5339
void SCIPbendersSetPriority(SCIP_BENDERS *benders, SCIP_SET *set, int priority)
Definition: benders.c:6015
static SCIP_Bool subproblemIsActive(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:3344
static SCIP_RETCODE addSlackVars(SCIP *scip, SCIP_BENDERS *benders, SCIP_CONS *cons, SCIP_CONSHDLR **linearconshdlrs, SCIP_CONSHDLR *nlconshdlr, int nlinearconshdlrs)
Definition: benders.c:1555
SCIP_RETCODE SCIPbendersExit(SCIP_BENDERS *benders, SCIP_SET *set)
Definition: benders.c:2469
void SCIPbendersSetInitsol(SCIP_BENDERS *benders, SCIP_DECL_BENDERSINITSOL((*bendersinitsol)))
Definition: benders.c:5897
static SCIP_DECL_EVENTINITSOL(eventInitsolBendersNodefocus)
Definition: benders.c:247
SCIP_RETCODE SCIPbendersChgMastervarsToCont(SCIP_BENDERS *benders, SCIP_SET *set, int probnumber)
Definition: benders.c:6606
void SCIPbendersSortBenderscuts(SCIP_BENDERS *benders)
Definition: benders.c:7162
SCIP_RETCODE SCIPbendersSetupSubproblem(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, int probnumber, SCIP_BENDERSENFOTYPE type)
Definition: benders.c:4659
static SCIP_RETCODE setAndUpdateCorePoint(SCIP *scip, SCIP_BENDERS *benders)
Definition: benders.c:3074
static SCIP_RETCODE createSubproblems(SCIP_BENDERS *benders, SCIP_SET *set)
Definition: benders.c:2018
SCIP_RETCODE SCIPbendersSetMastervarsCont(SCIP_BENDERS *benders, int probnumber, SCIP_Bool arecont)
Definition: benders.c:6811
static SCIP_RETCODE freeEventhandler(SCIP *scip, SCIP_EVENTHDLR *eventhdlr)
Definition: benders.c:198
void SCIPbendersSetSolvesub(SCIP_BENDERS *benders, SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub)))
Definition: benders.c:5941
void SCIPbendersSetSubproblemsAreInfeasible(SCIP_BENDERS *benders, SCIP_SET *set)
Definition: benders.c:6580
void SCIPbendersSetExitsol(SCIP_BENDERS *benders, SCIP_DECL_BENDERSEXITSOL((*bendersexitsol)))
Definition: benders.c:5908
void SCIPbendersSortBenderscutsName(SCIP_BENDERS *benders)
Definition: benders.c:7177
static SCIP_RETCODE resetOrigSubproblemParams(SCIP *subproblem, SCIP_SUBPROBPARAMS *origparams)
Definition: benders.c:5039
SCIP_RETCODE SCIPbendersCreate(SCIP_BENDERS **benders, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int priority, SCIP_Bool cutlp, SCIP_Bool cutpseudo, SCIP_Bool cutrelax, SCIP_Bool shareauxvars, SCIP_DECL_BENDERSCOPY((*benderscopy)), SCIP_DECL_BENDERSFREE((*bendersfree)), SCIP_DECL_BENDERSINIT((*bendersinit)), SCIP_DECL_BENDERSEXIT((*bendersexit)), SCIP_DECL_BENDERSINITPRE((*bendersinitpre)), SCIP_DECL_BENDERSEXITPRE((*bendersexitpre)), SCIP_DECL_BENDERSINITSOL((*bendersinitsol)), SCIP_DECL_BENDERSEXITSOL((*bendersexitsol)), SCIP_DECL_BENDERSGETVAR((*bendersgetvar)), SCIP_DECL_BENDERSCREATESUB((*benderscreatesub)), SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve)), SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex)), SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub)), SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve)), SCIP_DECL_BENDERSFREESUB((*bendersfreesub)), SCIP_BENDERSDATA *bendersdata)
Definition: benders.c:1356
static SCIP_RETCODE addSlackVarsToConstraints(SCIP_BENDERS *benders, SCIP_SET *set, int probnumber)
Definition: benders.c:1667
static SCIP_RETCODE updateAuxiliaryVarLowerbound(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_RESULT *result)
Definition: benders.c:3017
static SCIP_RETCODE exitEventhandler(SCIP *scip, SCIP_EVENTHDLR *eventhdlr)
Definition: benders.c:178
static SCIP_RETCODE solveBendersSubproblems(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, SCIP_BENDERSENFOTYPE type, SCIP_BENDERSSOLVELOOP solveloop, SCIP_Bool checkint, int *nverified, int *solveidx, int nsolveidx, SCIP_Bool **subprobsolved, SCIP_BENDERSSUBSTATUS **substatus, SCIP_Bool *infeasible, SCIP_Bool *optimal, SCIP_Bool *stopped)
Definition: benders.c:3444
static SCIP_RETCODE storeSubproblemMasterVar(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_VAR *var, int probnumber)
Definition: benders.c:1479
SCIP_RETCODE SCIPbendersCopyInclude(SCIP_BENDERS *benders, SCIP_SET *sourceset, SCIP_SET *targetset, SCIP_HASHMAP *varmap, SCIP_Bool threadsafe, SCIP_Bool *valid)
Definition: benders.c:1073
static SCIP_RETCODE createAndAddTransferredCut(SCIP *sourcescip, SCIP_BENDERS *benders, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, int nvars)
Definition: benders.c:2305
SCIP_RETCODE SCIPbendersMergeSubproblemIntoMaster(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, int probnumber)
Definition: benders.c:5601
static SCIP_RETCODE doBendersCreate(SCIP_BENDERS **benders, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int priority, SCIP_Bool cutlp, SCIP_Bool cutpseudo, SCIP_Bool cutrelax, SCIP_Bool shareauxvars, SCIP_DECL_BENDERSCOPY((*benderscopy)), SCIP_DECL_BENDERSFREE((*bendersfree)), SCIP_DECL_BENDERSINIT((*bendersinit)), SCIP_DECL_BENDERSEXIT((*bendersexit)), SCIP_DECL_BENDERSINITPRE((*bendersinitpre)), SCIP_DECL_BENDERSEXITPRE((*bendersexitpre)), SCIP_DECL_BENDERSINITSOL((*bendersinitsol)), SCIP_DECL_BENDERSEXITSOL((*bendersexitsol)), SCIP_DECL_BENDERSGETVAR((*bendersgetvar)), SCIP_DECL_BENDERSCREATESUB((*benderscreatesub)), SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve)), SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex)), SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub)), SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve)), SCIP_DECL_BENDERSFREESUB((*bendersfreesub)), SCIP_BENDERSDATA *bendersdata)
Definition: benders.c:1144
static SCIP_DECL_EVENTEXITSOL(eventExitsolBendersNodefocus)
Definition: benders.c:261
static SCIP_RETCODE initialiseSubproblem(SCIP_BENDERS *benders, SCIP_SET *set, int probnumber, SCIP_Bool *infeasible, SCIP_Bool *success)
Definition: benders.c:1717
static SCIP_RETCODE copyMemoryAndTimeLimits(SCIP *scip, SCIP *subproblem)
Definition: benders.c:4928
static SCIP_RETCODE transferBendersCuts(SCIP *sourcescip, SCIP *subscip, SCIP_BENDERS *benders)
Definition: benders.c:2423
void SCIPbendersSetBenderscutsSorted(SCIP_BENDERS *benders, SCIP_Bool sorted)
Definition: benders.c:7061
static SCIP_RETCODE assignAuxiliaryVariables(SCIP *scip, SCIP_BENDERS *benders)
Definition: benders.c:908
SCIP_RETCODE SCIPbendersFree(SCIP_BENDERS **benders, SCIP_SET *set)
Definition: benders.c:1435
void SCIPbendersSetSubproblemComp(SCIP_BENDERS *benders, SCIP_DECL_SORTPTRCOMP((*benderssubcomp)))
Definition: benders.c:5963
SCIP_RETCODE SCIPbendersInitsol(SCIP_BENDERS *benders, SCIP_SET *set)
Definition: benders.c:2719
SCIP_RETCODE SCIPbendersExecSubproblemSolve(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, int probnumber, SCIP_BENDERSSOLVELOOP solveloop, SCIP_Bool enhancement, SCIP_Bool *solved, SCIP_Bool *infeasible, SCIP_BENDERSENFOTYPE type)
Definition: benders.c:4490
void SCIPbendersSetFreesub(SCIP_BENDERS *benders, SCIP_DECL_BENDERSFREESUB((*bendersfreesub)))
Definition: benders.c:5974
static SCIP_RETCODE releaseVarMappingHashmapVars(SCIP *scip, SCIP_BENDERS *benders)
Definition: benders.c:1401
static SCIP_RETCODE addAuxiliaryVariablesToMaster(SCIP *scip, SCIP_BENDERS *benders)
Definition: benders.c:691
static SCIP_RETCODE setSubproblemParams(SCIP *scip, SCIP *subproblem)
Definition: benders.c:4988
void SCIPbendersSetInit(SCIP_BENDERS *benders, SCIP_DECL_BENDERSINIT((*bendersinit)))
Definition: benders.c:5853
SCIP_RETCODE SCIPbendersDeactivate(SCIP_BENDERS *benders, SCIP_SET *set)
Definition: benders.c:2908
SCIP_RETCODE SCIPbendersStoreCut(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, int nvars)
Definition: benders.c:7013
void SCIPbendersSetCopy(SCIP_BENDERS *benders, SCIP_DECL_BENDERSCOPY((*benderscopy)))
Definition: benders.c:5831
SCIP_RETCODE SCIPbendersAddSubproblem(SCIP_BENDERS *benders, SCIP *subproblem)
Definition: benders.c:6185
SCIP_Real SCIPbendersGetAuxiliaryVarVal(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, int probnumber)
Definition: benders.c:5418
SCIP_RETCODE SCIPbendersExec(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, SCIP_RESULT *result, SCIP_Bool *infeasible, SCIP_Bool *auxviol, SCIP_BENDERSENFOTYPE type, SCIP_Bool checkint)
Definition: benders.c:3882
SCIP_Bool SCIPbendersGetMastervarsCont(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:6846
static SCIP_RETCODE exitsolEventhandler(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTTYPE eventtype)
Definition: benders.c:154
void SCIPbendersSetFree(SCIP_BENDERS *benders, SCIP_DECL_BENDERSFREE((*bendersfree)))
Definition: benders.c:5842
static SCIP_RETCODE updateEventhdlrUpperbound(SCIP_BENDERS *benders, int probnumber, SCIP_Real upperbound)
Definition: benders.c:472
static SCIP_RETCODE storeOrigSubproblemParams(SCIP *subproblem, SCIP_SUBPROBPARAMS *origparams)
Definition: benders.c:4961
SCIP_RETCODE SCIPbendersInitpre(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_STAT *stat)
Definition: benders.c:2635
void SCIPbendersEnableOrDisableClocks(SCIP_BENDERS *benders, SCIP_Bool enable)
Definition: benders.c:6121
void SCIPbendersSetExitpre(SCIP_BENDERS *benders, SCIP_DECL_BENDERSEXITPRE((*bendersexitpre)))
Definition: benders.c:5886
static void findAuxiliaryVar(SCIP *scip, SCIP_BENDERS *benders, SCIP_VAR **targetvar, int subscipdepth, int probnumber)
Definition: benders.c:858
static SCIP_RETCODE updateSubproblemStatQueue(SCIP_BENDERS *benders, int *solveidx, int nsolveidx, SCIP_Bool updatestat)
Definition: benders.c:3395
static SCIP_RETCODE checkSubproblemConvexity(SCIP_BENDERS *benders, SCIP_SET *set, int probnumber)
Definition: benders.c:1810
static SCIP_RETCODE updateSubproblemLowerbound(SCIP *masterprob, SCIP_BENDERS *benders)
Definition: benders.c:501
static SCIP_RETCODE generateBendersCuts(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, SCIP_RESULT *result, SCIP_BENDERSENFOTYPE type, SCIP_BENDERSSOLVELOOP solveloop, SCIP_Bool checkint, SCIP_Bool *subprobsolved, SCIP_BENDERSSUBSTATUS *substatus, int *solveidx, int nsolveidx, int *mergecands, int *npriomergecands, int *nmergecands, int *nsolveloops)
Definition: benders.c:3684
static SCIP_RETCODE initEventhandlerData(SCIP *scip, SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: benders.c:116
void SCIPbendersSetInitpre(SCIP_BENDERS *benders, SCIP_DECL_BENDERSINITPRE((*bendersinitpre)))
Definition: benders.c:5875
void SCIPbendersSetSubproblemEnabled(SCIP_BENDERS *benders, int probnumber, SCIP_Bool enabled)
Definition: benders.c:6773
void SCIPbendersSetPostsolve(SCIP_BENDERS *benders, SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve)))
Definition: benders.c:5952
SCIP_RETCODE SCIPbendersIncludeBenderscut(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_BENDERSCUT *benderscut)
Definition: benders.c:7073
SCIP_RETCODE SCIPbendersExitpre(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_STAT *stat)
Definition: benders.c:2693
static int numSubproblemsToCheck(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_BENDERSENFOTYPE type)
Definition: benders.c:3329
SCIP_RETCODE SCIPbendersExitsol(SCIP_BENDERS *benders, SCIP_SET *set)
Definition: benders.c:2752
SCIP_RETCODE SCIPbendersSolveSubproblem(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, int probnumber, SCIP_Bool *infeasible, SCIP_Bool solvecip, SCIP_Real *objective)
Definition: benders.c:4819
static void resetSubproblemObjectiveValue(SCIP_BENDERS *benders, SCIP_SET *set)
Definition: benders.c:978
static SCIP_RETCODE initialiseLPSubproblem(SCIP_BENDERS *benders, SCIP_SET *set, int probnumber, SCIP_Bool *infeasible)
Definition: benders.c:1760
static SCIP_RETCODE createMasterVarMapping(SCIP_BENDERS *benders, SCIP_SET *sourceset, SCIP_HASHMAP *varmap)
Definition: benders.c:1033
static SCIP_RETCODE checkSubproblemIndependence(SCIP *scip, SCIP_BENDERS *benders)
Definition: benders.c:2581
SCIP_RETCODE SCIPbendersInit(SCIP_BENDERS *benders, SCIP_SET *set)
Definition: benders.c:2225
internal methods for Benders' decomposition
Definition: struct_benders.h:58
SCIP_Bool benderscutsnamessorted
Definition: struct_benders.h:185
Definition: struct_benders.h:47
Definition: struct_benderscut.h:47
Definition: struct_cons.h:47
Definition: struct_cons.h:128
Definition: struct_event.h:218
Definition: struct_misc.h:132
Definition: struct_misc.h:139
Definition: struct_message.h:46
Definition: type_nlpi.h:67
Definition: struct_lp.h:205
Definition: struct_set.h:75
Definition: struct_sol.h:74
Definition: struct_stat.h:62
Definition: struct_benders.h:204
Definition: struct_benders.h:195
Definition: struct_var.h:262
Definition: struct_scip.h:72
data structures required for Benders' decomposition
datastructures for Benders' decomposition cuts techniques
Definition: heur_padm.c:132
#define SCIP_DECL_BENDERSSOLVESUBCONVEX(x)
Definition: type_benders.h:271