benders.c
Go to the documentation of this file.
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
53 #define SCIP_DEFAULT_TRANSFERCUTS FALSE /** should Benders' cuts generated in LNS heuristics be transferred to the main SCIP instance? */
54 #define SCIP_DEFAULT_CUTSASCONSS TRUE /** should the transferred cuts be added as constraints? */
55 #define SCIP_DEFAULT_LNSCHECK TRUE /** should the Benders' decomposition be used in LNS heuristics */
57 #define SCIP_DEFAULT_LNSMAXCALLS 10 /** the maximum number of Benders' decomposition calls in LNS heuristics */
58 #define SCIP_DEFAULT_LNSMAXCALLSROOT 0 /** the maximum number of root node Benders' decomposition calls in LNS heuristics */
59 #define SCIP_DEFAULT_SUBPROBFRAC 1.0 /** fraction of subproblems that are solved in each iteration */
60 #define SCIP_DEFAULT_UPDATEAUXVARBOUND FALSE /** should the auxiliary variable lower bound be updated by solving the subproblem */
61 #define SCIP_DEFAULT_AUXVARSIMPLINT FALSE /** set the auxiliary variables as implint if the subproblem objective is integer */
62 #define SCIP_DEFAULT_CUTCHECK TRUE /** should cuts be generated during the checking of solutions? */
63 #define SCIP_DEFAULT_STRENGTHENMULT 0.5 /** the convex combination multiplier for the cut strengthening */
64 #define SCIP_DEFAULT_NOIMPROVELIMIT 5 /** the maximum number of cut strengthening without improvement */
65 #define SCIP_DEFAULT_STRENGTHENPERTURB 1e-06 /** the amount by which the cut strengthening solution is perturbed */
66 #define SCIP_DEFAULT_STRENGTHENENABLED FALSE /** enable the core point cut strengthening approach */
67 #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) */
68 #define SCIP_DEFAULT_NUMTHREADS 1 /** the number of parallel threads to use when solving the subproblems */
69 #define SCIP_DEFAULT_EXECFEASPHASE FALSE /** should a feasibility phase be executed during the root node processing */
70 #define SCIP_DEFAULT_SLACKVARCOEF 1e+6 /** the objective coefficient of the slack variables in the subproblem */
71 #define SCIP_DEFAULT_CHECKCONSCONVEXITY TRUE /** should the constraints of the subproblem be checked for convexity? */
73 #define BENDERS_MAXPSEUDOSOLS 5 /** the maximum number of pseudo solutions checked before suggesting
78 #define AUXILIARYVAR_NAME "##bendersauxiliaryvar" /** the name for the Benders' auxiliary variables in the master problem */
79 #define SLACKVAR_NAME "##bendersslackvar" /** the name for the Benders' slack variables added to each
88 #define MIPNODEFOCUS_EVENTHDLR_DESC "node focus event handler for the MIP solve method for Benders' decomposition"
91 #define UPPERBOUND_EVENTHDLR_DESC "found solution event handler to terminate subproblem solve for a given upper bound"
229 /* sending an interrupt solve signal to return the control back to the Benders' decomposition plugin.
233 SCIP_CALL(SCIPdropEvent(scip, SCIP_EVENTTYPE_NODEFOCUSED, eventhdlr, NULL, eventhdlrdata->filterpos));
239 /** solving process initialization method of event handler (called when branch and bound process is about to begin) */
252 /** solving process deinitialization method of event handler (called before branch and bound process data is freed) */
312 SCIP_CALL(SCIPdropEvent(scip, SCIP_EVENTTYPE_NODEFOCUSED, eventhdlr, NULL, eventhdlrdata->filterpos));
320 /** solving process initialization method of event handler (called when branch and bound process is about to begin) */
333 /** solving process deinitialization method of event handler (called before branch and bound process data is freed) */
390 if( SCIPisLT(scip, SCIPgetSolOrigObj(scip, bestsol)*(int)SCIPgetObjsense(scip), eventhdlrdata->upperbound) )
398 /** solving process initialization method of event handler (called when branch and bound process is about to begin) */
411 /** solving process deinitialization method of event handler (called before branch and bound process data is freed) */
464 eventhdlr = SCIPfindEventhdlr(SCIPbendersSubproblem(benders, probnumber), UPPERBOUND_EVENTHDLR_NAME);
478 * This function solves the master problem with only the auxiliary variables in the objective function.
569 /** solving process initialization method of event handler (called when branch and bound process is about to begin) */
582 /* The event is only caught if there is an active Benders' decomposition, the integer subproblem are solved and
585 if( SCIPbendersIsActive(benders) && !SCIPbendersOnlyCheckConvexRelax(benders, SCIPgetSubscipsOff(scip))
595 /* ---------------- Methods for the parallelisation of Benders' decomposition ---------------- */
681 /* this is a workaround for GCG. GCG expects that the variable has vardata when added. So a dummy vardata is created */
688 /* if the current Benders is the highest priority Benders, then we need to create the auxiliary variables.
689 * Otherwise, if the shareauxvars flag is set, then the auxiliary variables from the highest priority Benders' are
697 /* if the auxiliary variables are shared, then a pointer to the variable is retrieved from topbenders,
709 /* set the variable type of the auxiliary variables to implied integer if the objective function of the
710 * subproblem is guaranteed to be integer. This behaviour is controlled through a user parameter.
711 * NOTE: It is only possible to determine if the objective function is integral if the subproblem is defined as
720 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "%s_%d_%s", AUXILIARYVAR_NAME, i, SCIPbendersGetName(benders) );
721 SCIP_CALL( SCIPcreateVarBasic(scip, &auxiliaryvar, varname, benders->subproblowerbound[i], SCIPinfinity(scip),
740 /** assigns the copied auxiliary variables in the target SCIP to the target Benders' decomposition data */
759 /* this is a workaround for GCG. GCG expects that the variable has vardata when added. So a dummy vardata is created */
766 /* if the auxiliary variable are shared, then the variable name will have a suffix of the highest priority Benders'
783 /* the prefix for the variable names is required for UG, since we don't know how many copies have been made. To
784 * find the target variable, we start with an empty prefix. Then t_ is prepended until the target variable is
791 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "%s%s_%d_%s", prefix, AUXILIARYVAR_NAME, i, SCIPbendersGetName(topbenders));
793 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "%s%s_%d_%s", prefix, AUXILIARYVAR_NAME, i, SCIPbendersGetName(benders));
795 /* finding the variable in the copied problem that has the same name as the auxiliary variable */
861 return strcmp(SCIPbendersGetName((SCIP_BENDERS*)elem1), SCIPbendersGetName((SCIP_BENDERS*)elem2));
879 /** creates a variable mapping between the master problem variables of the source scip and the sub scip */
902 /* creating the hashmap for the mapping between the master variable of the target and source scip */
907 /* getting the variable pointer for the target SCIP variables. The variable mapping returns the target SCIP
931 SCIP_BENDERS* targetbenders; /* the copy of the Benders' decomposition struct in the target set */
941 if( benders->benderscopy != NULL && targetset->benders_copybenders && SCIPbendersIsActive(benders) )
943 SCIPsetDebugMsg(targetset, "including Benders' decomposition %s in subscip %p\n", SCIPbendersGetName(benders), (void*)targetset->scip);
971 /* When the Benders' decomposition is copied then a variable mapping between the master problem variables is
972 * required. This variable mapping is used to transfer the cuts generated in the target SCIP to the source SCIP.
973 * The variable map is stored in the target Benders' decomposition. This will be freed when the sub-SCIP is freed.
1004 SCIP_DECL_BENDERSCOPY ((*benderscopy)), /**< copy method of Benders' decomposition or NULL if you don't want to copy your plugin into sub-SCIPs */
1008 SCIP_DECL_BENDERSINITPRE((*bendersinitpre)),/**< presolving initialization method for Benders' decomposition */
1009 SCIP_DECL_BENDERSEXITPRE((*bendersexitpre)),/**< presolving deinitialization method for Benders' decomposition */
1010 SCIP_DECL_BENDERSINITSOL((*bendersinitsol)),/**< solving process initialization method of Benders' decomposition */
1011 SCIP_DECL_BENDERSEXITSOL((*bendersexitsol)),/**< solving process deinitialization method of Benders' decomposition */
1012 SCIP_DECL_BENDERSGETVAR((*bendersgetvar)),/**< returns the master variable for a given subproblem variable */
1013 SCIP_DECL_BENDERSCREATESUB((*benderscreatesub)),/**< creates a Benders' decomposition subproblem */
1014 SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve)),/**< called prior to the subproblem solving loop */
1015 SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex)),/**< the solving method for convex Benders' decomposition subproblems */
1016 SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub)),/**< the solving method for the Benders' decomposition subproblems */
1017 SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve)),/**< called after the subproblems are solved. */
1018 SCIP_DECL_BENDERSFREESUB((*bendersfreesub)),/**< the freeing method for the Benders' decomposition subproblems */
1029 /* Checking whether the benderssolvesub and the bendersfreesub are both implemented or both are not implemented */
1033 SCIPerrorMessage("Benders' decomposition <%s> requires that if bendersFreesub%s is implemented, then at least "
1034 "one of bendersSolvesubconvex%s or bendersSolvesub%s are implemented.\n", name, name, name, name);
1068 (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of Benders' decomposition <%s>", name);
1075 "should Benders' cuts be generated for LP solutions?", &(*benders)->cutlp, FALSE, cutlp, NULL, NULL) ); /*lint !e740*/
1079 "should Benders' cuts be generated for pseudo solutions?", &(*benders)->cutpseudo, FALSE, cutpseudo, NULL, NULL) ); /*lint !e740*/
1083 "should Benders' cuts be generated for relaxation solutions?", &(*benders)->cutrelax, FALSE, cutrelax, NULL, NULL) ); /*lint !e740*/
1085 /* These parameters are left for the user to decide in a settings file. This departs from the usual SCIP convention
1090 "should Benders' cuts from LNS heuristics be transferred to the main SCIP instance?", &(*benders)->transfercuts,
1095 "should Benders' decomposition be used in LNS heurisics?", &(*benders)->lnscheck, FALSE, SCIP_DEFAULT_LNSCHECK,
1100 "maximum depth at which the LNS check is performed (-1: no limit)", &(*benders)->lnsmaxdepth, TRUE,
1105 "the maximum number of Benders' decomposition calls in LNS heuristics (-1: no limit)", &(*benders)->lnsmaxcalls,
1110 "the maximum number of root node Benders' decomposition calls in LNS heuristics (-1: no limit)",
1125 "should the auxiliary variable bound be updated by solving the subproblem?", &(*benders)->updateauxvarbound,
1130 "if the subproblem objective is integer, then define the auxiliary variables as implied integers?",
1145 "the maximum number of cut strengthening without improvement", &(*benders)->noimprovelimit, TRUE,
1150 "the constant use to perturb the cut strengthening core point", &(*benders)->perturbeps, FALSE,
1155 "should the core point cut strengthening be employed (only applied to fractional solutions or continuous subproblems)?",
1156 &(*benders)->strengthenenabled, FALSE, SCIP_DEFAULT_STRENGTHENENABLED, NULL, NULL) ); /*lint !e740*/
1160 "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)",
1161 &(*benders)->strengthenintpoint, FALSE, SCIP_DEFAULT_STRENGTHENINTPOINT, "lfiroz", NULL, NULL) ); /*lint !e740*/
1170 "should a feasibility phase be executed during the root node, i.e. adding slack variables to constraints to ensure feasibility",
1175 "the objective coefficient of the slack variables in the subproblem", &(*benders)->slackvarcoef, FALSE,
1180 "should the constraints of the subproblems be checked for convexity?", &(*benders)->checkconsconvexity, FALSE,
1188 * To use the Benders' decomposition for solving a problem, it first has to be activated with a call to SCIPactivateBenders().
1202 SCIP_DECL_BENDERSCOPY ((*benderscopy)), /**< copy method of Benders' decomposition or NULL if you don't want to copy your plugin into sub-SCIPs */
1206 SCIP_DECL_BENDERSINITPRE((*bendersinitpre)),/**< presolving initialization method for Benders' decomposition */
1207 SCIP_DECL_BENDERSEXITPRE((*bendersexitpre)),/**< presolving deinitialization method for Benders' decomposition */
1208 SCIP_DECL_BENDERSINITSOL((*bendersinitsol)),/**< solving process initialization method of Benders' decomposition */
1209 SCIP_DECL_BENDERSEXITSOL((*bendersexitsol)),/**< solving process deinitialization method of Benders' decomposition */
1210 SCIP_DECL_BENDERSGETVAR((*bendersgetvar)),/**< returns the master variable for a given subproblem variable */
1211 SCIP_DECL_BENDERSCREATESUB((*benderscreatesub)),/**< creates a Benders' decomposition subproblem */
1212 SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve)),/**< called prior to the subproblem solving loop */
1213 SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex)),/**< the solving method for convex Benders' decomposition subproblems */
1214 SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub)),/**< the solving method for the Benders' decomposition subproblems */
1215 SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve)),/**< called after the subproblems are solved. */
1216 SCIP_DECL_BENDERSFREESUB((*bendersfreesub)),/**< the freeing method for the Benders' decomposition subproblems */
1224 SCIP_CALL_FINALLY( doBendersCreate(benders, set, messagehdlr, blkmem, name, desc, priority, cutlp, cutpseudo,
1225 cutrelax, shareauxvars, benderscopy, bendersfree, bendersinit, bendersexit, bendersinitpre, bendersexitpre,
1226 bendersinitsol, bendersexitsol, bendersgetvar, benderscreatesub, benderspresubsolve, benderssolvesubconvex,
1227 benderssolvesub, benderspostsolve, bendersfreesub, bendersdata), (void) SCIPbendersFree(benders, set) );
1287 /* if the Benders' decomposition is a copy and a varmap has been passed to SCIP_BENDERS, then the variable map
1340 /* checking whether the constraint is a linear constraint. If so, we add a coefficient to the constraint */
1351 && (conshdlr != conshdlr_nonlinear && conshdlr != conshdlr_quadratic && conshdlr != conshdlr_abspower) )
1354 "This is not supported and the slack variable will not be added to the constraint. Feasibility cuts may be invalid.\n",
1376 /* if the right hand side is finite, then we need to add a slack variable with a negative coefficient */
1381 SCIP_CALL( SCIPcreateVarBasic(scip, &var, name, 0.0, SCIPinfinity(scip), objcoef, SCIP_VARTYPE_CONTINUOUS) );
1400 /* if the left hand side if finite, then we need to add a slack variable with a positive coefficient */
1405 SCIP_CALL( SCIPcreateVarBasic(scip, &var, name, 0.0, SCIPinfinity(scip), objcoef, SCIP_VARTYPE_CONTINUOUS) );
1427 /** adds the slack variables to each of the constraints for the generation of feasibility cuts for the given non-linear
1467 SCIP_CALL( addSlackVars(subproblem, benders, cons, linearconshdlrs, conshdlr_nonlinear, conshdlr_quadratic,
1474 /** initialises a MIP subproblem by putting the problem into SCIP_STAGE_SOLVING. This is achieved by calling SCIPsolve
1476 * The LP subproblem is also initialised using this method; however, a different event handler is added. This event
1478 * The MIP solving function is called to initialise the subproblem because this function calls SCIPsolve with the
1503 SCIP_CALL( SCIPbendersSolveSubproblemCIP(set->scip, benders, probnumber, &solvestatus, FALSE) );
1519 /** initialises an LP subproblem by putting the problem into probing mode. The probing mode is invoked in a node focus
1520 * event handler. This event handler is added just prior to calling the initialise subproblem function.
1545 SCIP_CALL( SCIPincludeEventhdlrBasic(subproblem, &eventhdlr, NODEFOCUS_EVENTHDLR_NAME, NODEFOCUS_EVENTHDLR_DESC,
1559 /** checks whether the convex relaxation of the subproblem is sufficient to solve the original problem to optimality
1562 * To do this, we check that all variables are of continuous type and that every constraint is either handled by known
1563 * linear constraint handler (knapsack, linear, logicor, setppc, varbound) or a known nonlinear constraint handler
1564 * (nonlinear, quadratic, abspower). In the latter case, we also check whether the nonlinear constraint is convex.
1565 * Further, nonlinear constraints are only considered if an NLP solver interface is available, i.e., and NLP could
1567 * If constraints are present that cannot be identified as linear or convex nonlinear, then we assume that the
1613 SCIP_CALL( SCIPgetVarsData(subproblem, &vars, &nvars, &nbinvars, &nintvars, &nimplintvars, NULL) );
1615 /* if there are any binary, integer or implied integer variables, then the subproblems is marked as non-convex */
1628 /* Get pointers to interesting nonlinear constraint handlers, if we also have an NLP solver to solve NLPs.
1629 * If there is no NLP solver, but there are (convex) nonlinear constraints, then the LP relaxation of subproblems
1630 * will (currently) not be sufficient to solve subproblems to optimality. Thus, we also take the presence of convex
1631 * nonlinear constraints as signal for having to solve the CIP eventually, thus, by abuse of notation,
1632 * return not-convex here. In summary, we do not need to have a special look onto non-linear constraints
1633 * if no NLP solver is present, and can treat them as any other constraint that is not of linear type.
1642 /* if the quadratic constraint handler exists, then we create a hashmap of variables that can be assumed to be fixed.
1649 SCIP_CALL( SCIPhashmapCreate(&assumevarfixed, SCIPblkmem(set->scip), SCIPgetNVars(subproblem)) );
1678 SCIPdebugMsg(subproblem, "subproblem <%s>: constraint <%s> is linear\n", SCIPgetProbName(subproblem), SCIPconsGetName(cons));
1691 if( ((SCIPisInfinity(subproblem, -SCIPgetLhsNonlinear(subproblem, cons)) || (curvature & SCIP_EXPRCURV_CONCAVE) == SCIP_EXPRCURV_CONCAVE)) &&
1692 ((SCIPisInfinity(subproblem, SCIPgetRhsNonlinear(subproblem, cons)) || (curvature & SCIP_EXPRCURV_CONVEX) == SCIP_EXPRCURV_CONVEX)) )
1695 SCIPdebugMsg(subproblem, "subproblem <%s>: nonlinear constraint <%s> is convex\n", SCIPgetProbName(subproblem), SCIPconsGetName(cons));
1702 SCIPdebugMsg(subproblem, "subproblem <%s>: nonlinear constraint <%s> is not convex\n", SCIPgetProbName(subproblem), SCIPconsGetName(cons));
1719 SCIPdebugMsg(subproblem, "subproblem <%s>: quadratic constraint <%s> is convex\n", SCIPgetProbName(subproblem), SCIPconsGetName(cons));
1726 SCIPdebugMsg(subproblem, "subproblem <%s>: quadratic constraint <%s> not convex\n", SCIPgetProbName(subproblem), SCIPconsGetName(cons));
1740 SCIPdebugMsg(subproblem, "subproblem <%s>: abspower constraint <%s> is convex\n", SCIPgetProbName(subproblem), SCIPconsGetName(cons));
1747 SCIPdebugMsg(subproblem, "subproblem <%s>: abspower constraint <%s> not convex\n", SCIPgetProbName(subproblem), SCIPconsGetName(cons));
1754 * skip soc constraints: it would depend how these are represented in the NLP eventually, which could be nonconvex
1758 SCIPdebugMsg(subproblem, "subproblem <%s>: potentially nonconvex constraint <%s>\n", SCIPgetProbName(subproblem), SCIPconsGetName(cons));
1767 /* setting the flag for the convexity of the subproblem. If convexity doesn't need to be checked, then it is assumed
1768 * that the subproblems are convex. However, if there are discrete variables, then the problem must be set as
1769 * non-convex. The discrete master variables will be changed to continuous, but this will happen at the first call to
1796 SCIPdebugMsg(subproblem, "subproblem <%s> has been found to be of type %d\n", SCIPgetProbName(subproblem),
1826 /* if the subproblems have already been created, then they will not be created again. This is the case if the
1827 * transformed problem has been freed and then retransformed. The subproblems should only be created when the problem
1842 /* the subproblem SCIP instance could be set to NULL. This is because user defined subproblem solving methods
1843 * could be used that don't solve a SCIP instance. Thus, the following setup of the subproblem SCIP instance is
1846 * NOTE: since the subproblems are supplied as NULL pointers, the internal convexity check can not be performed.
1857 /* The objective function coefficients of the master problem are set to zero. This is necessary for the Benders'
1858 * decomposition algorithm, since the cut methods and the objective function check assumes that the objective
1861 * This only occurs if the Benders' decomposition is not a copy. It is assumed that the correct objective
1864 * If the subproblems were copied, then the master variables will be checked to ensure that they have a zero
1877 /* if mastervar is not NULL, then the subproblem variable has a corresponding master problem variable */
1880 SCIPverbMessage(subproblem, SCIP_VERBLEVEL_FULL, NULL, "Benders' decomposition: Changing the objective "
1892 SCIPverbMessage(subproblem, SCIP_VERBLEVEL_HIGH, NULL, "Benders' decomposition: Objective coefficients of "
1897 /* checking the convexity of the subproblem. The convexity of the subproblem indicates whether the convex
1902 /* if the problem is convex and has nonlinear constraints, then slack variables must be added to each of the
1909 /* the slack variables are only added to the subproblem once. If the initialisation methods are called from a
1910 * copy, then the slack variables are not re-added. Alternatively, if the copy must be threadsafe, then the
1918 /* setting the flag to indicate that slack variables have been added to the subproblem constraints. This is only
1925 /* after checking the subproblem for convexity, if the subproblem has convex constraints and continuous variables,
1930 /* if the user has not implemented a solve subproblem callback, then the subproblem solves are performed
1943 /* because the subproblems could be reused in the copy, the event handler is not created again. If the
1945 * NOTE: This currently works with the benders_default implementation. It may not be very general. */
1977 /* checking the convexity of the master problem. This information is useful for the cut generation methods, such as
2025 /* if the Benders' decomposition is a copy, then the auxiliary variables already exist. So they are registered with
2026 * the Benders' decomposition struct during the init stage. If the Benders' decomposition is not a copy, then the
2035 /* creates the subproblems and sets up the probing mode for LP subproblems. This function calls the benderscreatesub
2045 SCIP_ALLOC( BMSallocBlockMemoryArray(SCIPblkmem(set->scip), &benders->storedcuts, BENDERS_ARRAYSIZE) );
2064 /** Transfers Benders' cuts that were generated while solving a sub-SCIP to the original SCIP instance. This involves
2065 * creating a constraint/cut that is equivalent to the generated cut in the sub-SCIP. This new constraint/cut is then
2080 SCIP_CONSHDLR* consbenders; /* a helper variable for the Benders' decomposition constraint handler */
2081 SCIP_CONS* transfercons = NULL; /* the constraint that is generated to transfer the constraints/cuts */
2107 * SCIPcreateConsBasicLinear/SCIPcreateEmptyRowConshdlr. This should be implemented to improve the performance of the
2114 SCIP_CALL( SCIPcreateConsBasicLinear(sourcescip, &transfercons, cutname, 0, NULL, NULL, lhs, rhs) );
2119 SCIP_CALL( SCIPcreateEmptyRowConshdlr(sourcescip, &transfercut, consbenders, cutname, lhs, rhs, FALSE,
2135 /* if the source variable is not found, then the mapping in incomplete. So the constraint can not be
2258 /* if the Benders' decomposition is a copy, then is a variable mapping was provided, then the generated cuts will
2269 SCIPfreeBlockMemoryArray(set->scip, &benders->storedcuts[i]->vals, benders->storedcuts[i]->nvars);
2270 SCIPfreeBlockMemoryArray(set->scip, &benders->storedcuts[i]->vars, benders->storedcuts[i]->nvars);
2282 /* it is possible that the master problem is not solved. As such, the auxiliary variables will not be created. So
2287 /* we need to remove the locks from the auxiliary variables. This will be called always for the highest priority
2291 SCIP_CALL( SCIPaddVarLocksType(set->scip, benders->auxiliaryvars[i], SCIP_LOCKTYPE_MODEL, -1, 0) );
2339 /* looping over all subproblems to check whether there exists at least one master problem variable */
2344 /* if there are user defined solving or freeing functions, then it is not possible to declare the independence of
2359 /* if the subporblem variable is not NULL, then the subproblem depends on the master problem */
2386 /* if the Benders' decomposition is the original, then the auxiliary variables need to be created. If the Benders'
2387 * decomposition is a copy, then the auxiliary variables already exist. The assignment of the auxiliary variables
2392 /* check the subproblem independence. This check is only performed if the user has not implemented a solve
2490 /* freeing all subproblems that are independent, this is because they have not bee freed during the subproblem
2517 /* sorting the Benders' decomposition cuts in order of priority. Only a single cut is generated for each subproblem
2518 * per solving iteration. This is particularly important in the case of the optimality and feasibility cuts. Since
2519 * these work on two different solutions to the subproblem, it is not necessary to generate both cuts. So, once the
2610 SCIP_CALL( SCIPincludeEventhdlrBasic(set->scip, &eventhdlr, NODESOLVED_EVENTHDLR_NAME, NODESOLVED_EVENTHDLR_DESC,
2643 /* if the subproblems were created by the Benders' decomposition core, then they need to be freed */
2692 /** updates the lower bound for all auxiliary variables. This is called if the first LP enforced is unbounded. */
2719 SCIP_CALL( SCIPbendersComputeSubproblemLowerbound(benders, set, i, &lowerbound, &infeasible) );
2734 SCIPsetDebugMsg(set, "Tightened lower bound of <%s> to %g\n", SCIPvarGetName(auxiliaryvar), lowerbound);
2747 /** sets the core point used for cut strengthening. If the strenghtenintpoint is set to 'i', then the core point is
2761 /* if the core point is not NULL and the interior point is not reinitialised, then nothing is done */
2767 /* if the core point should be updated, then this only happens if the incumbent solution has been updated */
2800 /* if there is time remaining, then compute the relative interior point. Otherwise, return the LP solution */
2803 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, 0, "Computing relative interior point (time limit: %g, iter limit: %d) ...\n", timelimit, INT_MAX);
2804 SCIP_CALL( SCIPcomputeLPRelIntPoint(scip, TRUE, FALSE, timelimit, INT_MAX, &benders->corepoint) );
2844 SCIP_Bool* auxviol, /**< set to TRUE only if the solution is feasible but the aux vars are violated */
2845 SCIP_Bool* infeasible, /**< is the master problem infeasible with respect to the Benders' cuts? */
2846 SCIP_Bool* skipsolve, /**< should the main solve be skipped as a result of this strengthening? */
2862 /* the cut stabilisation is only performed when enforcing LP solutions. The solution is not NULL if the stabilisation
2879 /* if the number of iterations without improvement exceeds 3*noimprovelimit, then the no stabilisation is performed
2884 /* if there is no incumbent solution, then it is not possible to create the core point and hence the strengthening
2890 /* if no LP iterations have been performed since the last call of the cut strenghtening, then the strengthening is
2898 /* if the separation point solution is NULL, then we create the solution using the current LP relaxation. */
2902 * TODO: This could be a little to memory heavy, it may be better just to create the separation point once and then
2911 /* creating a solution that is a convex combination of the LP solution and the separation point */
2933 /* if the variable is a linking variable and it is not fixed, then a convex combination with the corepoint is
2938 /* if the number of iterations without improvement exceeds noimprovelimit, then no convex combination is
2949 /* if the number of iterations without improvement is less than 2*noimprovelimit, then perturbation is
2966 SCIP_CALL( SCIPsolveBendersSubproblems(set->scip, benders, sepapoint, result, infeasible, auxviol, type, checkint) );
2968 SCIPsetDebugMsg(set, "solved Benders' decomposition subproblems with stabilised point. noimprovecount %d result %d\n",
2991 * when Benders' is used in the LNS heuristics, only the convex relaxations of the master/subproblems are checked,
2992 * i.e. no integer cuts are generated. In this case, then Benders' decomposition is performed under the assumption
3015 return (int) SCIPsetCeil(set, (SCIP_Real) SCIPbendersGetNSubproblems(benders)*benders->subprobfrac);
3098 solvestat->avgiter = (SCIP_Real)(solvestat->avgiter*solvestat->ncalls + SCIPgetNLPIterations(subproblem))
3112 /** Solves each of the Benders' decomposition subproblems for the given solution. All, or a fraction, of subproblems are
3114 * Since a convex relaxation of the subproblem could be solved to generate cuts, a parameter nverified is used to
3115 * identified the number of subproblems that have been solved in their "original" form. For example, if the subproblem
3116 * is a MIP, then if the LP is solved to generate cuts, this does not constitute a verification. The verification is
3130 SCIP_Bool** subprobsolved, /**< an array indicating the subproblems that were solved in this loop. */
3132 SCIP_Bool* infeasible, /**< is the master problem infeasible with respect to the Benders' cuts? */
3158 * NOTE: This may not be correct. The Benders' decomposition parallelisation should not take all minimum threads if
3159 * they are specified. The number of threads should be specified with the Benders' decomposition parameters.
3166 /* in the case of an LNS check, only the convex relaxations of the subproblems will be solved. This is a performance
3167 * feature, since solving the convex relaxation is typically much faster than solving the corresponding CIP. While
3168 * the CIP is not solved during the LNS check, the solutions are still of higher quality than when Benders' is not
3173 SCIPsetDebugMsg(set, "Performing the subproblem solving process. Number of subproblems to check %d\n", nsolveidx);
3179 /* TODO: Check whether this is absolutely necessary. I think that this if statment can be removed. */
3185 /* TODO: ensure that the each of the subproblems solve and update the parameters with the correct return values
3188 #pragma omp parallel for num_threads(numthreads) private(i) reduction(&&:locoptimal) reduction(||:locinfeasible) reduction(+:locnverified) reduction(||:locstopped) reduction(min:retcode)
3206 /* for the second solving loop, if the problem is an LP, it is not solved again. If the problem is a MIP,
3207 * then the subproblem objective function value is set to infinity. However, if the subproblem is proven
3209 * If the solve loop is SCIP_BENDERSSOLVELOOP_USERCIP, then nothing is done. It is assumed that the user will
3223 /* if the subproblem is independent, then it does not need to be solved. In this case, the nverified flag will
3228 /* NOTE: There is no need to update the optimal flag. This is because optimal is always TRUE until a
3231 /* if the auxiliary variable value is infinity, then the subproblem has not been solved yet. Currently the
3243 SCIPsetDebugMsg(set, "Benders' decomposition: subproblem %d is not active, but has not been solved."
3251 SCIPbendersSetSubproblemObjval(benders, i, SCIPbendersGetAuxiliaryVarVal(benders, set, sol, i));
3260 SCIPsetDebugMsg(set, "Benders' decomposition: subproblem %d is not active, setting status to OPTIMAL\n", i);
3266 if( solveloop == SCIP_BENDERSSOLVELOOP_CONVEX || solveloop == SCIP_BENDERSSOLVELOOP_USERCONVEX )
3271 retcode = SCIPbendersExecSubproblemSolve(benders, set, sol, i, solveloop, FALSE, &solved, &subinfeas, type);
3290 /* if the subproblems are solved to check integer feasibility, then the optimality check must be performed.
3291 * This will only be performed if checkint is TRUE and the subproblem was solved. The subproblem may not be
3296 /* if the subproblem is feasible, then it is necessary to update the value of the auxiliary variable to the
3310 /* It is only possible to determine the optimality of a solution within a given subproblem in four
3313 * ii) solveloop == SCIP_BENDERSOLVELOOP_CONVEX and only the convex relaxations will be checked.
3314 * iii) solveloop == SCIP_BENDERSSOLVELOOP_USERCIP and the subproblem was solved, since the user has
3329 SCIPbendersGetAuxiliaryVarVal(benders, set, sol, i), SCIPbendersGetSubproblemObjval(benders, i));
3334 SCIPbendersGetAuxiliaryVarVal(benders, set, sol, i), SCIPbendersGetSubproblemObjval(benders, i));
3339 /* the nverified variable is only incremented when the original form of the subproblem has been solved.
3340 * What is meant by "original" is that the LP relaxation of CIPs are solved to generate valid cuts. So
3341 * if the subproblem is defined as a CIP, then it is only classified as checked if the CIP is solved.
3345 * ii) solveloop == SCIP_BENDERSSOLVELOOP_CIP or USERCIP and the CIP for the subproblem has been
3349 if( ((solveloop == SCIP_BENDERSSOLVELOOP_CONVEX || solveloop == SCIP_BENDERSSOLVELOOP_USERCONVEX)
3366 SCIPsetDebugMsg(set, "Local variable values: nverified %d infeasible %d optimal %d stopped %d\n", locnverified,
3382 * The priority of the results are: SCIP_CONSADDED (SCIP_SEPARATED), SCIP_DIDNOTFIND, SCIP_FEASIBLE, SCIP_DIDNOTRUN. In
3399 SCIP_Bool* subprobsolved, /**< an array indicating the subproblems that were solved in this loop. */
3427 /* in the case of an LNS check, only the convex relaxations of the subproblems will be solved. This is a performance
3428 * feature, since solving the convex relaxation is typically much faster than solving the corresponding CIP. While
3429 * the CIP is not solved during the LNS check, the solutions are still of higher quality than when Benders' is not
3436 && SCIPsetGetStage(set) != SCIP_STAGE_TRANSFORMED && SCIPsetGetStage(set) != SCIP_STAGE_PRESOLVED
3449 /* cuts can only be generated if the subproblem is not independent and if it has been solved. Additionally, the
3467 /* the result is updated only if a Benders' cut is generated or one was not found. However, if a cut has
3468 * been found in a previous iteration, then the result is returned as SCIP_CONSADDED or SCIP_SEPARATED.
3469 * This result is permitted because if a constraint was added, the solution that caused the error in the cut
3474 || (!SCIPbenderscutIsLPCut(benderscuts[j]) && ((solveloop == SCIP_BENDERSSOLVELOOP_CIP && !convexsub)
3501 /* the highest priority for the results is CONSADDED and SEPARATED. The solveloopresult will always be
3520 /* since a cut was not found, then merging could be useful to avoid this in subsequent iterations. The
3531 /* if the subproblem is infeasible and no cut generation methods were run, then the infeasibility will
3532 * never be resolved. As such, the subproblem will be merged into the master problem. If the subproblem
3571 if( addedcuts == 0 && SCIPbendersGetNConvexSubproblems(benders) < SCIPbendersGetNSubproblems(benders)
3580 * The checkint flag indicates whether integer feasibility can be assumed. If it is not assumed, i.e. checkint ==
3581 * FALSE, then only the convex relaxations of the subproblems are solved. If integer feasibility is assumed, i.e.
3582 * checkint == TRUE, then the convex relaxations and the full CIP are solved to generate Benders' cuts and check
3585 * TODO: consider allowing the possibility to pass solution information back from the subproblems instead of the scip
3586 * instance. This would allow the use of different solvers for the subproblems, more importantly allowing the use of an
3594 SCIP_Bool* infeasible, /**< is the master problem infeasible with respect to the Benders' cuts? */
3595 SCIP_Bool* auxviol, /**< set to TRUE only if the solution is feasible but the aux vars are violated */
3625 SCIPsetDebugMsg(set, "Starting Benders' decomposition subproblem solving. type %d checkint %d\n", type, checkint);
3639 /* It is assumed that the problem is optimal, until a subproblem is found not to be optimal. However, not all
3640 * subproblems could be checked in each iteration. As such, it is not possible to state that the problem is optimal
3641 * if not all subproblems are checked. Situations where this may occur is when a subproblem is a MIP and only the LP
3642 * is solved. Also, in a distributed computation, then it may be advantageous to only solve some subproblems before
3643 * resolving the master problem. As such, for a problem to be optimal, then (optimal && allverified) == TRUE
3654 /* if the Benders' decomposition is called from a sub-SCIP and the sub-SCIPs have been deactivated, then it is
3655 * assumed that this is an LNS heuristic. As such, the check is not performed and the solution is assumed to be
3662 || (type != SCIP_BENDERSENFOTYPE_CHECK && SCIPgetDepth(set->scip) == 0 && benders->lnsmaxcallsroot > -1
3669 /* it is not necessary to check all primal solutions by solving the Benders' decomposition subproblems.
3671 * If the solution is non-improving, the result FEASIBLE is returned. While this may be incorrect w.r.t to the
3672 * Benders' subproblems, this solution will never be the optimal solution. A non-improving solution may be used
3673 * within LNS primal heuristics. If this occurs, the improving solution, if found, will be checked by the solving
3677 if( checkint && SCIPsetIsLE(set, SCIPgetPrimalbound(set->scip)*(int)SCIPgetObjsense(set->scip),
3684 /* if the enforcement type is SCIP_BENDERSENFOTYPE_LP and the LP is currently unbounded. This could mean that there
3685 * is no lower bound on the auxiliary variables. In this case, we try to update the lower bound for the auxiliary
3688 if( type == SCIP_BENDERSENFOTYPE_LP && SCIPgetLPSolstat(set->scip) == SCIP_LPSOLSTAT_UNBOUNDEDRAY
3707 SCIP_CALL( benders->benderspresubsolve(set->scip, benders, sol, type, checkint, infeasible, auxviol, &skipsolve,
3717 SCIPerrorMessage("the user-defined pre subproblem solving method for the Benders' decomposition <%s> returned "
3722 /* if the solve must be skipped, then the solving loop is exited and the user defined result is returned */
3731 /* the cut strengthening is performed before the regular subproblem solve is called. To avoid recursion, the flag
3732 * strengthenround is set to TRUE when the cut strengthening is performed. The cut strengthening is not performed as
3735 * NOTE: cut strengthening is only applied for fractional solutions and integer solutions if there are no CIP
3739 && (!checkint || SCIPbendersGetNConvexSubproblems(benders) == SCIPbendersGetNSubproblems(benders)) )
3744 /* if the user has not requested the solve to be skipped, then the cut strengthening is performed */
3745 SCIP_CALL( performInteriorSolCutStrengthening(benders, set, sol, type, checkint, FALSE, infeasible, auxviol,
3749 /* if the solve must be skipped, then the solving loop is exited and the user defined result is returned */
3774 /* only a subset of the subproblems are initially solved. Both solving loops are executed for the subproblems to
3775 * check whether any cuts are generated. If a cut is generated, then no further subproblems are solved. If a cut is
3783 /* by default the number of solve loops is 1. This is the case if all subproblems are LP or the user has defined a
3784 * benderssolvesub callback. If there is a subproblem that is not an LP, then 2 solve loops are performed. The first
3791 SCIP_BENDERSSOLVELOOP solveloop; /* identifies what problem type is solve in this solve loop */
3793 /* if either benderssolvesubconvex or benderssolvesub are implemented, then the user callbacks are invoked */
3808 /* if the solving has been stopped, then the subproblem solving and cut generation must terminate */
3812 /* Generating cuts for the subproblems. Cuts are only generated when the solution is from primal heuristics,
3817 SCIP_CALL( generateBendersCuts(benders, set, sol, result, type, solveloop, checkint, subprobsolved,
3822 /* The first solving loop solves the convex subproblems and the convex relaxations of the CIP subproblems. The
3823 * second solving loop solves the CIP subproblems. The second solving loop is only called if the integer
3824 * feasibility is being checked and if the convex subproblems and convex relaxations are not infeasible.
3826 if( !(*infeasible) && checkint && !SCIPbendersOnlyCheckConvexRelax(benders, SCIPsetGetSubscipsOff(set))
3838 /* if the result is CONSADDED or SEPARATED, then a cut is generated and no further subproblem processing is
3853 SCIPsetDebugMsg(set, "End Benders' decomposition subproblem solve. result %d infeasible %d auxviol %d nverified %d\n",
3863 /* if the number of checked pseudo solutions exceeds a set limit, then all subproblems are passed as merge
3864 * candidates. Currently, merging subproblems into the master problem is the only method for resolving numerical
3867 * We are only interested in the pseudo solutions that have been checked completely for integrality. This is
3868 * identified by checkint == TRUE. This means that the Benders' decomposition constraint is one of the last
3869 * constraint handlers that must resolve the infeasibility. If the Benders' decomposition framework can't resolve the
3878 /* if a priority merge candidate already exists, then no other merge candidates need to be added.*/
3881 /* all subproblems are added to the merge candidate list. The first active subproblem is added as a
3896 SCIPverbMessage(set->scip, SCIP_VERBLEVEL_HIGH, NULL, " The number of checked pseudo solutions exceeds the "
3897 "limit of %d. All active subproblems are merge candidates, with subproblem %d a priority candidate.\n",
3905 /* if the result is SCIP_DIDNOTFIND, then there was a error in generating cuts in all subproblems that are not
3906 * optimal. This result does not cutoff any solution, so the Benders' decomposition algorithm will fail.
3908 * It could happen that the cut strengthening approach causes an error the cut generation. In this case, an error
3910 * TODO: Work out a way to ensure Benders' decomposition does not terminate due to a SCIP_DIDNOTFIND result.
3919 SCIPerrorMessage("An error was found when generating cuts for non-optimal subproblems of Benders' "
3920 "decomposition <%s>. Consider merging the infeasible subproblems into the master problem.\n", SCIPbendersGetName(benders));
3922 /* since no other cuts are generated, then this error will result in a crash. It is possible to avoid the error,
3925 * NOTE: If the error occurs while checking solutions, i.e. SCIP_BENDERSENFOTYPE_CHECK, then it is valid to set
3942 /* if the subproblems are not infeasible, but they are also not optimal. This means that there is a violation
3943 * in the auxiliary variable values. In this case, a feasible result is returned with the auxviol flag set to
3952 /* if the subproblems are being solved as part of conscheck, then the results flag must be returned after the solving
3961 /* if the subproblems are not infeasible, but they are also not optimal. This means that there is a violation
3962 * in the auxiliary variable values. In this case, a feasible result is returned with the auxviol flag set to
3970 /* calling the post-solve call back for the Benders' decomposition algorithm. This allows the user to work directly
3978 SCIP_CALL( benders->benderspostsolve(set->scip, benders, sol, type, mergecands, npriomergecands, nmergecands,
3985 /* since subproblems have been merged, then constraints have been added. This could resolve the unresolved
3992 SCIPerrorMessage("An error occurred during Benders' decomposition cut generations and no merging had been "
4031 SCIPsetDebugMsg(set, "End Benders' decomposition execution method. result %d infeasible %d auxviol %d\n", *result,
4044 /* if there was an error in generating cuts and merging was not performed, then the solution is perturbed in an
4055 /* if the user has not requested the solve to be skipped, then the cut strengthening is performed */
4056 SCIP_CALL( performInteriorSolCutStrengthening(benders, set, sol, type, checkint, TRUE, infeasible, auxviol,
4066 /* if the Benders' decomposition subproblem check stopped, then we don't have a valid result. In this case, the
4072 /* if the subproblem verification identifies the solution as feasible, then a check whether slack variables have been
4073 * used is necessary. If any slack variables are non-zero, then the solution is reverified after the objective
4095 SCIP_CALL( SCIPsolveBendersSubproblems(set->scip, benders, sol, result, infeasible, auxviol, type, checkint) );
4106 SCIP_CALL( SCIPsolveBendersSubproblems(set->scip, benders, sol, result, infeasible, auxviol, type, checkint) );
4124 SCIP_BENDERSSOLVELOOP solveloop, /**< the solve loop iteration. The first iter is for LP, the second for IP */
4134 assert(solveloop == SCIP_BENDERSSOLVELOOP_USERCONVEX || solveloop == SCIP_BENDERSSOLVELOOP_USERCIP);
4138 /* calls the user defined subproblem solving method. Only the convex relaxations are solved during the Large
4166 SCIPerrorMessage("the user-defined solving method for the Benders' decomposition <%s> returned invalid result <%d>\n",
4177 SCIPerrorMessage("the user-defined solving method for the Benders' decomposition <%s> returned objective value %g\n",
4195 SCIP_BENDERSSOLVELOOP solveloop, /**< the solve loop iteration. The first iter is for LP, the second for IP */
4217 if( subproblem == NULL && (benders->benderssolvesubconvex == NULL || benders->benderssolvesub == NULL) )
4219 SCIPerrorMessage("The subproblem %d is set to NULL, but both bendersSolvesubconvex%s and bendersSolvesub%s "
4228 /* if the subproblem solve callback is implemented, then that is used instead of the default setup */
4229 if( solveloop == SCIP_BENDERSSOLVELOOP_USERCONVEX || solveloop == SCIP_BENDERSSOLVELOOP_USERCIP )
4231 /* calls the user defined subproblem solving method. Only the convex relaxations are solved during the Large
4233 SCIP_CALL( executeUserDefinedSolvesub(benders, set, sol, probnumber, solveloop, infeasible, &objective, &result) );
4245 /* if the limits of the master problem were hit during the setup process, then the subproblem will not have
4257 SCIP_CALL( updateEventhdlrUpperbound(benders, probnumber, SCIPbendersGetAuxiliaryVarVal(benders, set, sol, probnumber)) );
4266 SCIP_CALL( SCIPbendersSolveSubproblemLP(set->scip, benders, probnumber, &solvestatus, &objective) );
4279 SCIP_CALL( SCIPbendersSolveSubproblemCIP(set->scip, benders, probnumber, &solvestatus, FALSE) );
4284 /* if the generic subproblem solving methods are used, then the CIP subproblems are always solved. */
4302 * If a subproblem is unbounded, then the auxiliary variables are set to -infinity and the unbounded flag is
4317 SCIPverbMessage(set->scip, SCIP_VERBLEVEL_FULL, NULL, " Benders' decomposition: Error solving "
4323 SCIPerrorMessage("The Benders' decomposition subproblem %d is unbounded. This should not happen.\n",
4329 SCIPerrorMessage("Invalid status returned from solving Benders' decomposition subproblem %d. Solution status: %d\n",
4336 assert(solveloop == SCIP_BENDERSSOLVELOOP_USERCONVEX || solveloop == SCIP_BENDERSSOLVELOOP_USERCIP);
4343 SCIPerrorMessage("The Benders' decomposition subproblem %d is unbounded. This should not happen.\n",
4349 SCIPerrorMessage("Invalid result <%d> from user-defined subproblem solving method. This should not happen.\n",
4383 SCIPerrorMessage("The subproblem %d is NULL. Thus, the subproblem setup must be performed manually in either "
4392 /* if the Benders' decomposition subproblem is convex and has continuous variables, then probing mode
4394 * If the subproblem contains non-convex constraints or discrete variables, then the problem must be initialised,
4395 * and then put into SCIP_STAGE_SOLVING to be able to change the variable bounds. The probing mode is entered once
4420 /* looping over all variables in the subproblem to find those corresponding to the master problem variables. */
4421 /* TODO: It should be possible to store the pointers to the master variables to speed up the subproblem setup */
4428 /* It is possible due to numerics that the solution value exceeds the upper or lower bounds. When this
4429 * happens, it causes an error in the LP solver as a result of inconsistent bounds. So the following statements
4430 * are used to ensure that the bounds are not exceeded when applying the fixings for the Benders'
4456 /* if the slack variables have been added to help improve feasibility, then they remain unfixed with a large
4457 * objective coefficient. Once the root node has been solved to optimality, then the slack variables are
4460 if( benders->feasibilityphase && SCIPgetDepth(set->scip) == 0 && type != SCIP_BENDERSENFOTYPE_CHECK )
4472 /* if the subproblem is non-linear and convex, then slack variables have been added to the subproblem. These
4473 * need to be fixed to zero when first solving the subproblem. However, if the slack variables have been added
4487 /* if the subproblem contain non-convex constraints or discrete variables, then the probing mode is entered after
4501 /** Solve a Benders' decomposition subproblems. This will either call the user defined method or the generic solving
4502 * methods. If the generic method is called, then the subproblem must be set up before calling this method. */
4520 if( SCIPbendersSubproblem(benders, probnumber) != NULL && !SCIPbendersSubproblemIsSetup(benders, probnumber)
4523 SCIPerrorMessage("Benders' decomposition subproblem %d must be set up before calling SCIPbendersSolveSubproblem(). Call SCIPsetupSubproblem() first.\n", probnumber);
4527 /* if the subproblem solve callback is implemented, then that is used instead of the default setup */
4539 SCIP_CALL( executeUserDefinedSolvesub(benders, set, sol, probnumber, solveloop, infeasible, &subobj, &result) );
4552 if( solvecip && SCIPbendersGetSubproblemType(benders, probnumber) != SCIP_BENDERSSUBTYPE_CONVEXCONT )
4556 SCIP_CALL( SCIPbendersSolveSubproblemCIP(set->scip, benders, probnumber, &solvestatus, solvecip) );
4561 (*objective) = SCIPgetSolOrigObj(subproblem, SCIPgetBestSol(subproblem))*(int)SCIPgetObjsense(subproblem);
4567 /* if the subproblem has convex constraints and continuous variables, then it should have been initialised and
4572 /* if the subproblem is not in probing mode, then it must be put into that mode for the LP solve. */
4591 SCIP_CALL( SCIPbendersSolveSubproblemLP(set->scip, benders, probnumber, &solvestatus, &lpobjective) );
4625 /* setting the time limit for the Benders' decomposition subproblems. It is set to 102% of the remaining time. */
4635 submemorylimit = mastermemorylimit - (SCIPgetMemUsed(scip) + SCIPgetMemExternEstim(scip))/1048576.0;
4659 SCIP_CALL( SCIPgetBoolParam(subproblem, "lp/alwaysgetduals", &origparams->lp_alwaysgetduals) );
4662 SCIP_CALL( SCIPgetIntParam(subproblem, "propagating/maxrounds", &origparams->prop_maxrounds) );
4663 SCIP_CALL( SCIPgetIntParam(subproblem, "propagating/maxroundsroot", &origparams->prop_maxroundsroot) );
4664 SCIP_CALL( SCIPgetIntParam(subproblem, "constraints/linear/propfreq", &origparams->cons_linear_propfreq) );
4739 SCIP_CALL( SCIPsetIntParam(subproblem, "propagating/maxroundsroot", origparams->prop_maxroundsroot) );
4740 SCIP_CALL( SCIPsetIntParam(subproblem, "constraints/linear/propfreq", origparams->cons_linear_propfreq) );
4766 /* TODO: This should be solved just as an LP, so as a MIP. There is too much overhead with the MIP.
4771 /* only solve the NLP relaxation if the NLP has been constructed and there exists an NLPI. If it is not possible to
4811 if( nlptermstat == SCIP_NLPTERMSTAT_OKAY && (nlpsolstat == SCIP_NLPSOLSTAT_LOCINFEASIBLE || nlpsolstat == SCIP_NLPSOLSTAT_GLOBINFEASIBLE) )
4831 SCIPerrorMessage("The NLP of Benders' decomposition subproblem %d is unbounded. This should not happen.\n",
4841 SCIPerrorMessage("Invalid solution status: %d. Termination status: %d. Solving the NLP relaxation of Benders' decomposition subproblem %d.\n",
4871 SCIPerrorMessage("The LP of Benders' decomposition subproblem %d is unbounded. This should not happen.\n",
4895 SCIPerrorMessage("Invalid status: %d. Solving the LP relaxation of Benders' decomposition subproblem %d.\n",
4936 /* If the solve has been stopped for the subproblem, then we need to restart it to complete the solve. The subproblem
4940 /* the subproblem should be in probing mode. Otherwise, the event handler did not work correctly */
4946 /* the problem was interrupted in the event handler, so SCIP needs to be informed that the problem is to be restarted */
4964 /* if the problem is not in probing mode, then we need to solve the LP. That requires all methods that will
4989 SCIPerrorMessage("Invalid status: %d. Solving the CIP of Benders' decomposition subproblem %d.\n",
5012 || (benders->bendersfreesub == NULL && benders->benderssolvesubconvex == NULL && benders->benderssolvesub == NULL));
5028 /* ending probing mode to reset the current node. The probing mode will be restarted at the next solve */
5036 /* if the subproblems were solved as part of an enforcement stage, then they will still be in probing mode. The
5053 /** compares the subproblem objective value with the auxiliary variable value for optimality */
5072 SCIPsetDebugMsg(set, "Subproblem %d - Auxiliary Variable: %g Subproblem Objective: %g Reldiff: %g Soltol: %g\n",
5074 SCIPrelDiff(SCIPbendersGetSubproblemObjval(benders, probnumber), auxiliaryvarval), benders->solutiontol);
5076 if( SCIPrelDiff(SCIPbendersGetSubproblemObjval(benders, probnumber), auxiliaryvarval) < benders->solutiontol )
5101 /** Solves an independent subproblem to identify its lower bound. The lower bound is then used to update the bound on
5130 SCIPinfoMessage(set->scip, NULL, "Benders' decomposition: a bendersSolvesub or bendersSolvesubconvex has been "
5133 "SCIPbendersUpdateSubproblemLowerbound in bendersCreatesub. The auxiliary variable %d will remain as %g\n",
5140 SCIPverbMessage(set->scip, SCIP_VERBLEVEL_FULL, NULL, "Benders' decomposition: Computing a lower bound for"
5161 /* if the subproblem is independent, then the default SCIP settings are used. Otherwise, only the root node is solved
5172 /* if the subproblem not independent and is convex, then the probing LP is solved. Otherwise, the MIP is solved */
5201 if( nlptermstat == SCIP_NLPTERMSTAT_OKAY && (nlpsolstat == SCIP_NLPSOLSTAT_LOCINFEASIBLE || nlpsolstat == SCIP_NLPSOLSTAT_GLOBINFEASIBLE) )
5226 /* if the subproblem is not convex, then event handlers have been added to interrupt the solve. These must be
5229 eventhdlrdata = SCIPeventhdlrGetData(SCIPfindEventhdlr(subproblem, MIPNODEFOCUS_EVENTHDLR_NAME));
5252 /* the subproblem must be freed so that it is reset for the subsequent Benders' decomposition solves. If the
5253 * subproblems are independent, they are not freed. SCIPfreeBendersSubproblem must still be called, but in this
5254 * function the independent subproblems are not freed. However, they will still be freed at the end of the
5262 /** Merges a subproblem into the master problem. This process just adds a copy of the subproblem variables and
5263 * constraints to the master problem, but keeps the subproblem stored in the Benders' decomposition data structure. The reason for
5264 * keeping the subproblem available is for when it is queried for solutions after the problem is solved.
5266 * Once the subproblem is merged into the master problem, then the subproblem is flagged as disabled. This means that
5269 * The associated auxiliary variables are kept in the master problem. The objective function of the merged subproblem
5275 SCIP_HASHMAP* varmap, /**< a hashmap to store the mapping of subproblem variables corresponding
5302 SCIPverbMessage(set->scip, SCIP_VERBLEVEL_HIGH, NULL, " Benders' decomposition: Infeasibility of subproblem %d can't "
5303 "be resolved. Subproblem %d is being merged into the master problem.\n", probnumber, probnumber);