Scippy

SCIP

Solving Constraint Integer Programs

benderscut_int.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-2018 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_int.c
17  * @brief Generates a Laporte and Louveaux Benders' decomposition integer 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_int.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_paramset.h"
31 #include "scip/scip_benders.h"
32 #include "scip/scip_cons.h"
33 #include "scip/scip_cut.h"
34 #include "scip/scip_general.h"
35 #include "scip/scip_lp.h"
36 #include "scip/scip_mem.h"
37 #include "scip/scip_message.h"
38 #include "scip/scip_numerics.h"
39 #include "scip/scip_param.h"
40 #include "scip/scip_prob.h"
41 #include "scip/scip_sol.h"
42 #include <string.h>
43 
44 #define BENDERSCUT_NAME "integer"
45 #define BENDERSCUT_DESC "Laporte and Louveaux Benders' decomposition integer cut"
46 #define BENDERSCUT_PRIORITY 0
47 #define BENDERSCUT_LPCUT FALSE
48 
49 #define SCIP_DEFAULT_ADDCUTS FALSE /** Should cuts be generated, instead of constraints */
50 #define SCIP_DEFAULT_CUTCONSTANT -10000.0
51 
52 /*
53  * Data structures
54  */
55 
56 /** Benders' decomposition cuts data */
57 struct SCIP_BenderscutData
58 {
59  SCIP_BENDERS* benders; /**< the Benders' decomposition data structure */
60  SCIP_Real cutconstant; /**< the constant for computing the integer cuts */
61  SCIP_Real* subprobconstant; /**< the constant for each subproblem used for computing the integer cuts */
62  SCIP_Bool addcuts; /**< should cuts be generated instead of constraints */
63  SCIP_Bool* firstcut; /**< flag to indicate that the first cut needs to be generated. */
64  int nsubproblems; /**< the number of subproblems for the Benders' decomposition */
65 };
66 
67 /** method to call, when the priority of a Benders' decomposition was changed */
68 static
69 SCIP_DECL_PARAMCHGD(paramChgdBenderscutintConstant)
70 { /*lint --e{715}*/
71  SCIP_BENDERSCUTDATA* benderscutdata;
72  int i;
73 
74  benderscutdata = (SCIP_BENDERSCUTDATA*)SCIPparamGetData(param);
75  assert(benderscutdata != NULL);
76 
77  for( i = 0; i < benderscutdata->nsubproblems; i++ )
78  benderscutdata->subprobconstant[i] = benderscutdata->cutconstant;
79 
80  return SCIP_OKAY;
81 }
82 
83 
84 /** creates the Benders' decomposition cut data */
85 static
87  SCIP* scip, /**< the SCIP data structure */
88  SCIP_BENDERSCUTDATA* benderscutdata /**< the Benders' cut data */
89  )
90 {
91  int i;
92 
93  assert(scip != NULL);
94  assert(benderscutdata != NULL);
95 
96  /* allocating the memory for the subproblem constants */
97  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &benderscutdata->subprobconstant, benderscutdata->nsubproblems) );
98  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &benderscutdata->firstcut, benderscutdata->nsubproblems) );
99 
100  for( i = 0; i < benderscutdata->nsubproblems; i++ )
101  {
102  benderscutdata->subprobconstant[i] = benderscutdata->cutconstant;
103  benderscutdata->firstcut[i] = TRUE;
104  }
105 
106  return SCIP_OKAY;
107 }
108 
109 /*
110  * Local methods
111  */
112 
113 /** computes a standard Benders' optimality cut from the dual solutions of the LP */
114 static
116  SCIP* masterprob, /**< the SCIP instance of the master problem */
117  SCIP_BENDERS* benders, /**< the benders' decomposition structure */
118  SCIP_SOL* sol, /**< primal CIP solution */
119  SCIP_CONS* cons, /**< the constraint for the generated cut, can be NULL */
120  SCIP_ROW* row, /**< the row for the generated cut, can be NULL */
121  SCIP_Real cutconstant, /**< the constant value in the integer optimality cut */
122  int probnumber, /**< the number of the pricing problem */
123  SCIP_Bool addcut, /**< indicates whether a cut is created instead of a constraint */
124  SCIP_Bool* success /**< was the cut generation successful? */
125  )
126 {
127  SCIP_VAR** vars;
128  int nvars;
129  SCIP_Real subprobobj; /* the objective function value of the subproblem */
130  SCIP_Real lhs; /* the left hand side of the cut */
131  int i;
132  SCIP* subproblem;
133  SCIP_SOL* subprobsol;
134 
135 #ifndef NDEBUG
136  SCIP_Real verifyobj = 0;
137 #endif
138 
139  assert(masterprob != NULL);
140  assert(benders != NULL);
141  assert(cons != NULL || addcut);
142  assert(row != NULL || !addcut);
143 
144  (*success) = FALSE;
145 
146  /* getting the best solution from the subproblem */
147 
148 #ifdef SCIP_DEBUG
149  subproblem = SCIPbendersSubproblem(benders, probnumber);
150  subprobsol = SCIPgetBestSol(subproblem);
151 #endif
152 
153  subprobobj = SCIPbendersGetSubproblemObjval(benders, probnumber);
154 
155  SCIPdebugMsg(masterprob, "Subproblem %d - Objective Value: Stored - %g Orig Obj - %g\n", probnumber,
156  SCIPbendersGetSubproblemObjval(benders, probnumber), SCIPgetSolOrigObj(subproblem, subprobsol));
157 
158  nvars = SCIPgetNVars(masterprob);
159  vars = SCIPgetVars(masterprob);
160 
161  /* adding the subproblem objective function value to the lhs */
162  if( addcut )
163  lhs = SCIProwGetLhs(row);
164  else
165  lhs = SCIPgetLhsLinear(masterprob, cons);
166 
167  /* looping over all master problem variables to update the coefficients in the computed cut. */
168  for( i = 0; i < nvars; i++ )
169  {
170  SCIP_VAR* subprobvar;
171  SCIP_Real coef;
172 
173  SCIP_CALL( SCIPgetBendersSubproblemVar(masterprob, benders, vars[i], &subprobvar, probnumber) );
174 
175  /* if there is a corresponding subproblem variable, then the variable will not be NULL. */
176  if( subprobvar != NULL )
177  {
178  /* if the variable is on its upper bound, then the subproblem objective value is added to the cut */
179  if( SCIPisFeasEQ(masterprob, SCIPgetSolVal(masterprob, sol, vars[i]), 1.0) )
180  {
181  coef = -(subprobobj - cutconstant);
182  lhs -= (subprobobj - cutconstant);
183  }
184  else
185  coef = (subprobobj - cutconstant);
186 
187  /* adding the variable to the cut. The coefficient is the subproblem objective value */
188  if( addcut )
189  {
190  SCIP_CALL( SCIPaddVarToRow(masterprob, row, vars[i], coef) );
191  }
192  else
193  {
194  SCIP_CALL( SCIPaddCoefLinear(masterprob, cons, vars[i], coef) );
195  }
196  }
197  }
198 
199  lhs += subprobobj;
200 
201  /* if the bound becomes infinite, then the cut generation terminates. */
202  if( SCIPisInfinity(masterprob, lhs) || SCIPisInfinity(masterprob, -lhs) )
203  {
204  (*success) = FALSE;
205  SCIPdebugMsg(masterprob, "Infinite bound when generating integer optimality cut.\n");
206  return SCIP_OKAY;
207  }
208 
209  /* Update the lhs of the cut */
210  if( addcut )
211  {
212  SCIP_CALL( SCIPchgRowLhs(masterprob, row, lhs) );
213  }
214  else
215  {
216  SCIP_CALL( SCIPchgLhsLinear(masterprob, cons, lhs) );
217  }
218 
219 #ifndef NDEBUG
220  if( addcut )
221  lhs = SCIProwGetLhs(row);
222  else
223  lhs = SCIPgetLhsLinear(masterprob, cons);
224  verifyobj += lhs;
225 
226  if( addcut )
227  verifyobj -= SCIPgetRowSolActivity(masterprob, row, sol);
228  else
229  verifyobj -= SCIPgetActivityLinear(masterprob, cons, sol);
230 #endif
231 
232  assert(SCIPisFeasEQ(masterprob, verifyobj, subprobobj));
233 
234  (*success) = TRUE;
235 
236  return SCIP_OKAY;
237 }
238 
239 
240 /** adds the auxiliary variable to the generated cut. If this is the first optimality cut for the subproblem, then the
241  * auxiliary variable is first created and added to the master problem.
242  */
243 static
245  SCIP* masterprob, /**< the SCIP instance of the master problem */
246  SCIP_BENDERS* benders, /**< the benders' decomposition structure */
247  SCIP_CONS* cons, /**< the constraint for the generated cut, can be NULL */
248  SCIP_ROW* row, /**< the row for the generated cut, can be NULL */
249  int probnumber, /**< the number of the pricing problem */
250  SCIP_Bool addcut /**< indicates whether a cut is created instead of a constraint */
251  )
252 {
253  SCIP_VAR* auxiliaryvar;
254 
255  assert(masterprob != NULL);
256  assert(benders != NULL);
257  assert(cons != NULL || addcut);
258  assert(row != NULL || !addcut);
259 
260  auxiliaryvar = SCIPbendersGetAuxiliaryVar(benders, probnumber);
261 
262  /* adding the auxiliary variable to the generated cut */
263  if( addcut )
264  {
265  SCIP_CALL( SCIPaddVarToRow(masterprob, row, auxiliaryvar, 1.0) );
266  }
267  else
268  {
269  SCIP_CALL( SCIPaddCoefLinear(masterprob, cons, auxiliaryvar, 1.0) );
270  }
271 
272  return SCIP_OKAY;
273 }
274 
275 
276 /** generates and applies Benders' cuts */
277 static
279  SCIP* masterprob, /**< the SCIP instance of the master problem */
280  SCIP_BENDERS* benders, /**< the benders' decomposition */
281  SCIP_BENDERSCUT* benderscut, /**< the benders' decomposition cut method */
282  SCIP_SOL* sol, /**< primal CIP solution */
283  int probnumber, /**< the number of the pricing problem */
284  SCIP_BENDERSENFOTYPE type, /**< the enforcement type calling this function */
285  SCIP_RESULT* result, /**< the result from solving the subproblems */
286  SCIP_Bool initcons /**< is this function called to generate the initial constraint */
287  )
288 {
289  SCIP_BENDERSCUTDATA* benderscutdata;
290  SCIP_CONSHDLR* consbenders;
291  SCIP_CONS* cons;
292  SCIP_ROW* row;
293  char cutname[SCIP_MAXSTRLEN];
294  SCIP_Bool optimal;
295  SCIP_Bool addcut;
296  SCIP_Bool success;
297 
298  assert(masterprob != NULL);
299  assert(benders != NULL);
300  assert(benderscut != NULL);
301  assert(result != NULL);
302 
303  row = NULL;
304  cons = NULL;
305 
306  success = FALSE;
307 
308  /* retrieving the Benders' cut data */
309  benderscutdata = SCIPbenderscutGetData(benderscut);
310 
311  /* if the cuts are generated prior to the solving stage, then rows can not be generated. So constraints must be added
312  * to the master problem.
313  */
314  if( SCIPgetStage(masterprob) < SCIP_STAGE_INITSOLVE )
315  addcut = FALSE;
316  else
317  addcut = benderscutdata->addcuts;
318 
319  /* retrieving the Benders' decomposition constraint handler */
320  consbenders = SCIPfindConshdlr(masterprob, "benders");
321 
322  /* checking the optimality of the original problem with a comparison between the auxiliary variable and the
323  * objective value of the subproblem
324  */
325  optimal = FALSE;
326  SCIP_CALL( SCIPcheckBendersSubproblemOptimality(masterprob, benders, sol, probnumber, &optimal) );
327 
328  if( optimal )
329  {
330  (*result) = SCIP_FEASIBLE;
331  SCIPdebugMsg(masterprob, "No <%s> cut added. Current Master Problem Obj: %g\n", BENDERSCUT_NAME,
332  SCIPgetSolOrigObj(masterprob, NULL));
333  return SCIP_OKAY;
334  }
335 
336  /* checking if the subproblem lower bound has been updated. If it is has changed, then firstcut is set to TRUE.
337  * Otherwise, the constant remains the same.
338  */
339  if( SCIPisLT(masterprob, benderscutdata->subprobconstant[probnumber],
340  SCIPbendersGetSubproblemLowerbound(benders, probnumber)) )
341  {
342  benderscutdata->subprobconstant[probnumber] = SCIPbendersGetSubproblemLowerbound(benders, probnumber);
343  benderscutdata->firstcut[probnumber] = TRUE;
344  }
345 
346  /* if no integer cuts have been previously generated, then an initial lower bounding cut is added */
347  if( benderscutdata->firstcut[probnumber] )
348  {
349  benderscutdata->firstcut[probnumber] = FALSE;
350  SCIP_CALL( generateAndApplyBendersIntegerCuts(masterprob, benders, benderscut, sol, probnumber, type, result,
351  TRUE) );
352  }
353 
354  /* setting the name of the generated cut */
355  (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "integeroptcut_%d_%d", probnumber,
356  SCIPbenderscutGetNFound(benderscut) );
357 
358  /* creating an empty row or constraint for the Benders' cut */
359  if( addcut )
360  {
361  SCIP_CALL( SCIPcreateEmptyRowCons(masterprob, &row, consbenders, cutname, 0.0, SCIPinfinity(masterprob), FALSE,
362  FALSE, TRUE) );
363  }
364  else
365  {
366  SCIP_CALL( SCIPcreateConsBasicLinear(masterprob, &cons, cutname, 0, NULL, NULL, 0.0, SCIPinfinity(masterprob)) );
367  SCIP_CALL( SCIPsetConsDynamic(masterprob, cons, TRUE) );
368  SCIP_CALL( SCIPsetConsRemovable(masterprob, cons, TRUE) );
369  }
370 
371  if( initcons )
372  {
373  SCIP_Real lhs;
374 
375  /* adding the subproblem objective function value to the lhs */
376  if( addcut )
377  lhs = SCIProwGetLhs(row);
378  else
379  lhs = SCIPgetLhsLinear(masterprob, cons);
380 
381  lhs += benderscutdata->subprobconstant[probnumber];
382 
383  /* if the bound becomes infinite, then the cut generation terminates. */
384  if( SCIPisInfinity(masterprob, lhs) || SCIPisInfinity(masterprob, -lhs) )
385  {
386  success = FALSE;
387  SCIPdebugMsg(masterprob, "Infinite bound when generating integer optimality cut.\n");
388  }
389 
390  /* Update the lhs of the cut */
391  if( addcut )
392  {
393  SCIP_CALL( SCIPchgRowLhs(masterprob, row, lhs) );
394  }
395  else
396  {
397  SCIP_CALL( SCIPchgLhsLinear(masterprob, cons, lhs) );
398  }
399  }
400  else
401  {
402  /* computing the coefficients of the optimality cut */
403  SCIP_CALL( computeStandardIntegerOptCut(masterprob, benders, sol, cons, row,
404  benderscutdata->subprobconstant[probnumber], probnumber, addcut, &success) );
405  }
406 
407  /* if success is FALSE, then there was an error in generating the integer optimality cut. No cut will be added to
408  * the master problem. Otherwise, the constraint is added to the master problem.
409  */
410  if( !success )
411  {
412  (*result) = SCIP_DIDNOTFIND;
413  SCIPdebugMsg(masterprob, "Error in generating Benders' integer optimality cut for problem %d.\n", probnumber);
414  }
415  else
416  {
417  /* adding the auxiliary variable to the optimality cut */
418  SCIP_CALL( addAuxiliaryVariableToCut(masterprob, benders, cons, row, probnumber, addcut) );
419 
420  /* adding the constraint to the master problem */
421  if( addcut )
422  {
423  SCIP_Bool infeasible;
424 
425  if( type == SCIP_BENDERSENFOTYPE_LP || type == SCIP_BENDERSENFOTYPE_RELAX )
426  {
427  SCIP_CALL( SCIPaddRow(masterprob, row, FALSE, &infeasible) );
428  assert(!infeasible);
429  }
430  else
431  {
432  assert(type == SCIP_BENDERSENFOTYPE_CHECK || type == SCIP_BENDERSENFOTYPE_PSEUDO);
433  SCIP_CALL( SCIPaddPoolCut(masterprob, row) );
434  }
435 
436  /* storing the generated cut */
437  SCIP_CALL( SCIPstoreBenderscutCut(masterprob, benderscut, row) );
438 
439 #ifdef SCIP_DEBUG
440  SCIP_CALL( SCIPprintRow(masterprob, row, NULL) );
441  SCIPinfoMessage(masterprob, NULL, ";\n");
442 #endif
443 
444  (*result) = SCIP_SEPARATED;
445  }
446  else
447  {
448  SCIP_CALL( SCIPaddCons(masterprob, cons) );
449 
450  /* storing the generated cut */
451  SCIP_CALL( SCIPstoreBenderscutCons(masterprob, benderscut, cons) );
452 
453  SCIPdebugPrintCons(masterprob, cons, NULL);
454 
455  (*result) = SCIP_CONSADDED;
456  }
457  }
458 
459  if( addcut )
460  {
461  /* release the row */
462  SCIP_CALL( SCIPreleaseRow(masterprob, &row) );
463  }
464  else
465  {
466  /* release the constraint */
467  SCIP_CALL( SCIPreleaseCons(masterprob, &cons) );
468  }
469 
470  return SCIP_OKAY;
471 }
472 
473 /*
474  * Callback methods of Benders' decomposition cuts
475  */
476 
477 /** destructor of Benders' decomposition cuts to free user data (called when SCIP is exiting) */
478 static
479 SCIP_DECL_BENDERSCUTFREE(benderscutFreeInt)
480 { /*lint --e{715}*/
481  SCIP_BENDERSCUTDATA* benderscutdata;
482 
483  assert( benderscut != NULL );
484  assert( strcmp(SCIPbenderscutGetName(benderscut), BENDERSCUT_NAME) == 0 );
485 
486  /* free Benders' cut data */
487  benderscutdata = SCIPbenderscutGetData(benderscut);
488  assert( benderscutdata != NULL );
489 
490  SCIPfreeBlockMemory(scip, &benderscutdata);
491 
492  SCIPbenderscutSetData(benderscut, NULL);
493 
494  return SCIP_OKAY;
495 }
496 
497 
498 /** initialization method of Benders' decomposition cuts (called after problem was transformed) */
499 static
500 SCIP_DECL_BENDERSCUTINIT(benderscutInitInt)
501 { /*lint --e{715}*/
502  SCIP_BENDERSCUTDATA* benderscutdata;
503 
504  assert( benderscut != NULL );
505  assert( strcmp(SCIPbenderscutGetName(benderscut), BENDERSCUT_NAME) == 0 );
506 
507  /* free Benders' cut data */
508  benderscutdata = SCIPbenderscutGetData(benderscut);
509  assert( benderscutdata != NULL );
510 
511  benderscutdata->nsubproblems = SCIPbendersGetNSubproblems(benderscutdata->benders);
512  SCIP_CALL( createBenderscutData(scip, benderscutdata) );
513 
514  return SCIP_OKAY;
515 }
516 
517 /** deinitialization method of Benders' decomposition cuts (called before transformed problem is freed) */
518 static
519 SCIP_DECL_BENDERSCUTEXIT(benderscutExitInt)
520 { /*lint --e{715}*/
521  SCIP_BENDERSCUTDATA* benderscutdata;
522 
523  assert( benderscut != NULL );
524  assert( strcmp(SCIPbenderscutGetName(benderscut), BENDERSCUT_NAME) == 0 );
525 
526  /* free Benders' cut data */
527  benderscutdata = SCIPbenderscutGetData(benderscut);
528  assert( benderscutdata != NULL );
529 
530  SCIPfreeBlockMemoryArray(scip, &benderscutdata->firstcut, benderscutdata->nsubproblems);
531  SCIPfreeBlockMemoryArray(scip, &benderscutdata->subprobconstant, benderscutdata->nsubproblems);
532 
533  return SCIP_OKAY;
534 }
535 
536 /** execution method of Benders' decomposition cuts */
537 static
538 SCIP_DECL_BENDERSCUTEXEC(benderscutExecInt)
539 { /*lint --e{715}*/
540  assert(scip != NULL);
541  assert(benders != NULL);
542  assert(benderscut != NULL);
543  assert(result != NULL);
544 
545  /* it is only possible to generate the Laporte and Louveaux cuts for pure binary master problems */
547  {
548  SCIPinfoMessage(scip, NULL, "The integer optimality cuts can only be applied to problems with a "
549  "pure binary master problem. The integer optimality cuts will be disabled.\n");
550 
551  SCIPbenderscutSetEnabled(benderscut, FALSE);
552 
553  return SCIP_OKAY;
554  }
555 
556  /* the integer subproblem could terminate early if the auxiliary variable value is much greater than the optimal
557  * solution. As such, it is only necessary to generate a cut if the subproblem is OPTIMAL */
558  if( SCIPgetStatus(SCIPbendersSubproblem(benders, probnumber)) == SCIP_STATUS_OPTIMAL )
559  {
560  /* generating a cut for a given subproblem */
561  SCIP_CALL( generateAndApplyBendersIntegerCuts(scip, benders, benderscut, sol, probnumber, type, result, FALSE) );
562  }
563 
564  return SCIP_OKAY;
565 }
566 
567 
568 /*
569  * Benders' decomposition cuts specific interface methods
570  */
571 
572 /** creates the int Benders' decomposition cuts and includes it in SCIP */
574  SCIP* scip, /**< SCIP data structure */
575  SCIP_BENDERS* benders /**< Benders' decomposition */
576  )
577 {
578  SCIP_BENDERSCUTDATA* benderscutdata;
579  SCIP_BENDERSCUT* benderscut;
580  char paramname[SCIP_MAXSTRLEN];
581 
582  assert(benders != NULL);
583 
584  /* create int Benders' decomposition cuts data */
585  SCIP_CALL( SCIPallocBlockMemory(scip, &benderscutdata) );
586  benderscutdata->benders = benders;
587 
588  benderscut = NULL;
589 
590  /* include Benders' decomposition cuts */
592  BENDERSCUT_PRIORITY, BENDERSCUT_LPCUT, benderscutExecInt, benderscutdata) );
593 
594  assert(benderscut != NULL);
595 
596  /* set non fundamental callbacks via setter functions */
597  SCIP_CALL( SCIPsetBenderscutFree(scip, benderscut, benderscutFreeInt) );
598  SCIP_CALL( SCIPsetBenderscutInit(scip, benderscut, benderscutInitInt) );
599  SCIP_CALL( SCIPsetBenderscutExit(scip, benderscut, benderscutExitInt) );
600 
601  /* add int Benders' decomposition cuts parameters */
602  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "benders/%s/benderscut/%s/cutsconstant",
604  SCIP_CALL( SCIPaddRealParam(scip, paramname,
605  "the constant term of the integer Benders' cuts.",
606  &benderscutdata->cutconstant, FALSE, SCIP_DEFAULT_CUTCONSTANT, -SCIPinfinity(scip), SCIPinfinity(scip),
607  paramChgdBenderscutintConstant, (SCIP_PARAMDATA*)benderscutdata) );
608 
609  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "benders/%s/benderscut/%s/addcuts",
611  SCIP_CALL( SCIPaddBoolParam(scip, paramname,
612  "should cuts be generated and added to the cutpool instead of global constraints directly added to the problem.",
613  &benderscutdata->addcuts, FALSE, SCIP_DEFAULT_ADDCUTS, NULL, NULL) );
614 
615  return SCIP_OKAY;
616 }
SCIP_RETCODE SCIPstoreBenderscutCut(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_ROW *cut)
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
Generates a Laporte and Louveaux Benders&#39; decomposition integer cut.
SCIP_RETCODE SCIPincludeBenderscutInt(SCIP *scip, SCIP_BENDERS *benders)
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:116
SCIP_Real SCIPgetActivityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
const char * SCIPbenderscutGetName(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:489
#define NULL
Definition: def.h:239
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)
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:99
SCIP_Real SCIPbendersGetSubproblemObjval(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:4431
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
public methods for SCIP parameter handling
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:412
static SCIP_RETCODE generateAndApplyBendersIntegerCuts(SCIP *masterprob, SCIP_BENDERS *benders, SCIP_BENDERSCUT *benderscut, SCIP_SOL *sol, int probnumber, SCIP_BENDERSENFOTYPE type, SCIP_RESULT *result, SCIP_Bool initcons)
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)
struct SCIP_BenderscutData SCIP_BENDERSCUTDATA
public methods for memory management
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:954
static SCIP_DECL_BENDERSCUTFREE(benderscutFreeInt)
SCIP_BENDERSCUTDATA * SCIPbenderscutGetData(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:400
static SCIP_DECL_PARAMCHGD(paramChgdBenderscutintConstant)
SCIP_PARAMDATA * SCIPparamGetData(SCIP_PARAM *param)
Definition: paramset.c:661
#define SCIP_MAXSTRLEN
Definition: def.h:260
const char * SCIPbendersGetName(SCIP_BENDERS *benders)
Definition: benders.c:4194
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition: scip_lp.c:1602
#define BENDERSCUT_NAME
struct SCIP_ParamData SCIP_PARAMDATA
Definition: type_paramset.h:76
void SCIPbenderscutSetData(SCIP_BENDERSCUT *benderscut, SCIP_BENDERSCUTDATA *benderscutdata)
Definition: benderscut.c:410
static SCIP_RETCODE createBenderscutData(SCIP *scip, SCIP_BENDERSCUTDATA *benderscutdata)
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:16869
#define FALSE
Definition: def.h:65
public methods for Benders&#39; decomposition
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10017
#define TRUE
Definition: def.h:64
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
enum SCIP_BendersEnfoType SCIP_BENDERSENFOTYPE
Definition: type_benders.h:42
static SCIP_RETCODE addAuxiliaryVariableToCut(SCIP *masterprob, SCIP_BENDERS *benders, SCIP_CONS *cons, SCIP_ROW *row, int probnumber, SCIP_Bool addcut)
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:114
#define BENDERSCUT_PRIORITY
#define BENDERSCUT_DESC
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:97
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:83
SCIP_RETCODE SCIPgetBendersSubproblemVar(SCIP *scip, SCIP_BENDERS *benders, SCIP_VAR *var, SCIP_VAR **mappedvar, int probnumber)
Definition: scip_benders.c:739
#define SCIPdebugMsg
Definition: scip_message.h:88
SCIP_Longint SCIPbenderscutGetNFound(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:540
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:279
#define BENDERSCUT_LPCUT
public methods for numerical tolerances
public methods for handling parameter settings
SCIP_RETCODE SCIPsetConsRemovable(SCIP *scip, SCIP_CONS *cons, SCIP_Bool removable)
Definition: scip_cons.c:1488
void SCIPbenderscutSetEnabled(SCIP_BENDERSCUT *benderscut, SCIP_Bool enabled)
Definition: benderscut.c:687
public methods for Benders decomposition
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2822
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip_general.c:519
static SCIP_RETCODE computeStandardIntegerOptCut(SCIP *masterprob, SCIP_BENDERS *benders, SCIP_SOL *sol, SCIP_CONS *cons, SCIP_ROW *row, SCIP_Real cutconstant, int probnumber, SCIP_Bool addcut, SCIP_Bool *success)
SCIP_RETCODE SCIPsetConsDynamic(SCIP *scip, SCIP_CONS *cons, SCIP_Bool dynamic)
Definition: scip_cons.c:1463
#define SCIP_CALL(x)
Definition: def.h:351
SCIP_RETCODE SCIPsetBenderscutExit(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTEXIT((*benderscutexit)))
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition: scip_cut.c:294
public methods for constraint handler plugins and constraints
static SCIP_DECL_BENDERSCUTEXEC(benderscutExecInt)
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:62
static SCIP_DECL_BENDERSCUTINIT(benderscutInitInt)
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:1336
SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
Definition: scip_cut.c:405
public methods for LP management
SCIP_RETCODE SCIPchgRowLhs(SCIP *scip, SCIP_ROW *row, SCIP_Real lhs)
Definition: scip_lp.c:1495
public methods for cuts and aggregation rows
SCIP_RETCODE SCIPstoreBenderscutCons(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_CONS *cons)
#define SCIP_DEFAULT_ADDCUTS
SCIP * SCIPbendersSubproblem(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:4248
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1493
Constraint handler for linear constraints in their most general form, .
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPgetRowSolActivity(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip_lp.c:2045
SCIP_RETCODE SCIPcheckBendersSubproblemOptimality(SCIP *scip, SCIP_BENDERS *benders, SCIP_SOL *sol, int probnumber, SCIP_Bool *optimal)
Definition: scip_benders.c:934
int SCIPbendersGetNSubproblems(SCIP_BENDERS *benders)
Definition: benders.c:4238
int SCIPgetNBinVars(SCIP *scip)
Definition: scip_prob.c:2089
public methods for the LP relaxation, rows and columns
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:2044
public methods for Benders&#39; decomposition cuts
SCIP_RETCODE SCIPsetBenderscutInit(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTINIT((*benderscutinit)))
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip_lp.c:1474
general public methods
SCIP_Real SCIPbendersGetSubproblemLowerbound(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:4751
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition: scip_sol.c:2379
public methods for solutions
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1187
public methods for message output
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1999
#define SCIP_Real
Definition: def.h:150
public methods for message handling
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
Definition: scip_lp.c:2094
SCIP_RETCODE SCIPsetBenderscutFree(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTFREE((*benderscutfree)))
SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
static SCIP_DECL_BENDERSCUTEXIT(benderscutExitInt)
#define SCIP_DEFAULT_CUTCONSTANT
SCIP_VAR * SCIPbendersGetAuxiliaryVar(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:4392
public methods for global and local (sub)problems
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1410
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, 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: scip_param.c:211
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:129