Scippy

SCIP

Solving Constraint Integer Programs

scip_benders.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 scip_benders.c
17  * @brief public methods for Benders decomposition
18  * @author Tobias Achterberg
19  * @author Timo Berthold
20  * @author Gerald Gamrath
21  * @author Robert Lion Gottwald
22  * @author Stefan Heinz
23  * @author Gregor Hendel
24  * @author Thorsten Koch
25  * @author Alexander Martin
26  * @author Marc Pfetsch
27  * @author Michael Winkler
28  * @author Kati Wolter
29  *
30  * @todo check all SCIP_STAGE_* switches, and include the new stages TRANSFORMED and INITSOLVE
31  */
32 
33 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
34 
35 #include "scip/benderscut.h"
36 #include "scip/benders.h"
37 #include "scip/debug.h"
38 #include "scip/pub_benders.h"
39 #include "scip/pub_message.h"
40 #include "scip/scip_benders.h"
41 #include "scip/set.h"
42 #include "scip/struct_mem.h"
43 #include "scip/struct_scip.h"
44 #include "scip/struct_set.h"
45 
46 /** creates a Benders' decomposition and includes it in SCIP
47  *
48  * To use the Benders' decomposition for solving a problem, it first has to be activated with a call to SCIPactivateBenders().
49  * This should be done during the problem creation stage.
50  *
51  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
52  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
53  *
54  * @pre This method can be called if SCIP is in one of the following stages:
55  * - \ref SCIP_STAGE_INIT
56  * - \ref SCIP_STAGE_PROBLEM
57  *
58  * @note method has all Benders' decomposition callbacks as arguments and is thus changed every time a new callback is
59  * added in future releases; consider using SCIPincludeBendersBasic() and setter functions
60  * if you seek for a method which is less likely to change in future releases
61  */
63  SCIP* scip, /**< SCIP data structure */
64  const char* name, /**< name of Benders' decomposition */
65  const char* desc, /**< description of Benders' decomposition */
66  int priority, /**< priority of the Benders' decomposition */
67  SCIP_Bool cutlp, /**< should Benders' cuts be generated for LP solutions */
68  SCIP_Bool cutpseudo, /**< should Benders' cuts be generated for pseudo solutions */
69  SCIP_Bool cutrelax, /**< should Benders' cuts be generated for relaxation solutions */
70  SCIP_Bool shareauxvars, /**< should this Benders' use the highest priority Benders aux vars */
71  SCIP_DECL_BENDERSCOPY ((*benderscopy)), /**< copy method of Benders' decomposition or NULL if you don't want to copy your plugin into sub-SCIPs */
72  SCIP_DECL_BENDERSFREE ((*bendersfree)), /**< destructor of Benders' decomposition */
73  SCIP_DECL_BENDERSINIT ((*bendersinit)), /**< initialize Benders' decomposition */
74  SCIP_DECL_BENDERSEXIT ((*bendersexit)), /**< deinitialize Benders' decomposition */
75  SCIP_DECL_BENDERSINITPRE((*bendersinitpre)),/**< presolving initialization method for Benders' decomposition */
76  SCIP_DECL_BENDERSEXITPRE((*bendersexitpre)),/**< presolving deinitialization method for Benders' decomposition */
77  SCIP_DECL_BENDERSINITSOL((*bendersinitsol)),/**< solving process initialization method of Benders' decomposition */
78  SCIP_DECL_BENDERSEXITSOL((*bendersexitsol)),/**< solving process deinitialization method of Benders' decomposition */
79  SCIP_DECL_BENDERSGETVAR((*bendersgetvar)),/**< returns the master variable for a given subproblem variable */
80  SCIP_DECL_BENDERSCREATESUB((*benderscreatesub)),/**< creates a Benders' decomposition subproblem */
81  SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve)),/**< the execution method of the Benders' decomposition algorithm */
82  SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex)),/**< the solving method for convex Benders' decomposition subproblems */
83  SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub)),/**< the solving method for the Benders' decomposition subproblems */
84  SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve)),/**< called after the subproblems are solved. */
85  SCIP_DECL_BENDERSFREESUB((*bendersfreesub)),/**< the freeing method for the Benders' decomposition subproblems */
86  SCIP_BENDERSDATA* bendersdata /**< Benders' decomposition data */
87  )
88 {
89  SCIP_BENDERS* benders;
90 
91  SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeBenders", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
92 
93  /* check whether pricer is already present */
94  if( SCIPfindBenders(scip, name) != NULL )
95  {
96  SCIPerrorMessage("benders <%s> already included.\n", name);
97  return SCIP_INVALIDDATA;
98  }
99 
100  /* Checking whether the benderssolvesub and the bendersfreesub are both implemented or both are not implemented */
101  if( (benderssolvesubconvex == NULL && benderssolvesub == NULL && bendersfreesub != NULL)
102  || ((benderssolvesubconvex != NULL || benderssolvesub != NULL) && bendersfreesub == NULL) )
103  {
104  SCIPerrorMessage("Benders' decomposition <%s> requires that if bendersFreesub%s is "
105  "implemented at least one of bendersSolvesubconvex%s or bendersSolvesub%s are implemented, "
106  "or if bendersFreesub%s is not implemented, then none are implented.\n", name, name, name, name, name);
107  return SCIP_INVALIDCALL;
108  }
109 
110  SCIP_CALL( SCIPbendersCreate(&benders, scip->set, scip->messagehdlr, scip->mem->setmem, name, desc, priority,
111  cutlp, cutpseudo, cutrelax, shareauxvars, benderscopy, bendersfree, bendersinit, bendersexit, bendersinitpre,
112  bendersexitpre, bendersinitsol, bendersexitsol, bendersgetvar, benderscreatesub, benderspresubsolve,
113  benderssolvesubconvex, benderssolvesub, benderspostsolve, bendersfreesub, bendersdata) );
114  SCIP_CALL( SCIPsetIncludeBenders(scip->set, benders) );
115 
116  return SCIP_OKAY;
117 }
118 
119 /** creates a Benders' decomposition and includes it in SCIP with all non-fundamental callbacks set to NULL
120  *
121  * If needed, the non-fundamental callbacks can be added afterwards via setter functions SCIPsetBendersCopy(),
122  * SCIPsetBendersFree(), SCIPsetBendersInity(), SCIPsetBendersExit(), SCIPsetBendersInitsol(), SCIPsetBendersExitsol(),
123  * SCIPsetBendersFarkas().
124  *
125  * To use the Benders' decomposition for solving a problem, it first has to be activated with a call to SCIPactivateBenders().
126  * This should be done during the problem creation stage.
127  *
128  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
129  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
130  *
131  * @pre This method can be called if SCIP is in one of the following stages:
132  * - \ref SCIP_STAGE_INIT
133  * - \ref SCIP_STAGE_PROBLEM
134  *
135  * @note if you want to set all callbacks with a single method call, consider using SCIPincludeBenders() instead
136  */
138  SCIP* scip, /**< SCIP data structure */
139  SCIP_BENDERS** bendersptr, /**< reference to a benders, or NULL */
140  const char* name, /**< name of Benders' decomposition */
141  const char* desc, /**< description of Benders' decomposition */
142  int priority, /**< priority of the Benders' decomposition */
143  SCIP_Bool cutlp, /**< should Benders' cuts be generated for LP solutions */
144  SCIP_Bool cutpseudo, /**< should Benders' cuts be generated for pseudo solutions */
145  SCIP_Bool cutrelax, /**< should Benders' cuts be generated for relaxation solutions */
146  SCIP_Bool shareauxvars, /**< should this Benders' use the highest priority Benders aux vars */
147  SCIP_DECL_BENDERSGETVAR((*bendersgetvar)),/**< returns the master variable for a given subproblem variable */
148  SCIP_DECL_BENDERSCREATESUB((*benderscreatesub)),/**< creates a Benders' decomposition subproblem */
149  SCIP_BENDERSDATA* bendersdata /**< Benders' decomposition data */
150  )
151 {
152  SCIP_BENDERS* benders;
153 
154  SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeBendersBasic", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
155 
156  /* check whether Benders' decomposition is already present */
157  if( SCIPfindBenders(scip, name) != NULL )
158  {
159  SCIPerrorMessage("benders <%s> already included.\n", name);
160  return SCIP_INVALIDDATA;
161  }
162 
163  SCIP_CALL( SCIPbendersCreate(&benders, scip->set, scip->messagehdlr, scip->mem->setmem, name, desc, priority,
164  cutlp, cutpseudo, cutrelax, shareauxvars, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, bendersgetvar,
165  benderscreatesub, NULL, NULL, NULL, NULL, NULL, bendersdata) );
166  SCIP_CALL( SCIPsetIncludeBenders(scip->set, benders) );
167 
168  if( bendersptr != NULL )
169  *bendersptr = benders;
170 
171  return SCIP_OKAY;
172 }
173 
174 /** sets copy method of benders
175  *
176  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
177  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
178  *
179  * @pre This method can be called if SCIP is in one of the following stages:
180  * - \ref SCIP_STAGE_INIT
181  * - \ref SCIP_STAGE_PROBLEM
182  */
184  SCIP* scip, /**< SCIP data structure */
185  SCIP_BENDERS* benders, /**< Benders' decomposition */
186  SCIP_DECL_BENDERSCOPY((*benderscopy)) /**< copy method of Benders' decomposition or NULL if you don't want to copy your plugin into sub-SCIPs */
187  )
188 {
189  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBendersCopy", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
190 
191  assert(benders != NULL);
192 
193  SCIPbendersSetCopy(benders, benderscopy);
194 
195  return SCIP_OKAY;
196 }
197 
198 /** sets destructor method of benders
199  *
200  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
201  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
202  *
203  * @pre This method can be called if SCIP is in one of the following stages:
204  * - \ref SCIP_STAGE_INIT
205  * - \ref SCIP_STAGE_PROBLEM
206  */
208  SCIP* scip, /**< SCIP data structure */
209  SCIP_BENDERS* benders, /**< Benders' decomposition */
210  SCIP_DECL_BENDERSFREE((*bendersfree)) /**< destructor of Benders' decomposition */
211  )
212 {
213  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBendersFree", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
214 
215  assert(benders != NULL);
216 
217  SCIPbendersSetFree(benders, bendersfree);
218 
219  return SCIP_OKAY;
220 }
221 
222 /** sets initialization method of benders
223  *
224  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
225  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
226  *
227  * @pre This method can be called if SCIP is in one of the following stages:
228  * - \ref SCIP_STAGE_INIT
229  * - \ref SCIP_STAGE_PROBLEM
230  */
232  SCIP* scip, /**< SCIP data structure */
233  SCIP_BENDERS* benders, /**< Benders' decomposition */
234  SCIP_DECL_BENDERSINIT ((*bendersinit)) /**< initialize Benders' decomposition */
235  )
236 {
237  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBendersInit", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
238 
239  assert(benders != NULL);
240 
241  SCIPbendersSetInit(benders, bendersinit);
242 
243  return SCIP_OKAY;
244 }
245 
246 /** sets deinitialization method of benders
247  *
248  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
249  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
250  *
251  * @pre This method can be called if SCIP is in one of the following stages:
252  * - \ref SCIP_STAGE_INIT
253  * - \ref SCIP_STAGE_PROBLEM
254  */
256  SCIP* scip, /**< SCIP data structure */
257  SCIP_BENDERS* benders, /**< Benders' decomposition */
258  SCIP_DECL_BENDERSEXIT ((*bendersexit)) /**< deinitialize Benders' decomposition */
259  )
260 {
261  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBendersExit", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
262 
263  assert(benders != NULL);
264 
265  SCIPbendersSetExit(benders, bendersexit);
266 
267  return SCIP_OKAY;
268 }
269 
270 /** sets presolving initialization method of benders
271  *
272  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
273  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
274  *
275  * @pre This method can be called if SCIP is in one of the following stages:
276  * - \ref SCIP_STAGE_INIT
277  * - \ref SCIP_STAGE_PROBLEM
278  */
280  SCIP* scip, /**< SCIP data structure */
281  SCIP_BENDERS* benders, /**< Benders' decomposition */
282  SCIP_DECL_BENDERSINITPRE((*bendersinitpre))/**< presolving initialization method of Benders' decomposition */
283  )
284 {
285  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBendersInitpre", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
286 
287  assert(benders != NULL);
288 
289  SCIPbendersSetInitpre(benders, bendersinitpre);
290 
291  return SCIP_OKAY;
292 }
293 
294 /** sets presolving deinitialization method of benders
295  *
296  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
297  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
298  *
299  * @pre This method can be called if SCIP is in one of the following stages:
300  * - \ref SCIP_STAGE_INIT
301  * - \ref SCIP_STAGE_PROBLEM
302  */
304  SCIP* scip, /**< SCIP data structure */
305  SCIP_BENDERS* benders, /**< Benders' decomposition */
306  SCIP_DECL_BENDERSEXITPRE((*bendersexitpre))/**< presolving deinitialization method of Benders' decomposition */
307  )
308 {
309  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBendersExitpre", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
310 
311  assert(benders != NULL);
312 
313  SCIPbendersSetExitpre(benders, bendersexitpre);
314 
315  return SCIP_OKAY;
316 }
317 
318 /** sets solving process initialization method of benders
319  *
320  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
321  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
322  *
323  * @pre This method can be called if SCIP is in one of the following stages:
324  * - \ref SCIP_STAGE_INIT
325  * - \ref SCIP_STAGE_PROBLEM
326  */
328  SCIP* scip, /**< SCIP data structure */
329  SCIP_BENDERS* benders, /**< Benders' decomposition */
330  SCIP_DECL_BENDERSINITSOL((*bendersinitsol))/**< solving process initialization method of Benders' decomposition */
331  )
332 {
333  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBendersInitsol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
334 
335  assert(benders != NULL);
336 
337  SCIPbendersSetInitsol(benders, bendersinitsol);
338 
339  return SCIP_OKAY;
340 }
341 
342 /** sets solving process deinitialization method of benders
343  *
344  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
345  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
346  *
347  * @pre This method can be called if SCIP is in one of the following stages:
348  * - \ref SCIP_STAGE_INIT
349  * - \ref SCIP_STAGE_PROBLEM
350  */
352  SCIP* scip, /**< SCIP data structure */
353  SCIP_BENDERS* benders, /**< Benders' decomposition */
354  SCIP_DECL_BENDERSEXITSOL((*bendersexitsol))/**< solving process deinitialization method of Benders' decomposition */
355  )
356 {
357  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBendersExitsol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
358 
359  assert(benders != NULL);
360 
361  SCIPbendersSetExitsol(benders, bendersexitsol);
362 
363  return SCIP_OKAY;
364 }
365 
366 /** sets the method called prior to solving the subproblems for benders
367  *
368  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
369  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
370  *
371  * @pre This method can be called if SCIP is in one of the following stages:
372  * - \ref SCIP_STAGE_INIT
373  * - \ref SCIP_STAGE_PROBLEM
374  */
376  SCIP* scip, /**< SCIP data structure */
377  SCIP_BENDERS* benders, /**< Benders' decomposition */
378  SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve))/**< method called prior to solving the subproblems */
379  )
380 {
381  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBendersPresubsolve", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
382 
383  assert(benders != NULL);
384 
385  SCIPbendersSetPresubsolve(benders, benderspresubsolve);
386 
387  return SCIP_OKAY;
388 }
389 
390 /** sets the subproblem solving and freeing methods for Benders' decomposition
391  *
392  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
393  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
394  *
395  * @pre This method can be called if SCIP is in one of the following stages:
396  * - \ref SCIP_STAGE_INIT
397  * - \ref SCIP_STAGE_PROBLEM
398  */
400  SCIP* scip, /**< SCIP data structure */
401  SCIP_BENDERS* benders, /**< Benders' decomposition */
402  SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex)),/**< the solving method for convex Benders' decomposition subproblems */
403  SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub)),/**< solving method for a Benders' decomposition subproblem */
404  SCIP_DECL_BENDERSFREESUB((*bendersfreesub))/**< the subproblem freeing method for Benders' decomposition */
405  )
406 {
407  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBendersSolveAndFreesub", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
408 
409  assert(benders != NULL);
410 
411  /* Checking whether the benderssolvesub and the bendersfreesub are both implemented or both are not implemented */
412  if( (benderssolvesubconvex == NULL && benderssolvesub == NULL && bendersfreesub != NULL)
413  || ((benderssolvesubconvex != NULL || benderssolvesub != NULL) && bendersfreesub == NULL) )
414  {
415  SCIPerrorMessage("Benders' decomposition <%s> requires that if bendersFreesub%s is "
416  "implemented at least one of bendersSolvesubconvex%s or bendersSolvesub%s are implemented, "
417  "or if bendersFreesub%s is not implemented, then none are implented.\n", SCIPbendersGetName(benders),
418  SCIPbendersGetName(benders), SCIPbendersGetName(benders), SCIPbendersGetName(benders),
419  SCIPbendersGetName(benders));
420  return SCIP_INVALIDCALL;
421  }
422 
423  SCIPbendersSetSolvesubconvex(benders, benderssolvesubconvex);
424  SCIPbendersSetSolvesub(benders, benderssolvesub);
425  SCIPbendersSetFreesub(benders, bendersfreesub);
426 
427  return SCIP_OKAY;
428 }
429 
430 /** sets the post solving methods for benders
431  *
432  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
433  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
434  *
435  * @pre This method can be called if SCIP is in one of the following stages:
436  * - \ref SCIP_STAGE_INIT
437  * - \ref SCIP_STAGE_PROBLEM
438  */
440  SCIP* scip, /**< SCIP data structure */
441  SCIP_BENDERS* benders, /**< Benders' decomposition */
442  SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve))/**< solving process deinitialization method of Benders' decomposition */
443  )
444 {
445  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBendersPostsolve", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
446 
447  assert(benders != NULL);
448 
449  SCIPbendersSetPostsolve(benders, benderspostsolve);
450 
451  return SCIP_OKAY;
452 }
453 
454 /** returns the Benders' decomposition of the given name, or NULL if not existing */
456  SCIP* scip, /**< SCIP data structure */
457  const char* name /**< name of Benders' decomposition */
458  )
459 {
460  assert(scip != NULL);
461  assert(scip->set != NULL);
462  assert(name != NULL);
463 
464  return SCIPsetFindBenders(scip->set, name);
465 }
466 
467 /** returns the array of currently available Benders' decomposition; active Benders' decomposition are in the first
468  * slots of the array
469  */
471  SCIP* scip /**< SCIP data structure */
472  )
473 {
474  assert(scip != NULL);
475  assert(scip->set != NULL);
476 
477  SCIPsetSortBenders(scip->set);
478 
479  return scip->set->benders;
480 }
481 
482 /** returns the number of currently available Benders' decomposition */
484  SCIP* scip /**< SCIP data structure */
485  )
486 {
487  assert(scip != NULL);
488  assert(scip->set != NULL);
489 
490  return scip->set->nbenders;
491 }
492 
493 /** returns the number of currently active Benders' decomposition */
495  SCIP* scip /**< SCIP data structure */
496  )
497 {
498  assert(scip != NULL);
499  assert(scip->set != NULL);
500 
501  return scip->set->nactivebenders;
502 }
503 
504 /** activates the Benders' decomposition to be used for the current problem
505  *
506  * This method should be called during the problem creation stage for all pricers that are necessary to solve
507  * the problem model.
508  *
509  * @note The Benders' decompositions are automatically deactivated when the problem is freed.
510  *
511  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
512  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
513  *
514  * @pre This method can be called if SCIP is in one of the following stages:
515  * - \ref SCIP_STAGE_PROBLEM
516  */
518  SCIP* scip, /**< SCIP data structure */
519  SCIP_BENDERS* benders, /**< the Benders' decomposition structure */
520  int nsubproblems /**< the number of subproblems in the Benders' decomposition */
521  )
522 {
523  SCIP_CALL( SCIPcheckStage(scip, "SCIPactivateBenders", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
524 
525  SCIP_CALL( SCIPbendersActivate(benders, scip->set, nsubproblems) );
526 
527  return SCIP_OKAY;
528 }
529 
530 /** deactivates the Benders' decomposition
531  *
532  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
533  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
534  *
535  * @pre This method can be called if SCIP is in one of the following stages:
536  * - \ref SCIP_STAGE_PROBLEM
537  * - \ref SCIP_STAGE_EXITSOLVE
538  */
540  SCIP* scip, /**< SCIP data structure */
541  SCIP_BENDERS* benders /**< the Benders' decomposition structure */
542  )
543 {
544  SCIP_CALL( SCIPcheckStage(scip, "SCIPdeactivateBenders", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE) );
545 
546  SCIPbendersDeactivate(benders, scip->set);
547 
548  return SCIP_OKAY;
549 }
550 
551 /** sets the priority of a Benders' decomposition */
553  SCIP* scip, /**< SCIP data structure */
554  SCIP_BENDERS* benders, /**< Benders' decomposition */
555  int priority /**< new priority of the Benders' decomposition */
556  )
557 {
558  assert(scip != NULL);
559  assert(scip->set != NULL);
560  assert(benders != NULL);
561 
562  SCIPbendersSetPriority(benders, scip->set, priority);
563 }
564 
565 /** calls the exec method of Benders' decomposition to solve the subproblems
566  *
567  * The checkint flag indicates whether integer feasibility can be assumed. If it is not assumed, i.e. checkint ==
568  * FALSE, then only the convex relaxations of the subproblems are solved. If integer feasibility is assumed, i.e.
569  * checkint == TRUE, then the convex relaxations and the full CIP are solved to generate Benders' cuts and check
570  * solution feasibility.
571  *
572  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
573  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
574  *
575  * @pre This method can be called if SCIP is in one of the following stages:
576  * - \ref SCIP_STAGE_INITPRESOLVE
577  * - \ref SCIP_STAGE_PRESOLVING
578  * - \ref SCIP_STAGE_EXITPRESOLVE
579  * - \ref SCIP_STAGE_PRESOLVED
580  * - \ref SCIP_STAGE_INITSOLVE
581  * - \ref SCIP_STAGE_SOLVING
582  * - \ref SCIP_STAGE_SOLVED
583  */
585  SCIP* scip, /**< SCIP data structure */
586  SCIP_BENDERS* benders, /**< Benders' decomposition */
587  SCIP_SOL* sol, /**< primal CIP solution, can be NULL */
588  SCIP_RESULT* result, /**< result of the pricing process */
589  SCIP_Bool* infeasible, /**< is the master problem infeasible with respect to the Benders' cuts? */
590  SCIP_Bool* auxviol, /**< set to TRUE only if the solution is feasible but the aux vars are violated */
591  SCIP_BENDERSENFOTYPE type, /**< the type of solution being enforced */
592  SCIP_Bool checkint /**< should the integer solution be checked by the subproblems */
593  )
594 {
595  assert(scip != NULL);
596  assert(scip->set != NULL);
597  assert(benders != NULL);
598 
599  SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveBendersSubproblems", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
600 
601  SCIP_CALL( SCIPbendersExec(benders, scip->set, sol, result, infeasible, auxviol, type, checkint) );
602 
603  return SCIP_OKAY;
604 }
605 
606 /** returns the master problem variable for the given subproblem variable
607  *
608  * This function is used as part of the cut generation process.
609  *
610  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
611  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
612  *
613  * @pre This method can be called if SCIP is in one of the following stages:
614  * - \ref SCIP_STAGE_INITPRESOLVE
615  * - \ref SCIP_STAGE_PRESOLVING
616  * - \ref SCIP_STAGE_EXITPRESOLVE
617  * - \ref SCIP_STAGE_PRESOLVED
618  * - \ref SCIP_STAGE_INITSOLVE
619  * - \ref SCIP_STAGE_SOLVING
620  * - \ref SCIP_STAGE_SOLVED
621  */
623  SCIP* scip, /**< SCIP data structure */
624  SCIP_BENDERS* benders, /**< Benders' decomposition */
625  SCIP_VAR* var, /**< the subproblem variable */
626  SCIP_VAR** mappedvar /**< pointer to store the master variable that var is mapped to */
627  )
628 {
629  assert(scip != NULL);
630  assert(scip->set != NULL);
631  assert(benders != NULL);
632  assert(var != NULL);
633  assert(mappedvar != NULL);
634 
635  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBendersMasterVar", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
636 
637  SCIP_CALL( SCIPbendersGetVar(benders, scip->set, var, mappedvar, -1) );
638 
639  return SCIP_OKAY;
640 }
641 
642 /** returns the subproblem problem variable for the given master variable
643  *
644  * This function is used as part of the cut generation process.
645  *
646  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
647  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
648  *
649  * @pre This method can be called if SCIP is in one of the following stages:
650  * - \ref SCIP_STAGE_INITPRESOLVE
651  * - \ref SCIP_STAGE_PRESOLVING
652  * - \ref SCIP_STAGE_EXITPRESOLVE
653  * - \ref SCIP_STAGE_PRESOLVED
654  * - \ref SCIP_STAGE_INITSOLVE
655  * - \ref SCIP_STAGE_SOLVING
656  * - \ref SCIP_STAGE_SOLVED
657  */
659  SCIP* scip, /**< SCIP data structure */
660  SCIP_BENDERS* benders, /**< Benders' decomposition */
661  SCIP_VAR* var, /**< the master variable */
662  SCIP_VAR** mappedvar, /**< pointer to store the subproblem variable that var is mapped to */
663  int probnumber /**< the subproblem number */
664  )
665 {
666  assert(scip != NULL);
667  assert(scip->set != NULL);
668  assert(benders != NULL);
669  assert(var != NULL);
670  assert(mappedvar != NULL);
671  assert(probnumber >= 0 && probnumber < SCIPgetBendersNSubproblems(scip, benders));
672 
673  SCIP_CALL( SCIPcheckStage(scip, "SCIPgetBendersSubproblemVar", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
674 
675  SCIP_CALL( SCIPbendersGetVar(benders, scip->set, var, mappedvar, probnumber) );
676 
677  return SCIP_OKAY;
678 }
679 
680 /** returns the number of subproblems that are stored in the given Benders' decomposition
681  *
682  * @return the number of subproblems in the Benders' decomposition
683  */
685  SCIP* scip, /**< SCIP data structure */
686  SCIP_BENDERS* benders /**< Benders' decomposition */
687  )
688 {
689  assert(scip != NULL);
690  assert(benders != NULL);
691 
692  return SCIPbendersGetNSubproblems(benders);
693 }
694 
695 /** registers the Benders' decomposition subproblem with the Benders' decomposition struct
696  *
697  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
698  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
699  *
700  * @pre This method can be called if SCIP is in one of the following stages:
701  * - \ref SCIP_STAGE_TRANSFORMED
702  */
704  SCIP* scip, /**< SCIP data structure */
705  SCIP_BENDERS* benders, /**< Benders' decomposition */
706  SCIP* subproblem /**< Benders' decomposition subproblem */
707  )
708 {
709  assert(scip != NULL);
710  assert(benders != NULL);
711  assert(subproblem != NULL);
712 
713  SCIP_CALL( SCIPcheckStage(scip, "SCIPaddBendersSubproblem", FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
714 
715  SCIP_CALL( SCIPbendersAddSubproblem(benders, subproblem) );
716 
717  return SCIP_OKAY;
718 }
719 
720 /** calls the generic subproblem setup method for a Benders' decomposition subproblem
721  *
722  * This is called if the user requires to solve the Benders' decomposition subproblem separately from the main Benders'
723  * solving loop. This could be in the case of enhancement techniques.
724  *
725  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
726  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
727  *
728  * @pre This method can be called if SCIP is in one of the following stages:
729  * - \ref SCIP_STAGE_TRANSFORMED
730  * - \ref SCIP_STAGE_INITPRESOLVE
731  * - \ref SCIP_STAGE_PRESOLVING
732  * - \ref SCIP_STAGE_EXITPRESOLVE
733  * - \ref SCIP_STAGE_PRESOLVED
734  * - \ref SCIP_STAGE_INITSOLVE
735  * - \ref SCIP_STAGE_SOLVING
736  * - \ref SCIP_STAGE_SOLVED
737  */
739  SCIP* scip, /**< SCIP data structure */
740  SCIP_BENDERS* benders, /**< the Benders' decomposition data structure */
741  SCIP_SOL* sol, /**< primal solution used to setup the problem, NULL for LP solution */
742  int probnumber /**< the subproblem number */
743  )
744 {
745  assert(scip != NULL);
746  assert(scip->set != NULL);
747  assert(benders != NULL);
748  assert(probnumber >= 0 && probnumber < SCIPgetBendersNSubproblems(scip, benders));
749 
750  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetupBendersSubproblem", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
751 
752  SCIP_CALL( SCIPbendersSetupSubproblem(benders, scip->set, sol, probnumber) );
753 
754  return SCIP_OKAY;
755 }
756 
757 /** calls the solving method for a single Benders' decomposition subproblem
758  *
759  * The method either calls the users solve subproblem method or calls the generic method. In the case of the generic
760  * method, the user must set up the subproblem prior to calling this method.
761  *
762  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
763  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
764  *
765  * @pre This method can be called if SCIP is in one of the following stages:
766  * - \ref SCIP_STAGE_TRANSFORMED
767  * - \ref SCIP_STAGE_INITPRESOLVE
768  * - \ref SCIP_STAGE_PRESOLVING
769  * - \ref SCIP_STAGE_EXITPRESOLVE
770  * - \ref SCIP_STAGE_PRESOLVED
771  * - \ref SCIP_STAGE_INITSOLVE
772  * - \ref SCIP_STAGE_SOLVING
773  * - \ref SCIP_STAGE_SOLVED
774  */
776  SCIP* scip, /**< SCIP data structure */
777  SCIP_BENDERS* benders, /**< Benders' decomposition */
778  SCIP_SOL* sol, /**< primal CIP solution, can be NULL for the current LP/Pseudo solution */
779  int probnumber, /**< the subproblem number */
780  SCIP_Bool* infeasible, /**< returns whether the current subproblem is infeasible */
781  SCIP_BENDERSENFOTYPE type, /**< the enforcement type calling this function */
782  SCIP_Bool solvecip, /**< directly solve the CIP subproblem */
783  SCIP_Real* objective /**< the objective function value of the subproblem, can be NULL */
784  )
785 {
786  assert(scip != NULL);
787  assert(scip->set != NULL);
788  assert(benders != NULL);
789  assert(probnumber >= 0 && probnumber < SCIPgetBendersNSubproblems(scip, benders));
790 
791  SCIP_CALL( SCIPcheckStage(scip, "SCIPsolveBendersSubproblem", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
792 
793  SCIP_CALL( SCIPbendersSolveSubproblem(benders, scip->set, sol, probnumber, infeasible, type, solvecip, objective) );
794 
795  return SCIP_OKAY;
796 }
797 
798 /** frees the subproblem after calling the solve subproblem method
799  *
800  * This will either call the user defined free
801  * subproblem callback for Benders' decomposition or the default freeing methods. In the default case, if the
802  * subproblem is an LP, then SCIPendProbing is called. If the subproblem is a MIP, then SCIPfreeTransform is called.
803  *
804  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
805  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
806  *
807  * @pre This method can be called if SCIP is in one of the following stages:
808  * - \ref SCIP_STAGE_TRANSFORMED
809  * - \ref SCIP_STAGE_INITPRESOLVE
810  * - \ref SCIP_STAGE_PRESOLVING
811  * - \ref SCIP_STAGE_EXITPRESOLVE
812  * - \ref SCIP_STAGE_PRESOLVED
813  * - \ref SCIP_STAGE_INITSOLVE
814  * - \ref SCIP_STAGE_SOLVING
815  * - \ref SCIP_STAGE_SOLVED
816  * - \ref SCIP_STAGE_EXITSOLVE
817  * - \ref SCIP_STAGE_FREETRANS
818  */
820  SCIP* scip, /**< SCIP data structure */
821  SCIP_BENDERS* benders, /**< Benders' decomposition */
822  int probnumber /**< the subproblem number */
823  )
824 {
825  assert(scip != NULL);
826  assert(scip->set != NULL);
827  assert(benders != NULL);
828  assert(probnumber >= 0 && probnumber < SCIPgetBendersNSubproblems(scip, benders));
829 
830  SCIP_CALL( SCIPcheckStage(scip, "SCIPfreeBendersSubproblem", FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE) );
831 
832  SCIP_CALL( SCIPbendersFreeSubproblem(benders, scip->set, probnumber) );
833 
834  return SCIP_OKAY;
835 }
836 
837 /** checks the optimality of a Benders' decomposition subproblem by comparing the objective function value against the
838  * value of the corresponding auxiliary variable
839  *
840  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
841  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
842  *
843  * @pre This method can be called if SCIP is in one of the following stages:
844  * - \ref SCIP_STAGE_INITPRESOLVE
845  * - \ref SCIP_STAGE_PRESOLVING
846  * - \ref SCIP_STAGE_SOLVING
847  * - \ref SCIP_STAGE_SOLVED
848  *
849  * @pre This method can be called if requested subproblem is in one of the following stages:
850  * - \ref SCIP_STAGE_SOLVING
851  * - \ref SCIP_STAGE_SOLVED
852  */
854  SCIP* scip, /**< SCIP data structure */
855  SCIP_BENDERS* benders, /**< the benders' decomposition structure */
856  SCIP_SOL* sol, /**< primal CIP solution, can be NULL for the current LP solution */
857  int probnumber, /**< the number of the pricing problem */
858  SCIP_Bool* optimal /**< flag to indicate whether the current subproblem is optimal for the master */
859  )
860 {
861  assert(scip != NULL);
862  assert(benders != NULL);
863  assert(probnumber >= 0 && probnumber < SCIPbendersGetNSubproblems(benders));
864 
865  /* check stages for both, SCIP and the requested subproblem data structure */
866  SCIP_CALL( SCIPcheckStage(scip, "SCIPcheckBendersSubproblemOptimality", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE) );
867  SCIP_CALL( SCIPcheckStage(SCIPbendersSubproblem(benders, probnumber), "SCIPcheckBendersSubproblemOptimality",
869 
870  SCIP_CALL( SCIPbendersCheckSubproblemOptimality(benders, scip->set, sol, probnumber, optimal) );
871 
872  return SCIP_OKAY;
873 }
874 
875 /** returns the value of the auxiliary variable for a given subproblem
876  *
877  * @return the value of the auxiliary variable for the given subproblem
878  */
880  SCIP* scip, /**< SCIP data structure */
881  SCIP_BENDERS* benders, /**< the benders' decomposition structure */
882  SCIP_SOL* sol, /**< primal CIP solution, can be NULL for the current LP solution */
883  int probnumber /**< the number of the pricing problem */
884  )
885 {
886  assert(scip != NULL);
887  assert(benders != NULL);
888  assert(probnumber >= 0 && probnumber < SCIPbendersGetNSubproblems(benders));
889 
890  return SCIPbendersGetAuxiliaryVarVal(benders, scip->set, sol, probnumber);
891 }
892 
893 /** solves an independent subproblem to identify its lower bound and updates the lower bound of the corresponding
894  * auxiliary variable
895  *
896  * @pre This method can be called if SCIP is in one of the following stages:
897  * - \ref SCIP_STAGE_INITPRESOLVE
898  * - \ref SCIP_STAGE_PRESOLVING
899  * - \ref SCIP_STAGE_EXITPRESOLVE
900  * - \ref SCIP_STAGE_PRESOLVED
901  * - \ref SCIP_STAGE_INITSOLVE
902  * - \ref SCIP_STAGE_SOLVING
903  *
904  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
905  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
906  */
908  SCIP* scip, /**< the SCIP data structure */
909  SCIP_BENDERS* benders, /**< Benders' decomposition */
910  int probnumber, /**< the subproblem to be evaluated */
911  SCIP_Real* lowerbound, /**< the lowerbound for the subproblem */
912  SCIP_Bool* infeasible /**< was the subproblem found to be infeasible? */
913  )
914 {
915  assert(scip != NULL);
916  assert(benders != NULL);
917  assert(probnumber >= 0 && probnumber < SCIPgetBendersNSubproblems(scip, benders));
918 
919  SCIP_CALL( SCIPcheckStage(scip, "SCIPcomputeBendersSubproblemLowerbound", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
920 
921  SCIP_CALL( SCIPbendersComputeSubproblemLowerbound(benders, scip->set, probnumber, lowerbound, infeasible) );
922 
923  return SCIP_OKAY;
924 }
925 
926 /** Merges a subproblem into the master problem. This process just adds a copy of the subproblem variables and
927  * constraints to the master problem, but keeps the subproblem stored in the Benders' decomposition data structure.
928  * The reason for keeping the subproblem available is for when it is queried for solutions after the problem is solved.
929  *
930  * Once the subproblem is merged into the master problem, then the subproblem is flagged as disabled. This means that
931  * it will not be solved in the subsequent subproblem solving loops.
932  *
933  * The associated auxiliary variables are kept in the master problem. The objective function of the merged subproblem
934  * is added as an underestimator constraint.
935  *
936  * @pre This method can be called if SCIP is in one of the following stages:
937  * - \ref SCIP_STAGE_INITPRESOLVE
938  * - \ref SCIP_STAGE_PRESOLVING
939  * - \ref SCIP_STAGE_EXITPRESOLVE
940  * - \ref SCIP_STAGE_PRESOLVED
941  * - \ref SCIP_STAGE_INITSOLVE
942  * - \ref SCIP_STAGE_SOLVING
943  *
944  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
945  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
946  */
948  SCIP* scip, /**< the SCIP data structure */
949  SCIP_BENDERS* benders, /**< Benders' decomposition */
950  SCIP_HASHMAP* varmap, /**< a hashmap to store the mapping of subproblem variables corresponding
951  * to the newly created master variables, or NULL */
952  SCIP_HASHMAP* consmap, /**< a hashmap to store the mapping of subproblem constraints to the
953  corresponding newly created constraints, or NULL */
954  int probnumber /**< the number of the subproblem that will be merged into the master problem*/
955  )
956 {
957  assert(scip != NULL);
958  assert(benders != NULL);
959  assert(probnumber >= 0 && probnumber < SCIPgetBendersNSubproblems(scip, benders));
960 
961  SCIP_CALL( SCIPcheckStage(scip, "SCIPmergeBendersSubproblemIntoMaster", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
962 
963  SCIP_CALL( SCIPbendersMergeSubproblemIntoMaster(benders, scip->set, varmap, consmap, probnumber) );
964 
965  return SCIP_OKAY;
966 }
967 
968 /** creates a Benders' cut algorithms and includes it in the associated Benders' decomposition
969  *
970  * This should be called from the SCIPincludeBendersXyz for the associated Benders' decomposition. It is only possible
971  * to include a Benders' cut algorithm if a Benders' decomposition has already been included
972  * This should be done during the problem creation stage.
973  *
974  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
975  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
976  *
977  * @pre This method can be called if SCIP is in one of the following stages:
978  * - \ref SCIP_STAGE_INIT
979  * - \ref SCIP_STAGE_PROBLEM
980  *
981  * @note method has all Benders' decomposition callbacks as arguments and is thus changed every time a new callback is
982  * added in future releases; consider using SCIPincludeBendersBasic() and setter functions
983  * if you seek for a method which is less likely to change in future releases
984  */
986  SCIP* scip, /**< SCIP data structure */
987  SCIP_BENDERS* benders, /**< Benders' decomposition */
988  const char* name, /**< name of Benders' decomposition cuts */
989  const char* desc, /**< description of Benders' decomposition cuts */
990  int priority, /**< priority of the Benders' decomposition cuts */
991  SCIP_Bool islpcut, /**< indicates whether the cut is generated from the LP solution */
992  SCIP_DECL_BENDERSCUTCOPY((*benderscutcopy)),/**< copy method of Benders' decomposition cuts or NULL if you don't want to copy your plugin into sub-SCIPs */
993  SCIP_DECL_BENDERSCUTFREE((*benderscutfree)),/**< destructor of Benders' decomposition cuts */
994  SCIP_DECL_BENDERSCUTINIT((*benderscutinit)),/**< initialize Benders' decomposition cuts */
995  SCIP_DECL_BENDERSCUTEXIT((*benderscutexit)),/**< deinitialize Benders' decomposition cuts */
996  SCIP_DECL_BENDERSCUTINITSOL((*benderscutinitsol)),/**< solving process initialization method of Benders' decomposition cuts */
997  SCIP_DECL_BENDERSCUTEXITSOL((*benderscutexitsol)),/**< solving process deinitialization method of Benders' decomposition cuts */
998  SCIP_DECL_BENDERSCUTEXEC((*benderscutexec)),/**< execution method of Benders' decomposition cuts */
999  SCIP_BENDERSCUTDATA* benderscutdata /**< Benders' decomposition cuts data */
1000  )
1001 {
1002  SCIP_BENDERSCUT* benderscut;
1003 
1004  SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeBenderscut", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1005 
1006  /* check whether pricer is already present */
1007  if( SCIPfindBenderscut(benders, name) != NULL )
1008  {
1009  SCIPerrorMessage("benders <%s> already included.\n", name);
1010  return SCIP_INVALIDDATA;
1011  }
1012 
1013  SCIP_CALL( SCIPbenderscutCreate(benders, &benderscut, scip->set, scip->messagehdlr, scip->mem->setmem, name, desc, priority,
1014  islpcut, benderscutcopy, benderscutfree, benderscutinit, benderscutexit,
1015  benderscutinitsol, benderscutexitsol, benderscutexec, benderscutdata) );
1016  SCIP_CALL( SCIPbendersIncludeBenderscut(benders, scip->set, benderscut) );
1017 
1018  return SCIP_OKAY;
1019 }
1020 
1021 /** creates a Benders' cut and includes it an associated Benders' decomposition with all non-fundamental callbacks set to NULL
1022  *
1023  * If needed, the non-fundamental callbacks can be added afterwards via setter functions SCIPsetBenderscutCopy(),
1024  * SCIPsetBenderscutFree(), SCIPsetBenderscutInit(), SCIPsetBenderscutExit(), SCIPsetBenderscutInitsol(),
1025  * SCIPsetBenderscutExitsol().
1026  *
1027  * This should be done during the problem creation stage.
1028  *
1029  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1030  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1031  *
1032  * @pre This method can be called if SCIP is in one of the following stages:
1033  * - \ref SCIP_STAGE_INIT
1034  * - \ref SCIP_STAGE_PROBLEM
1035  *
1036  * @note if you want to set all callbacks with a single method call, consider using SCIPincludeBenders() instead
1037  */
1039  SCIP* scip, /**< SCIP data structure */
1040  SCIP_BENDERS* benders, /**< Benders' decomposition */
1041  SCIP_BENDERSCUT** benderscutptr, /**< reference to a Benders' decomposition cut, or NULL */
1042  const char* name, /**< name of Benders' decomposition */
1043  const char* desc, /**< description of Benders' decomposition */
1044  int priority, /**< priority of the Benders' decomposition */
1045  SCIP_Bool islpcut, /**< indicates whether the cut is generated from the LP solution */
1046  SCIP_DECL_BENDERSCUTEXEC((*benderscutexec)),/**< the execution method of the Benders' cut algorithm */
1047  SCIP_BENDERSCUTDATA* benderscutdata /**< Benders' cut data */
1048  )
1049 {
1050  SCIP_BENDERSCUT* benderscut;
1051 
1052  SCIP_CALL( SCIPcheckStage(scip, "SCIPincludeBenderscutBasic", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1053 
1054  /* check whether Benders' decomposition cut is already present */
1055  if( SCIPfindBenderscut(benders, name) != NULL )
1056  {
1057  SCIPerrorMessage("Benders' cut <%s> already included.\n", name);
1058  return SCIP_INVALIDDATA;
1059  }
1060 
1061  SCIP_CALL( SCIPbenderscutCreate(benders, &benderscut, scip->set, scip->messagehdlr, scip->mem->setmem, name, desc,
1062  priority, islpcut, NULL, NULL, NULL, NULL, NULL, NULL, benderscutexec, benderscutdata) );
1063  SCIP_CALL( SCIPbendersIncludeBenderscut(benders, scip->set, benderscut) );
1064 
1065  if( benderscutptr != NULL )
1066  *benderscutptr = benderscut;
1067 
1068  return SCIP_OKAY;
1069 }
1070 
1071 /** sets copy method of Benders' decomposition cut
1072  *
1073  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1074  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1075  *
1076  * @pre This method can be called if SCIP is in one of the following stages:
1077  * - \ref SCIP_STAGE_INIT
1078  * - \ref SCIP_STAGE_PROBLEM
1079  */
1081  SCIP* scip, /**< SCIP data structure */
1082  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
1083  SCIP_DECL_BENDERSCUTCOPY((*benderscutcopy))/**< copy method of benderscut or NULL if you don't want to copy your plugin into sub-SCIPs */
1084  )
1085 {
1086  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBenderscutCopy", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1087 
1088  assert(benderscut != NULL);
1089 
1090  SCIPbenderscutSetCopy(benderscut, benderscutcopy);
1091 
1092  return SCIP_OKAY;
1093 }
1094 
1095 /** sets destructor method of benderscut
1096  *
1097  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1098  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1099  *
1100  * @pre This method can be called if SCIP is in one of the following stages:
1101  * - \ref SCIP_STAGE_INIT
1102  * - \ref SCIP_STAGE_PROBLEM
1103  */
1105  SCIP* scip, /**< SCIP data structure */
1106  SCIP_BENDERSCUT* benderscut, /**< benderscut */
1107  SCIP_DECL_BENDERSCUTFREE((*benderscutfree))/**< destructor of benderscut */
1108  )
1109 {
1110  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBenderscutFree", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1111 
1112  assert(benderscut != NULL);
1113 
1114  SCIPbenderscutSetFree(benderscut, benderscutfree);
1115 
1116  return SCIP_OKAY;
1117 }
1118 
1119 /** sets initialization method of benderscut
1120  *
1121  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1122  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1123  *
1124  * @pre This method can be called if SCIP is in one of the following stages:
1125  * - \ref SCIP_STAGE_INIT
1126  * - \ref SCIP_STAGE_PROBLEM
1127  */
1129  SCIP* scip, /**< SCIP data structure */
1130  SCIP_BENDERSCUT* benderscut, /**< benderscut */
1131  SCIP_DECL_BENDERSCUTINIT((*benderscutinit))/**< initialize benderscut */
1132  )
1133 {
1134  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBenderscutInit", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1135 
1136  assert(benderscut != NULL);
1137 
1138  SCIPbenderscutSetInit(benderscut, benderscutinit);
1139 
1140  return SCIP_OKAY;
1141 }
1142 
1143 /** sets deinitialization method of benderscut
1144  *
1145  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1146  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1147  *
1148  * @pre This method can be called if SCIP is in one of the following stages:
1149  * - \ref SCIP_STAGE_INIT
1150  * - \ref SCIP_STAGE_PROBLEM
1151  */
1153  SCIP* scip, /**< SCIP data structure */
1154  SCIP_BENDERSCUT* benderscut, /**< benderscut */
1155  SCIP_DECL_BENDERSCUTEXIT((*benderscutexit))/**< deinitialize benderscut */
1156  )
1157 {
1158  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBenderscutExit", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1159 
1160  assert(benderscut != NULL);
1161 
1162  SCIPbenderscutSetExit(benderscut, benderscutexit);
1163 
1164  return SCIP_OKAY;
1165 }
1166 
1167 /** sets solving process initialization method of benderscut
1168  *
1169  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1170  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1171  *
1172  * @pre This method can be called if SCIP is in one of the following stages:
1173  * - \ref SCIP_STAGE_INIT
1174  * - \ref SCIP_STAGE_PROBLEM
1175  */
1177  SCIP* scip, /**< SCIP data structure */
1178  SCIP_BENDERSCUT* benderscut, /**< benderscut */
1179  SCIP_DECL_BENDERSCUTINITSOL((*benderscutinitsol))/**< solving process initialization method of benderscut */
1180  )
1181 {
1182  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBenderscutInitsol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1183 
1184  assert(benderscut != NULL);
1185 
1186  SCIPbenderscutSetInitsol(benderscut, benderscutinitsol);
1187 
1188  return SCIP_OKAY;
1189 }
1190 
1191 /** sets solving process deinitialization method of benderscut
1192  *
1193  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1194  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1195  *
1196  * @pre This method can be called if SCIP is in one of the following stages:
1197  * - \ref SCIP_STAGE_INIT
1198  * - \ref SCIP_STAGE_PROBLEM
1199  */
1201  SCIP* scip, /**< SCIP data structure */
1202  SCIP_BENDERSCUT* benderscut, /**< benderscut */
1203  SCIP_DECL_BENDERSCUTEXITSOL((*benderscutexitsol))/**< solving process deinitialization method of benderscut */
1204  )
1205 {
1206  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBenderscutExitsol", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1207 
1208  assert(benderscut != NULL);
1209 
1210  SCIPbenderscutSetExitsol(benderscut, benderscutexitsol);
1211 
1212  return SCIP_OKAY;
1213 }
1214 
1215 /** sets the priority of a Benders' decomposition cut algorithm
1216  *
1217  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1218  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1219  *
1220  * @pre This method can be called if SCIP is in one of the following stages:
1221  * - \ref SCIP_STAGE_INIT
1222  * - \ref SCIP_STAGE_PROBLEM
1223  */
1225  SCIP* scip, /**< SCIP data structure */
1226  SCIP_BENDERSCUT* benderscut, /**< benderscut */
1227  int priority /**< new priority of the Benders' decomposition */
1228  )
1229 {
1230  SCIP_BENDERS** benders;
1231  int nbenders;
1232  int i;
1233 
1234  assert(scip != NULL);
1235  assert(scip->set != NULL);
1236  assert(benderscut != NULL);
1237 
1238  SCIP_CALL( SCIPcheckStage(scip, "SCIPsetBenderscutPriority", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1239 
1240  SCIPbenderscutSetPriority(benderscut, priority);
1241 
1242  /* DIRTY: This is not a good fix */
1243  /* Changing the priority of one Benders' cut in a Benders' decomposition requires all Benders' cuts to be set to
1244  * unsorted. This is a fix that is not very nice, but it does the job */
1245  benders = SCIPgetBenders(scip);
1246  nbenders = SCIPgetNBenders(scip);
1247  for( i = 0; i < nbenders; i++ )
1249 
1250  return SCIP_OKAY;
1251 }
1252 
1253 /** adds the generated cuts to the Benders' cut storage
1254  *
1255  * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
1256  * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
1257  *
1258  * @pre This method can be called if SCIP is in one of the following stages:
1259  * - \ref SCIP_STAGE_INITPRESOLVE
1260  * - \ref SCIP_STAGE_PRESOLVING
1261  * - \ref SCIP_STAGE_EXITPRESOLVE
1262  * - \ref SCIP_STAGE_PRESOLVED
1263  * - \ref SCIP_STAGE_INITSOLVE
1264  * - \ref SCIP_STAGE_SOLVING
1265  */
1267  SCIP* scip, /**< the SCIP data structure */
1268  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cuts */
1269  SCIP_VAR** vars, /**< the variables that have non-zero coefficients in the cut */
1270  SCIP_Real* vals, /**< the coefficients of the variables in the cut */
1271  SCIP_Real lhs, /**< the left hand side of the cut */
1272  SCIP_Real rhs, /**< the right hand side of the cut */
1273  int nvars /**< the number of variables with non-zero coefficients in the cut */
1274  )
1275 {
1276  assert(scip != NULL);
1277  assert(benderscut != NULL);
1278  assert(vars != NULL);
1279  assert(vals != NULL);
1280 
1281  SCIP_CALL( SCIPcheckStage(scip, "SCIPstoreBenderscutCut", FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
1282 
1283  SCIP_CALL( SCIPbenderscutStoreCut(benderscut, scip->set, vars, vals, lhs, rhs, nvars) );
1284 
1285  return SCIP_OKAY;
1286 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
#define SCIP_DECL_BENDERSCREATESUB(x)
Definition: type_benders.h:170
SCIP_RETCODE SCIPsetBenderscutExitsol(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTEXITSOL((*benderscutexitsol)))
#define NULL
Definition: def.h:253
SCIP_RETCODE SCIPbendersIncludeBenderscut(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_BENDERSCUT *benderscut)
Definition: benders.c:4792
SCIP_RETCODE SCIPgetBendersSubproblemVar(SCIP *scip, SCIP_BENDERS *benders, SCIP_VAR *var, SCIP_VAR **mappedvar, int probnumber)
Definition: scip_benders.c:658
void SCIPbendersDeactivate(SCIP_BENDERS *benders, SCIP_SET *set)
Definition: benders.c:1890
SCIP_RETCODE SCIPsetBendersPresubsolve(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve)))
Definition: scip_benders.c:375
struct SCIP_BenderscutData SCIP_BENDERSCUTDATA
#define SCIP_DECL_BENDERSINITSOL(x)
Definition: type_benders.h:130
SCIP_RETCODE SCIPbendersSetupSubproblem(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, int probnumber)
Definition: benders.c:3119
#define SCIP_DECL_BENDERSFREE(x)
Definition: type_benders.h:82
SCIP_BENDERS ** SCIPgetBenders(SCIP *scip)
Definition: scip_benders.c:470
void SCIPbenderscutSetPriority(SCIP_BENDERSCUT *benderscut, int priority)
Definition: benderscut.c:538
#define SCIP_DECL_BENDERSINITPRE(x)
Definition: type_benders.h:111
#define SCIP_DECL_BENDERSCUTFREE(x)
void SCIPbendersSetSolvesub(SCIP_BENDERS *benders, SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub)))
Definition: benders.c:4178
void SCIPbenderscutSetInitsol(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTINITSOL((*benderscutinitsol)))
Definition: benderscut.c:486
#define SCIP_DECL_BENDERSGETVAR(x)
Definition: type_benders.h:339
SCIP_RETCODE SCIPsetBendersPostsolve(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve)))
Definition: scip_benders.c:439
SCIP_RETCODE SCIPsetBendersFree(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSFREE((*bendersfree)))
Definition: scip_benders.c:207
int SCIPbendersGetNSubproblems(SCIP_BENDERS *benders)
Definition: benders.c:4255
#define FALSE
Definition: def.h:73
public methods for Benders&#39; decomposition
internal methods for Benders&#39; decomposition
SCIP_RETCODE SCIPsetBendersSolveAndFreesub(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex)), SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub)), SCIP_DECL_BENDERSFREESUB((*bendersfreesub)))
Definition: scip_benders.c:399
#define TRUE
Definition: def.h:72
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
enum SCIP_BendersEnfoType SCIP_BENDERSENFOTYPE
Definition: type_benders.h:42
SCIP_RETCODE SCIPbenderscutStoreCut(SCIP_BENDERSCUT *benderscut, SCIP_SET *set, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, int nvars)
Definition: benderscut.c:637
SCIP_RETCODE SCIPincludeBenders(SCIP *scip, const char *name, const char *desc, int priority, SCIP_Bool cutlp, SCIP_Bool cutpseudo, SCIP_Bool cutrelax, SCIP_Bool shareauxvars, SCIP_DECL_BENDERSCOPY((*benderscopy)), SCIP_DECL_BENDERSFREE((*bendersfree)), SCIP_DECL_BENDERSINIT((*bendersinit)), SCIP_DECL_BENDERSEXIT((*bendersexit)), SCIP_DECL_BENDERSINITPRE((*bendersinitpre)), SCIP_DECL_BENDERSEXITPRE((*bendersexitpre)), SCIP_DECL_BENDERSINITSOL((*bendersinitsol)), SCIP_DECL_BENDERSEXITSOL((*bendersexitsol)), SCIP_DECL_BENDERSGETVAR((*bendersgetvar)), SCIP_DECL_BENDERSCREATESUB((*benderscreatesub)), SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve)), SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex)), SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub)), SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve)), SCIP_DECL_BENDERSFREESUB((*bendersfreesub)), SCIP_BENDERSDATA *bendersdata)
Definition: scip_benders.c:62
void SCIPbendersSetFree(SCIP_BENDERS *benders, SCIP_DECL_BENDERSFREE((*bendersfree)))
Definition: benders.c:4079
#define SCIP_DECL_BENDERSINIT(x)
Definition: type_benders.h:91
void SCIPbendersSetExitpre(SCIP_BENDERS *benders, SCIP_DECL_BENDERSEXITPRE((*bendersexitpre)))
Definition: benders.c:4123
#define SCIP_DECL_BENDERSCUTEXEC(x)
SCIP_RETCODE SCIPcheckBendersSubproblemOptimality(SCIP *scip, SCIP_BENDERS *benders, SCIP_SOL *sol, int probnumber, SCIP_Bool *optimal)
Definition: scip_benders.c:853
SCIP_RETCODE SCIPsetBendersInitsol(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSINITSOL((*bendersinitsol)))
Definition: scip_benders.c:327
SCIP_RETCODE SCIPdeactivateBenders(SCIP *scip, SCIP_BENDERS *benders)
Definition: scip_benders.c:539
SCIP_RETCODE SCIPbendersCheckSubproblemOptimality(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, int probnumber, SCIP_Bool *optimal)
Definition: benders.c:3656
SCIP_Real SCIPgetBendersAuxiliaryVarVal(SCIP *scip, SCIP_BENDERS *benders, SCIP_SOL *sol, int probnumber)
Definition: scip_benders.c:879
void SCIPbendersSetInit(SCIP_BENDERS *benders, SCIP_DECL_BENDERSINIT((*bendersinit)))
Definition: benders.c:4090
void SCIPbendersSetExit(SCIP_BENDERS *benders, SCIP_DECL_BENDERSEXIT((*bendersexit)))
Definition: benders.c:4101
int nactivebenders
Definition: struct_set.h:137
#define SCIP_DECL_BENDERSCUTCOPY(x)
void SCIPbendersSetPostsolve(SCIP_BENDERS *benders, SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve)))
Definition: benders.c:4189
void SCIPsetBendersPriority(SCIP *scip, SCIP_BENDERS *benders, int priority)
Definition: scip_benders.c:552
#define SCIP_DECL_BENDERSCUTINIT(x)
SCIP_RETCODE SCIPsetIncludeBenders(SCIP_SET *set, SCIP_BENDERS *benders)
Definition: set.c:3668
int SCIPgetBendersNSubproblems(SCIP *scip, SCIP_BENDERS *benders)
Definition: scip_benders.c:684
void SCIPbendersSetFreesub(SCIP_BENDERS *benders, SCIP_DECL_BENDERSFREESUB((*bendersfreesub)))
Definition: benders.c:4200
SCIP_RETCODE SCIPbendersAddSubproblem(SCIP_BENDERS *benders, SCIP *subproblem)
Definition: benders.c:4379
SCIP_RETCODE SCIPgetBendersMasterVar(SCIP *scip, SCIP_BENDERS *benders, SCIP_VAR *var, SCIP_VAR **mappedvar)
Definition: scip_benders.c:622
SCIP_BENDERS * SCIPfindBenders(SCIP *scip, const char *name)
Definition: scip_benders.c:455
SCIP_RETCODE SCIPsetBenderscutExit(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTEXIT((*benderscutexit)))
void SCIPbenderscutSetExit(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTEXIT((*benderscutexit)))
Definition: benderscut.c:475
SCIP * SCIPbendersSubproblem(SCIP_BENDERS *benders, int probnumber)
Definition: benders.c:4265
SCIP_RETCODE SCIPcomputeBendersSubproblemLowerbound(SCIP *scip, SCIP_BENDERS *benders, int probnumber, SCIP_Real *lowerbound, SCIP_Bool *infeasible)
Definition: scip_benders.c:907
#define SCIP_DECL_BENDERSFREESUB(x)
Definition: type_benders.h:323
SCIP_MEM * mem
Definition: struct_scip.h:61
void SCIPbendersSetSolvesubconvex(SCIP_BENDERS *benders, SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex)))
Definition: benders.c:4167
SCIP_RETCODE SCIPincludeBenderscut(SCIP *scip, SCIP_BENDERS *benders, const char *name, const char *desc, int priority, SCIP_Bool islpcut, SCIP_DECL_BENDERSCUTCOPY((*benderscutcopy)), SCIP_DECL_BENDERSCUTFREE((*benderscutfree)), SCIP_DECL_BENDERSCUTINIT((*benderscutinit)), SCIP_DECL_BENDERSCUTEXIT((*benderscutexit)), SCIP_DECL_BENDERSCUTINITSOL((*benderscutinitsol)), SCIP_DECL_BENDERSCUTEXITSOL((*benderscutexitsol)), SCIP_DECL_BENDERSCUTEXEC((*benderscutexec)), SCIP_BENDERSCUTDATA *benderscutdata)
Definition: scip_benders.c:985
public methods for Benders decomposition
SCIP_RETCODE SCIPbendersFreeSubproblem(SCIP_BENDERS *benders, SCIP_SET *set, int probnumber)
Definition: benders.c:3606
#define SCIPerrorMessage
Definition: pub_message.h:45
#define SCIP_DECL_BENDERSEXIT(x)
Definition: type_benders.h:100
SCIP_RETCODE SCIPsolveBendersSubproblems(SCIP *scip, SCIP_BENDERS *benders, SCIP_SOL *sol, SCIP_RESULT *result, SCIP_Bool *infeasible, SCIP_Bool *auxviol, SCIP_BENDERSENFOTYPE type, SCIP_Bool checkint)
Definition: scip_benders.c:584
#define SCIP_DECL_BENDERSSOLVESUB(x)
Definition: type_benders.h:265
void SCIPbendersSetExitsol(SCIP_BENDERS *benders, SCIP_DECL_BENDERSEXITSOL((*bendersexitsol)))
Definition: benders.c:4145
SCIP_RETCODE SCIPcheckStage(SCIP *scip, const char *method, SCIP_Bool init, SCIP_Bool problem, SCIP_Bool transforming, SCIP_Bool transformed, SCIP_Bool initpresolve, SCIP_Bool presolving, SCIP_Bool exitpresolve, SCIP_Bool presolved, SCIP_Bool initsolve, SCIP_Bool solving, SCIP_Bool solved, SCIP_Bool exitsolve, SCIP_Bool freetrans, SCIP_Bool freescip)
Definition: debug.c:2010
SCIP_RETCODE SCIPmergeBendersSubproblemIntoMaster(SCIP *scip, SCIP_BENDERS *benders, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, int probnumber)
Definition: scip_benders.c:947
void SCIPbendersSetPriority(SCIP_BENDERS *benders, SCIP_SET *set, int priority)
Definition: benders.c:4241
int nbenders
Definition: struct_set.h:136
SCIP_RETCODE SCIPbendersSolveSubproblem(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, int probnumber, SCIP_Bool *infeasible, SCIP_BENDERSENFOTYPE type, SCIP_Bool solvecip, SCIP_Real *objective)
Definition: benders.c:3218
SCIP_RETCODE SCIPsetupBendersSubproblem(SCIP *scip, SCIP_BENDERS *benders, SCIP_SOL *sol, int probnumber)
Definition: scip_benders.c:738
#define SCIP_DECL_BENDERSCUTEXIT(x)
struct SCIP_BendersData SCIP_BENDERSDATA
Definition: type_benders.h:63
SCIP_BENDERSCUT * SCIPfindBenderscut(SCIP_BENDERS *benders, const char *name)
Definition: benders.c:4816
internal methods for global SCIP settings
#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)
SCIP main data structure.
int SCIPgetNBenders(SCIP *scip)
Definition: scip_benders.c:483
#define SCIP_DECL_BENDERSSOLVESUBCONVEX(x)
Definition: type_benders.h:232
BMS_BLKMEM * setmem
Definition: struct_mem.h:39
void SCIPbenderscutSetExitsol(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTEXITSOL((*benderscutexitsol)))
Definition: benderscut.c:497
SCIP_RETCODE SCIPbendersExec(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, SCIP_RESULT *result, SCIP_Bool *infeasible, SCIP_Bool *auxviol, SCIP_BENDERSENFOTYPE type, SCIP_Bool checkint)
Definition: benders.c:2502
void SCIPbendersSetInitsol(SCIP_BENDERS *benders, SCIP_DECL_BENDERSINITSOL((*bendersinitsol)))
Definition: benders.c:4134
SCIP_RETCODE SCIPbendersCreate(SCIP_BENDERS **benders, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int priority, SCIP_Bool cutlp, SCIP_Bool cutpseudo, SCIP_Bool cutrelax, SCIP_Bool shareauxvars, SCIP_DECL_BENDERSCOPY((*benderscopy)), SCIP_DECL_BENDERSFREE((*bendersfree)), SCIP_DECL_BENDERSINIT((*bendersinit)), SCIP_DECL_BENDERSEXIT((*bendersexit)), SCIP_DECL_BENDERSINITPRE((*bendersinitpre)), SCIP_DECL_BENDERSEXITPRE((*bendersexitpre)), SCIP_DECL_BENDERSINITSOL((*bendersinitsol)), SCIP_DECL_BENDERSEXITSOL((*bendersexitsol)), SCIP_DECL_BENDERSGETVAR((*bendersgetvar)), SCIP_DECL_BENDERSCREATESUB((*benderscreatesub)), SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve)), SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex)), SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub)), SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve)), SCIP_DECL_BENDERSFREESUB((*bendersfreesub)), SCIP_BENDERSDATA *bendersdata)
Definition: benders.c:969
SCIP_RETCODE SCIPsetBendersCopy(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSCOPY((*benderscopy)))
Definition: scip_benders.c:183
#define SCIP_DECL_BENDERSCOPY(x)
Definition: type_benders.h:74
void SCIPsetSortBenders(SCIP_SET *set)
Definition: set.c:3711
SCIP_RETCODE SCIPsetBenderscutPriority(SCIP *scip, SCIP_BENDERSCUT *benderscut, int priority)
void SCIPbendersSetPresubsolve(SCIP_BENDERS *benders, SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve)))
Definition: benders.c:4156
#define SCIP_Bool
Definition: def.h:70
SCIP_RETCODE SCIPbendersComputeSubproblemLowerbound(SCIP_BENDERS *benders, SCIP_SET *set, int probnumber, SCIP_Real *lowerbound, SCIP_Bool *infeasible)
Definition: benders.c:3709
void SCIPbenderscutSetFree(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTFREE((*benderscutfree)))
Definition: benderscut.c:453
SCIP_RETCODE SCIPsetBendersInitpre(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSINITPRE((*bendersinitpre)))
Definition: scip_benders.c:279
SCIP_RETCODE SCIPsetBenderscutCopy(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTCOPY((*benderscutcopy)))
int SCIPgetNActiveBenders(SCIP *scip)
Definition: scip_benders.c:494
void SCIPbendersSetInitpre(SCIP_BENDERS *benders, SCIP_DECL_BENDERSINITPRE((*bendersinitpre)))
Definition: benders.c:4112
methods for debugging
datastructures for block memory pools and memory buffers
SCIP_BENDERS ** benders
Definition: struct_set.h:92
SCIP_RETCODE SCIPbendersMergeSubproblemIntoMaster(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, int probnumber)
Definition: benders.c:3838
SCIP_RETCODE SCIPsetBendersInit(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSINIT((*bendersinit)))
Definition: scip_benders.c:231
SCIP_Real SCIPbendersGetAuxiliaryVarVal(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_SOL *sol, int probnumber)
Definition: benders.c:3688
SCIP_RETCODE SCIPbendersActivate(SCIP_BENDERS *benders, SCIP_SET *set, int nsubproblems)
Definition: benders.c:1827
void SCIPbenderscutSetInit(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTINIT((*benderscutinit)))
Definition: benderscut.c:464
SCIP_RETCODE SCIPsetBenderscutInitsol(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTINITSOL((*benderscutinitsol)))
SCIP_RETCODE SCIPbendersGetVar(SCIP_BENDERS *benders, SCIP_SET *set, SCIP_VAR *var, SCIP_VAR **mappedvar, int probnumber)
Definition: benders.c:4021
SCIP_RETCODE SCIPincludeBendersBasic(SCIP *scip, SCIP_BENDERS **bendersptr, const char *name, const char *desc, int priority, SCIP_Bool cutlp, SCIP_Bool cutpseudo, SCIP_Bool cutrelax, SCIP_Bool shareauxvars, SCIP_DECL_BENDERSGETVAR((*bendersgetvar)), SCIP_DECL_BENDERSCREATESUB((*benderscreatesub)), SCIP_BENDERSDATA *bendersdata)
Definition: scip_benders.c:137
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_BENDERS * SCIPsetFindBenders(SCIP_SET *set, const char *name)
Definition: set.c:3691
SCIP_RETCODE SCIPsolveBendersSubproblem(SCIP *scip, SCIP_BENDERS *benders, SCIP_SOL *sol, int probnumber, SCIP_Bool *infeasible, SCIP_BENDERSENFOTYPE type, SCIP_Bool solvecip, SCIP_Real *objective)
Definition: scip_benders.c:775
SCIP_RETCODE SCIPfreeBendersSubproblem(SCIP *scip, SCIP_BENDERS *benders, int probnumber)
Definition: scip_benders.c:819
#define SCIP_DECL_BENDERSEXITSOL(x)
Definition: type_benders.h:141
void SCIPbendersSetBenderscutsSorted(SCIP_BENDERS *benders, SCIP_Bool sorted)
Definition: benders.c:4780
SCIP_RETCODE SCIPsetBendersExitpre(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSEXITPRE((*bendersexitpre)))
Definition: scip_benders.c:303
SCIP_SET * set
Definition: struct_scip.h:62
public methods for message output
SCIP_MESSAGEHDLR * messagehdlr
Definition: struct_scip.h:65
#define SCIP_Real
Definition: def.h:164
#define SCIP_DECL_BENDERSCUTEXITSOL(x)
SCIP_RETCODE SCIPaddBendersSubproblem(SCIP *scip, SCIP_BENDERS *benders, SCIP *subproblem)
Definition: scip_benders.c:703
SCIP_RETCODE SCIPsetBenderscutInit(SCIP *scip, SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTINIT((*benderscutinit)))
#define SCIP_DECL_BENDERSPOSTSOLVE(x)
Definition: type_benders.h:301
void SCIPbendersSetCopy(SCIP_BENDERS *benders, SCIP_DECL_BENDERSCOPY((*benderscopy)))
Definition: benders.c:4068
SCIP_RETCODE SCIPsetBendersExitsol(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSEXITSOL((*bendersexitsol)))
Definition: scip_benders.c:351
#define SCIP_DECL_BENDERSEXITPRE(x)
Definition: type_benders.h:119
SCIP_RETCODE SCIPactivateBenders(SCIP *scip, SCIP_BENDERS *benders, int nsubproblems)
Definition: scip_benders.c:517
const char * SCIPbendersGetName(SCIP_BENDERS *benders)
Definition: benders.c:4211
SCIP_RETCODE SCIPbenderscutCreate(SCIP_BENDERS *benders, SCIP_BENDERSCUT **benderscut, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int priority, SCIP_Bool islpcut, SCIP_DECL_BENDERSCUTCOPY((*benderscutcopy)), SCIP_DECL_BENDERSCUTFREE((*benderscutfree)), SCIP_DECL_BENDERSCUTINIT((*benderscutinit)), SCIP_DECL_BENDERSCUTEXIT((*benderscutexit)), SCIP_DECL_BENDERSCUTINITSOL((*benderscutinitsol)), SCIP_DECL_BENDERSCUTEXITSOL((*benderscutexitsol)), SCIP_DECL_BENDERSCUTEXEC((*benderscutexec)), SCIP_BENDERSCUTDATA *benderscutdata)
Definition: benderscut.c:165
void SCIPbenderscutSetCopy(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTCOPY((*benderscutcopy)))
Definition: benderscut.c:442
SCIP_RETCODE SCIPsetBendersExit(SCIP *scip, SCIP_BENDERS *benders, SCIP_DECL_BENDERSEXIT((*bendersexit)))
Definition: scip_benders.c:255
datastructures for global SCIP settings
internal methods for Benders&#39; decomposition cuts
#define SCIP_DECL_BENDERSCUTINITSOL(x)
#define SCIP_DECL_BENDERSPRESUBSOLVE(x)
Definition: type_benders.h:192