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