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