Scippy

SCIP

Solving Constraint Integer Programs

benderscut_opt.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2019 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scip.zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file benderscut_opt.c
17  * @brief Generates a standard Benders' decomposition optimality cut
18  * @author Stephen J. Maher
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #include "scip/benderscut_opt.h"
24 #include "scip/cons_linear.h"
25 #include "scip/pub_benderscut.h"
26 #include "scip/pub_benders.h"
27 #include "scip/pub_lp.h"
28 #include "scip/pub_message.h"
29 #include "scip/pub_misc.h"
30 #include "scip/pub_misc_linear.h"
31 #include "scip/pub_var.h"
32 #include "scip/scip_benders.h"
33 #include "scip/scip_cons.h"
34 #include "scip/scip_cut.h"
35 #include "scip/scip_general.h"
36 #include "scip/scip_lp.h"
37 #include "scip/scip_mem.h"
38 #include "scip/scip_message.h"
39 #include "scip/scip_numerics.h"
40 #include "scip/scip_param.h"
41 #include "scip/scip_prob.h"
42 #include "scip/scip_probing.h"
43 #include "scip/scip_var.h"
44 #include <string.h>
45 
46 #define BENDERSCUT_NAME "optimality"
47 #define BENDERSCUT_DESC "Standard Benders' decomposition optimality cut"
48 #define BENDERSCUT_PRIORITY 5000
49 #define BENDERSCUT_LPCUT TRUE
50 
51 #define SCIP_DEFAULT_ADDCUTS FALSE /** Should cuts be generated, instead of constraints */
52 
53 /*
54  * Data structures
55  */
56 
57 /** Benders' decomposition cuts data */
58 struct SCIP_BenderscutData
59 {
60  SCIP_Bool addcuts; /**< should cuts be generated instead of constraints */
61 };
62 
63 
64 /*
65  * Local methods
66  */
67 
68 /** in the case of numerical troubles, the LP is resolved with solution polishing activated */
69 static
71  SCIP* subproblem, /**< the SCIP data structure */
72  SCIP_Bool* success /**< TRUE is the resolving of the LP was successful */
73  )
74 {
75  int oldpolishing;
76  SCIP_Bool lperror;
77  SCIP_Bool cutoff;
78 
79  assert(subproblem != NULL);
80  assert(SCIPinProbing(subproblem));
81 
82  (*success) = FALSE;
83 
84  /* setting the solution polishing parameter */
85  SCIP_CALL( SCIPgetIntParam(subproblem, "lp/solutionpolishing", &oldpolishing) );
86  SCIP_CALL( SCIPsetIntParam(subproblem, "lp/solutionpolishing", 2) );
87 
88  /* resolving the probing LP */
89  SCIP_CALL( SCIPsolveProbingLP(subproblem, -1, &lperror, &cutoff) );
90 
91  if( SCIPgetLPSolstat(subproblem) == SCIP_LPSOLSTAT_OPTIMAL )
92  (*success) = TRUE;
93 
94  /* resetting the solution polishing parameter */
95  SCIP_CALL( SCIPsetIntParam(subproblem, "lp/solutionpolishing", oldpolishing) );
96 
97  return SCIP_OKAY;
98 }
99 
100 /** computes a standard Benders' optimality cut from the dual solutions of the LP */
101 static
103  SCIP* masterprob, /**< the SCIP instance of the master problem */
104  SCIP* subproblem, /**< the SCIP instance of the subproblem */
105  SCIP_BENDERS* benders, /**< the benders' decomposition structure */
106  SCIP_VAR** vars, /**< the variables in the generated cut with non-zero coefficient */
107  SCIP_Real* vals, /**< the coefficients of the variables in the generated cut */
108  SCIP_Real* lhs, /**< the left hand side of the cut */
109  SCIP_Real* rhs, /**< the right hand side of the cut */
110  int* nvars, /**< the number of variables in the cut */
111  SCIP_Real* checkobj, /**< stores the objective function computed from the dual solution */
112  SCIP_Bool* success /**< was the cut generation successful? */
113  )
114 {
115  SCIP_VAR** subvars;
116  SCIP_VAR** fixedvars;
117  SCIP_CONS** conss;
118  int nsubvars;
119  int nfixedvars;
120  int nconss;
121  SCIP_Real dualsol;
122  SCIP_Real addval;
123  int i;
124 
125  (*checkobj) = 0;
126 
127  assert(masterprob != NULL);
128  assert(subproblem != NULL);
129  assert(benders != NULL);
130  assert(vars != NULL);
131  assert(vals != NULL);
132 
133  (*success) = FALSE;
134 
135  nsubvars = SCIPgetNVars(subproblem);
136  subvars = SCIPgetVars(subproblem);
137  nfixedvars = SCIPgetNFixedVars(subproblem);
138  fixedvars = SCIPgetFixedVars(subproblem);
139 
140  nconss = SCIPgetNConss(subproblem);
141  conss = SCIPgetConss(subproblem);
142 
143  /* looping over all constraints and setting the coefficients of the cut */
144  for( i = 0; i < nconss; i++ )
145  {
146  SCIP_Bool conssuccess;
147  addval = 0;
148 
149  SCIPconsGetDualsol(subproblem, conss[i], &dualsol, &conssuccess);
150  if( !conssuccess )
151  {
152  (*success) = FALSE;
153  SCIPdebugMsg(masterprob, "Error when generating optimality cut.\n");
154  return SCIP_OKAY;
155  }
156 
157  assert( !SCIPisInfinity(subproblem, dualsol) && !SCIPisInfinity(subproblem, -dualsol) );
158 
159  if( SCIPisZero(subproblem, dualsol) )
160  continue;
161 
162  if( SCIPisPositive(subproblem, dualsol) )
163  addval = dualsol*SCIPconsGetLhs(subproblem, conss[i], &conssuccess);
164  else if( SCIPisNegative(subproblem, dualsol) )
165  addval = dualsol*SCIPconsGetRhs(subproblem, conss[i], &conssuccess);
166 
167  if( !conssuccess )
168  {
169  (*success) = FALSE;
170  SCIPdebugMsg(masterprob, "Error when generating optimality cut.\n");
171  return SCIP_OKAY;
172  }
173 
174  (*lhs) += addval;
175 
176  /* if the bound becomes infinite, then the cut generation terminates. */
177  if( SCIPisInfinity(masterprob, (*lhs)) || SCIPisInfinity(masterprob, -(*lhs))
178  || SCIPisInfinity(masterprob, addval) || SCIPisInfinity(masterprob, -addval))
179  {
180  (*success) = FALSE;
181  SCIPdebugMsg(masterprob, "Infinite bound when generating optimality cut. lhs = %g addval = %g.\n", (*lhs), addval);
182  return SCIP_OKAY;
183  }
184  }
185 
186  /* looping over all variables to update the coefficients in the computed cut. */
187  for( i = 0; i < nsubvars + nfixedvars; i++ )
188  {
189  SCIP_VAR* var;
190  SCIP_VAR* mastervar;
191  SCIP_Real redcost;
192 
193  if( i < nsubvars )
194  var = subvars[i];
195  else
196  var = fixedvars[i - nsubvars];
197 
198  /* retrieving the master problem variable for the given subproblem variable. */
199  SCIP_CALL( SCIPgetBendersMasterVar(masterprob, benders, var, &mastervar) );
200 
201  redcost = SCIPgetVarRedcost(subproblem, var);
202 
203  (*checkobj) += SCIPvarGetUnchangedObj(var)*SCIPvarGetSol(var, TRUE);
204 
205  /* checking whether the subproblem variable has a corresponding master variable. */
206  if( mastervar != NULL )
207  {
208  SCIP_Real coef;
209 
210  coef = -1.0*(SCIPvarGetObj(var) + redcost);
211 
212  if( !SCIPisZero(masterprob, coef) )
213  {
214  vars[(*nvars)] = mastervar;
215  vals[(*nvars)] = coef;
216  (*nvars)++;
217  }
218  }
219  else
220  {
221  if( !SCIPisZero(subproblem, redcost) )
222  {
223  addval = 0;
224 
225  if( SCIPisPositive(subproblem, redcost) )
226  addval = redcost*SCIPvarGetLbLocal(var);
227  else if( SCIPisNegative(subproblem, redcost) )
228  addval = redcost*SCIPvarGetUbLocal(var);
229 
230  (*lhs) += addval;
231 
232  /* if the bound becomes infinite, then the cut generation terminates. */
233  if( SCIPisInfinity(masterprob, (*lhs)) || SCIPisInfinity(masterprob, -(*lhs))
234  || SCIPisInfinity(masterprob, addval) || SCIPisInfinity(masterprob, -addval))
235  {
236  (*success) = FALSE;
237  SCIPdebugMsg(masterprob, "Infinite bound when generating optimality cut.\n");
238  return SCIP_OKAY;
239  }
240  }
241  }
242  }
243 
244  assert(SCIPisInfinity(masterprob, (*rhs)));
245  /* the rhs should be infinite. If it changes, then there is an error */
246  if( !SCIPisInfinity(masterprob, (*rhs)) )
247  {
248  (*success) = FALSE;
249  SCIPdebugMsg(masterprob, "RHS is not infinite. rhs = %g.\n", (*rhs));
250  return SCIP_OKAY;
251  }
252 
253  (*success) = TRUE;
254 
255  return SCIP_OKAY;
256 }
257 
258 
259 /** Adds the auxiliary variable to the generated cut. If this is the first optimality cut for the subproblem, then the
260  * auxiliary variable is first created and added to the master problem.
261  */
262 static
264  SCIP* masterprob, /**< the SCIP instance of the master problem */
265  SCIP_BENDERS* benders, /**< the benders' decomposition structure */
266  SCIP_VAR** vars, /**< the variables in the generated cut with non-zero coefficient */
267  SCIP_Real* vals, /**< the coefficients of the variables in the generated cut */
268  int* nvars, /**< the number of variables in the cut */
269  int probnumber /**< the number of the pricing problem */
270  )
271 {
272  SCIP_VAR* auxiliaryvar;
273 
274  assert(masterprob != NULL);
275  assert(benders != NULL);
276  assert(vars != NULL);
277  assert(vals != NULL);
278 
279  auxiliaryvar = SCIPbendersGetAuxiliaryVar(benders, probnumber);
280 
281  vars[(*nvars)] = auxiliaryvar;
282  vals[(*nvars)] = 1.0;
283  (*nvars)++;
284 
285  return SCIP_OKAY;
286 }
287 
288 
289 /** generates and applies Benders' cuts */
290 static
292  SCIP* masterprob, /**< the SCIP instance of the master problem */
293  SCIP* subproblem, /**< the SCIP instance of the pricing problem */
294  SCIP_BENDERS* benders, /**< the benders' decomposition */
295  SCIP_BENDERSCUT* benderscut, /**< the benders' decomposition cut method */
296  SCIP_SOL* sol, /**< primal CIP solution */
297  int probnumber, /**< the number of the pricing problem */
298  SCIP_BENDERSENFOTYPE type, /**< the enforcement type calling this function */
299  SCIP_RESULT* result /**< the result from solving the subproblems */
300  )
301 {
302  SCIP_BENDERSCUTDATA* benderscutdata;
303  SCIP_CONSHDLR* consbenders;
304  SCIP_CONS* cons;
305  SCIP_ROW* row;
306  SCIP_VAR** vars;
307  SCIP_Real* vals;
308  SCIP_Real lhs;
309  SCIP_Real rhs;
310  int nvars;
311  int nmastervars;
312  char cutname[SCIP_MAXSTRLEN];
313  SCIP_Bool optimal;
314  SCIP_Bool addcut;
315  SCIP_Bool success;
316 
317  SCIP_Real checkobj;
318  SCIP_Real verifyobj;
319 
320  assert(masterprob != NULL);
321  assert(subproblem != NULL);
322  assert(benders != NULL);
323  assert(benderscut != NULL);
324  assert(result != NULL);
325  assert(SCIPgetStatus(subproblem) == SCIP_STATUS_OPTIMAL || SCIPgetLPSolstat(subproblem) == SCIP_LPSOLSTAT_OPTIMAL);
326 
327  row = NULL;
328  cons = NULL;
329 
330  /* retrieving the Benders' cut data */
331  benderscutdata = SCIPbenderscutGetData(benderscut);
332 
333  /* if the cuts are generated prior to the solving stage, then rows can not be generated. So constraints must be
334  * added to the master problem.
335  */
336  if( SCIPgetStage(masterprob) < SCIP_STAGE_INITSOLVE )
337  addcut = FALSE;
338  else
339  addcut = benderscutdata->addcuts;
340 
341  /* retrieving the Benders' decomposition constraint handler */
342  consbenders = SCIPfindConshdlr(masterprob, "benders");
343 
344  /* checking the optimality of the original problem with a comparison between the auxiliary variable and the
345  * objective value of the subproblem */
346  SCIP_CALL( SCIPcheckBendersSubproblemOptimality(masterprob, benders, sol, probnumber, &optimal) );
347 
348  if( optimal )
349  {
350  (*result) = SCIP_FEASIBLE;
351  SCIPdebugMsg(masterprob, "No cut added for subproblem %d\n", probnumber);
352  return SCIP_OKAY;
353  }
354 
355  /* allocating memory for the variable and values arrays */
356  nmastervars = SCIPgetNVars(masterprob) + SCIPgetNFixedVars(masterprob);
357  SCIP_CALL( SCIPallocClearBufferArray(masterprob, &vars, nmastervars) );
358  SCIP_CALL( SCIPallocClearBufferArray(masterprob, &vals, nmastervars) );
359  lhs = 0.0;
360  rhs = SCIPinfinity(masterprob);
361  nvars = 0;
362 
363  /* setting the name of the generated cut */
364  (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "optimalitycut_%d_%d", probnumber,
365  SCIPbenderscutGetNFound(benderscut) );
366 
367  /* computing the coefficients of the optimality cut */
368  SCIP_CALL( computeStandardOptimalityCut(masterprob, subproblem, benders, vars, vals, &lhs, &rhs, &nvars, &checkobj,
369  &success) );
370 
371  /* if success is FALSE, then there was an error in generating the optimality cut. No cut will be added to the master
372  * problem. Otherwise, the constraint is added to the master problem.
373  */
374  if( !success )
375  {
376  (*result) = SCIP_DIDNOTFIND;
377  SCIPdebugMsg(masterprob, "Error in generating Benders' optimality cut for problem %d.\n", probnumber);
378  }
379  else
380  {
381  /* creating an empty row or constraint for the Benders' cut */
382  if( addcut )
383  {
384  SCIP_CALL( SCIPcreateEmptyRowCons(masterprob, &row, consbenders, cutname, lhs, rhs, FALSE, FALSE, TRUE) );
385  SCIP_CALL( SCIPaddVarsToRow(masterprob, row, nvars, vars, vals) );
386  }
387  else
388  {
389  SCIP_CALL( SCIPcreateConsBasicLinear(masterprob, &cons, cutname, nvars, vars, vals, lhs, rhs) );
390  SCIP_CALL( SCIPsetConsDynamic(masterprob, cons, TRUE) );
391  SCIP_CALL( SCIPsetConsRemovable(masterprob, cons, TRUE) );
392  }
393 
394  /* computing the objective function from the cut activity to verify the accuracy of the constraint */
395  verifyobj = 0.0;
396  if( addcut )
397  {
398  verifyobj += SCIProwGetLhs(row) - SCIPgetRowSolActivity(masterprob, row, sol);
399  }
400  else
401  {
402  verifyobj += SCIPgetLhsLinear(masterprob, cons) - SCIPgetActivityLinear(masterprob, cons, sol);
403  }
404 
405  /* it is possible that numerics will cause the generated cut to be invalid. This cut should not be added to the
406  * master problem, since its addition could cut off feasible solutions. The success flag is set of false, indicating
407  * that the Benders' cut could not find a valid cut.
408  */
409  if( !SCIPisFeasEQ(masterprob, checkobj, verifyobj) )
410  {
411  success = FALSE;
412  SCIPdebugMsg(masterprob, "The objective function and cut activity are not equal (%g != %g).\n", checkobj,
413  verifyobj);
414 #ifdef SCIP_DEBUG
415  SCIPABORT();
416 #endif
417  }
418 
419  if( success )
420  {
421  /* adding the auxiliary variable to the optimality cut */
422  SCIP_CALL( addAuxiliaryVariableToCut(masterprob, benders, vars, vals, &nvars, probnumber) );
423 
424  /* adding the constraint to the master problem */
425  if( addcut )
426  {
427  SCIP_Bool infeasible;
428 
429  /* adding the auxiliary variable coefficient to the row */
430  SCIP_CALL( SCIPaddVarToRow(masterprob, row, vars[nvars - 1], vals[nvars - 1]) );
431 
432  if( type == SCIP_BENDERSENFOTYPE_LP || type == SCIP_BENDERSENFOTYPE_RELAX )
433  {
434  SCIP_CALL( SCIPaddRow(masterprob, row, FALSE, &infeasible) );
435  assert(!infeasible);
436  }
437  else
438  {
439  assert(type == SCIP_BENDERSENFOTYPE_CHECK || type == SCIP_BENDERSENFOTYPE_PSEUDO);
440  SCIP_CALL( SCIPaddPoolCut(masterprob, row) );
441  }
442 
443  (*result) = SCIP_SEPARATED;
444  }
445  else
446  {
447  /* adding the auxiliary variable coefficient to the constraint */
448  SCIP_CALL( SCIPaddCoefLinear(masterprob, cons, vars[nvars - 1], vals[nvars - 1]) );
449 
450  SCIP_CALL( SCIPaddCons(masterprob, cons) );
451 
452  SCIPdebugPrintCons(masterprob, cons, NULL);
453 
454  (*result) = SCIP_CONSADDED;
455  }
456 
457  /* storing the data that is used to create the cut */
458  SCIP_CALL( SCIPstoreBenderscutCut(masterprob, benderscut, vars, vals, lhs, rhs, nvars) );
459  }
460 
461  /* releasing the row or constraint */
462  if( addcut )
463  {
464  /* release the row */
465  SCIP_CALL( SCIPreleaseRow(masterprob, &row) );
466  }
467  else
468  {
469  /* release the constraint */
470  SCIP_CALL( SCIPreleaseCons(masterprob, &cons) );
471  }
472  }
473 
474  SCIPfreeBufferArray(masterprob, &vals);
475  SCIPfreeBufferArray(masterprob, &vars);
476 
477  return SCIP_OKAY;
478 }
479 
480 /*
481  * Callback methods of Benders' decomposition cuts
482  */
483 
484 /** destructor of Benders' decomposition cuts to free user data (called when SCIP is exiting) */
485 static
486 SCIP_DECL_BENDERSCUTFREE(benderscutFreeOpt)
487 { /*lint --e{715}*/
488  SCIP_BENDERSCUTDATA* benderscutdata;
489 
490  assert( benderscut != NULL );
491  assert( strcmp(SCIPbenderscutGetName(benderscut), BENDERSCUT_NAME) == 0 );
492 
493  /* free Benders' cut data */
494  benderscutdata = SCIPbenderscutGetData(benderscut);
495  assert( benderscutdata != NULL );
496 
497  SCIPfreeBlockMemory(scip, &benderscutdata);
498 
499  SCIPbenderscutSetData(benderscut, NULL);
500 
501  return SCIP_OKAY;
502 }
503 
504 
505 /** execution method of Benders' decomposition cuts */
506 static
507 SCIP_DECL_BENDERSCUTEXEC(benderscutExecOpt)
508 { /*lint --e{715}*/
509  SCIP* subproblem;
510 
511  assert(scip != NULL);
512  assert(benders != NULL);
513  assert(benderscut != NULL);
514  assert(result != NULL);
515  assert(probnumber >= 0 && probnumber < SCIPbendersGetNSubproblems(benders));
516 
517  subproblem = SCIPbendersSubproblem(benders, probnumber);
518 
519  /* only generate optimality cuts if the subproblem is optimal */
520  if( SCIPgetStatus(subproblem) == SCIP_STATUS_OPTIMAL ||
521  (SCIPgetStage(subproblem) == SCIP_STAGE_SOLVING && SCIPgetLPSolstat(subproblem) == SCIP_LPSOLSTAT_OPTIMAL) )
522  {
523  /* generating a cut for a given subproblem */
524  SCIP_CALL( generateAndApplyBendersCuts(scip, subproblem, benders, benderscut,
525  sol, probnumber, type, result) );
526 
527  /* if it was not possible to generate a cut, this could be due to numerical issues. So the solution to the LP is
528  * resolved and the generation of the cut is reattempted
529  */
530  if( (*result) == SCIP_DIDNOTFIND )
531  {
532  SCIP_Bool success;
533 
534  SCIPinfoMessage(scip, NULL, "Numerical trouble generating optimality cut for subproblem %d. Attempting to "
535  "polish the LP solution to find an alternative dual extreme point.\n", probnumber);
536 
537  SCIP_CALL( polishSolution(subproblem, &success) );
538 
539  /* only attempt to generate a cut if the solution polishing was successful */
540  if( success )
541  {
542  SCIP_CALL( generateAndApplyBendersCuts(scip, subproblem, benders, benderscut,
543  sol, probnumber, type, result) );
544  }
545  }
546  }
547 
548  return SCIP_OKAY;
549 }
550 
551 
552 /*
553  * Benders' decomposition cuts specific interface methods
554  */
555 
556 /** creates the opt Benders' decomposition cuts and includes it in SCIP */
558  SCIP* scip, /**< SCIP data structure */
559  SCIP_BENDERS* benders /**< Benders' decomposition */
560  )
561 {
562  SCIP_BENDERSCUTDATA* benderscutdata;
563  SCIP_BENDERSCUT* benderscut;
564  char paramname[SCIP_MAXSTRLEN];
565 
566  assert(benders != NULL);
567 
568  /* create opt Benders' decomposition cuts data */
569  SCIP_CALL( SCIPallocBlockMemory(scip, &benderscutdata) );
570 
571  benderscut = NULL;
572 
573  /* include Benders' decomposition cuts */
575  BENDERSCUT_PRIORITY, BENDERSCUT_LPCUT, benderscutExecOpt, benderscutdata) );
576 
577  assert(benderscut != NULL);
578 
579  /* setting the non fundamental callbacks via setter functions */
580  SCIP_CALL( SCIPsetBenderscutFree(scip, benderscut, benderscutFreeOpt) );
581 
582  /* add opt Benders' decomposition cuts parameters */
583  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "benders/%s/benderscut/%s/addcuts",
585  SCIP_CALL( SCIPaddBoolParam(scip, paramname,
586  "should cuts be generated and added to the cutpool instead of global constraints directly added to the problem.",
587  &benderscutdata->addcuts, FALSE, SCIP_DEFAULT_ADDCUTS, NULL, NULL) );
588 
589  return SCIP_OKAY;
590 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
SCIP_VAR * SCIPbendersGetAuxiliaryVar(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:4409
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPconsGetLhs(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
Definition: misc_linear.c:102
#define NULL
Definition: def.h:253
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:876
internal miscellaneous methods for linear constraints
public methods for SCIP parameter handling
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
#define BENDERSCUT_LPCUT
struct SCIP_BenderscutData SCIP_BENDERSCUTDATA
public methods for memory management
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip_general.c:466
#define SCIPallocClearBufferArray(scip, ptr, num)
Definition: scip_mem.h:113
SCIP_Real SCIPgetVarRedcost(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1866
#define SCIP_MAXSTRLEN
Definition: def.h:274
SCIP_Real SCIPconsGetRhs(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
Definition: misc_linear.c:38
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
int SCIPgetNConss(SCIP *scip)
Definition: scip_prob.c:3037
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1987
int SCIPbendersGetNSubproblems(SCIP_BENDERS *benders)
Definition: benders.c:4255
#define FALSE
Definition: def.h:73
SCIP_Longint SCIPbenderscutGetNFound(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:559
public methods for Benders&#39; decomposition
SCIP_EXPORT SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17200
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)
#define TRUE
Definition: def.h:72
SCIP_CONS ** SCIPgetConss(SCIP *scip)
Definition: scip_prob.c:3083
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
enum SCIP_BendersEnfoType SCIP_BENDERSENFOTYPE
Definition: type_benders.h:42
Generates a standard Benders&#39; decomposition optimality cut.
public methods for problem variables
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:47
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:95
SCIP_RETCODE SCIPcheckBendersSubproblemOptimality(SCIP *scip, SCIP_BENDERS *benders, SCIP_SOL *sol, int probnumber, SCIP_Bool *optimal)
Definition: scip_benders.c:853
#define BENDERSCUT_PRIORITY
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:123
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:78
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:83
public methods for SCIP variables
#define SCIPdebugMsg
Definition: scip_message.h:69
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip_lp.c:158
#define BENDERSCUT_NAME
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
public methods for numerical tolerances
SCIP_RETCODE SCIPincludeBenderscutOpt(SCIP *scip, SCIP_BENDERS *benders)
SCIP_RETCODE SCIPsetConsRemovable(SCIP *scip, SCIP_CONS *cons, SCIP_Bool removable)
Definition: scip_cons.c:1410
SCIP_RETCODE SCIPgetBendersMasterVar(SCIP *scip, SCIP_BENDERS *benders, SCIP_VAR *var, SCIP_VAR **mappedvar)
Definition: scip_benders.c:622
const char * SCIPbenderscutGetName(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:508
SCIP * SCIPbendersSubproblem(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:4265
#define BENDERSCUT_DESC
SCIP_EXPORT SCIP_Real SCIPvarGetSol(SCIP_VAR *var, SCIP_Bool getlpval)
Definition: var.c:12749
SCIP_VAR ** SCIPgetFixedVars(SCIP *scip)
Definition: scip_prob.c:2261
public methods for Benders decomposition
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip_lp.c:1406
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1942
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:87
static SCIP_RETCODE addAuxiliaryVariableToCut(SCIP *masterprob, SCIP_BENDERS *benders, SCIP_VAR **vars, SCIP_Real *vals, int *nvars, int probnumber)
void SCIPbenderscutSetData(SCIP_BENDERSCUT *benderscut, SCIP_BENDERSCUTDATA *benderscutdata)
Definition: benderscut.c:429
int SCIPgetNFixedVars(SCIP *scip)
Definition: scip_prob.c:2304
static SCIP_RETCODE computeStandardOptimalityCut(SCIP *masterprob, SCIP *subproblem, SCIP_BENDERS *benders, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real *lhs, SCIP_Real *rhs, int *nvars, SCIP_Real *checkobj, SCIP_Bool *success)
#define SCIP_CALL(x)
Definition: def.h:365
SCIP_RETCODE SCIPincludeBenderscutBasic(SCIP *scip, SCIP_BENDERS *benders, SCIP_BENDERSCUT **benderscutptr, const char *name, const char *desc, int priority, SCIP_Bool islpcut, SCIP_DECL_BENDERSCUTEXEC((*benderscutexec)), SCIP_BENDERSCUTDATA *benderscutdata)
public methods for constraint handler plugins and constraints
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition: scip_param.c:259
static SCIP_RETCODE polishSolution(SCIP *subproblem, SCIP_Bool *success)
SCIP_Real SCIPinfinity(SCIP *scip)
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:70
void SCIPconsGetDualsol(SCIP *scip, SCIP_CONS *cons, SCIP_Real *dualsol, SCIP_Bool *success)
Definition: misc_linear.c:347
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:16966
SCIP_EXPORT SCIP_Real SCIPvarGetUnchangedObj(SCIP_VAR *var)
Definition: var.c:17210
SCIP_RETCODE SCIPcreateEmptyRowCons(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:1268
public methods for LP management
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
public methods for cuts and aggregation rows
SCIP_Real SCIPgetActivityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
Constraint handler for linear constraints in their most general form, .
SCIP_EXPORT SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17408
public methods for the LP relaxation, rows and columns
public methods for Benders&#39; decomposition cuts
SCIP_RETCODE SCIPstoreBenderscutCut(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, int nvars)
SCIP_RETCODE SCIPsetBenderscutFree(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTFREE((*benderscutfree)))
SCIP_EXPORT SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17418
#define SCIP_DEFAULT_ADDCUTS
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition: scip_cut.c:220
general public methods
static SCIP_DECL_BENDERSCUTFREE(benderscutFreeOpt)
public methods for the probing mode
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition: scip_lp.c:1539
public methods for message output
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10263
#define SCIP_Real
Definition: def.h:164
public methods for message handling
SCIP_BENDERSCUTDATA * SCIPbenderscutGetData(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:419
static SCIP_RETCODE generateAndApplyBendersCuts(SCIP *masterprob, SCIP *subproblem, SCIP_BENDERS *benders, SCIP_BENDERSCUT *benderscut, SCIP_SOL *sol, int probnumber, SCIP_BENDERSENFOTYPE type, SCIP_RESULT *result)
static SCIP_DECL_BENDERSCUTEXEC(benderscutExecOpt)
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2765
SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
Definition: scip_cut.c:331
const char * SCIPbendersGetName(SCIP_BENDERS *benders)
Definition: benders.c:4211
SCIP_RETCODE SCIPaddVarsToRow(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_lp.c:1565
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:198
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1109
SCIP_RETCODE SCIPsetConsDynamic(SCIP *scip, SCIP_CONS *cons, SCIP_Bool dynamic)
Definition: scip_cons.c:1385
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:355
#define SCIPABORT()
Definition: def.h:337
public methods for global and local (sub)problems
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip_param.c:496
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:801
SCIP_Real SCIPgetRowSolActivity(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip_lp.c:1982