Scippy

SCIP

Solving Constraint Integer Programs

benderscut.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2018 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scip.zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file benderscut.c
17  * @brief methods for Benders' decomposition cut
18  * @author Stephen J. Maher
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #include <assert.h>
24 #include <string.h>
25 
26 #include "scip/def.h"
27 #include "scip/set.h"
28 #include "scip/clock.h"
29 #include "scip/paramset.h"
30 #include "scip/scip.h"
31 #include "scip/benderscut.h"
32 #include "scip/reopt.h"
33 #include "scip/pub_message.h"
34 #include "scip/pub_misc.h"
35 #include "scip/pub_benders.h"
36 
37 #include "scip/struct_benderscut.h"
38 
39 #define BENDERSCUT_ARRAYSIZE 10 /**< the initial size of the added constraints/cuts arrays */
40 
41 /* default parameter settings for the Benders' decomposition cuts */
42 #define SCIP_DEFAULT_ENABLED TRUE
43 
44 /** compares two Benders' cuts w. r. to their delay positions and their priority */
45 SCIP_DECL_SORTPTRCOMP(SCIPbenderscutComp)
46 { /*lint --e{715}*/
47  SCIP_BENDERSCUT* benderscut1 = (SCIP_BENDERSCUT*)elem1;
48  SCIP_BENDERSCUT* benderscut2 = (SCIP_BENDERSCUT*)elem2;
49 
50  assert(benderscut1 != NULL);
51  assert(benderscut2 != NULL);
52 
53  return benderscut2->priority - benderscut1->priority; /* prefer higher priorities */
54 }
55 
56 /** comparison method for sorting Benders' cuts w.r.t. to their name */
57 SCIP_DECL_SORTPTRCOMP(SCIPbenderscutCompName)
58 {
60 }
61 
62 /** method to call, when the priority of a compression was changed */
63 static
64 SCIP_DECL_PARAMCHGD(paramChgdBenderscutPriority)
65 { /*lint --e{715}*/
66  SCIP_PARAMDATA* paramdata;
67 
68  paramdata = SCIPparamGetData(param);
69  assert(paramdata != NULL);
70 
71  /* use SCIPsetBenderscutPriority() to mark the compressions unsorted */
72  SCIP_CALL( SCIPsetBenderscutPriority(scip, (SCIP_BENDERSCUT*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
73 
74  return SCIP_OKAY;
75 }
76 
77 /** copies the given Benders' decomposition cut to a new scip */
79  SCIP_BENDERS* benders, /**< the Benders' decomposition that the cuts are copied to */
80  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
81  SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
82  )
83 {
84  assert(benderscut != NULL);
85  assert(set != NULL);
86  assert(set->scip != NULL);
87 
88  if( benderscut->benderscutcopy != NULL )
89  {
90  SCIPsetDebugMsg(set, "including benderscut %s in subscip %p\n", SCIPbenderscutGetName(benderscut), (void*)set->scip);
91  SCIP_CALL( benderscut->benderscutcopy(set->scip, benders, benderscut) );
92  }
93 
94  return SCIP_OKAY;
95 }
96 
97 /** creates a Benders' decomposition cut */
99  SCIP_BENDERS* benders, /**< Benders' decomposition */
100  SCIP_BENDERSCUT** benderscut, /**< pointer to the Benders' decomposition cut data structure */
101  SCIP_SET* set, /**< global SCIP settings */
102  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
103  BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
104  const char* name, /**< name of the Benders' decomposition cut */
105  const char* desc, /**< description of the Benders' decomposition cut */
106  int priority, /**< priority of the the Benders' decomposition cut */
107  SCIP_Bool islpcut, /**< indicates whether the cut is generated from the LP solution */
108  SCIP_DECL_BENDERSCUTCOPY((*benderscutcopy)),/**< copy method of the Benders' decomposition cut or NULL if you don't want to copy your plugin into sub-SCIPs */
109  SCIP_DECL_BENDERSCUTFREE((*benderscutfree)),/**< destructor of the Benders' decomposition cut */
110  SCIP_DECL_BENDERSCUTINIT((*benderscutinit)),/**< initialize the Benders' decomposition cut */
111  SCIP_DECL_BENDERSCUTEXIT((*benderscutexit)),/**< deinitialize the Benders' decomposition cut */
112  SCIP_DECL_BENDERSCUTINITSOL((*benderscutinitsol)),/**< solving process initialization method of the Benders' decomposition cut */
113  SCIP_DECL_BENDERSCUTEXITSOL((*benderscutexitsol)),/**< solving process deinitialization method of the Benders' decomposition cut */
114  SCIP_DECL_BENDERSCUTEXEC((*benderscutexec)),/**< execution method of the Benders' decomposition cut */
115  SCIP_BENDERSCUTDATA* benderscutdata /**< Benders' decomposition cut data */
116  )
117 {
118  char paramname[SCIP_MAXSTRLEN];
119  char paramdesc[SCIP_MAXSTRLEN];
120 
121  assert(benderscut != NULL);
122  assert(name != NULL);
123  assert(desc != NULL);
124  assert(benderscutexec != NULL);
125 
126  SCIP_ALLOC( BMSallocMemory(benderscut) );
127  SCIP_ALLOC( BMSduplicateMemoryArray(&(*benderscut)->name, name, strlen(name)+1) );
128  SCIP_ALLOC( BMSduplicateMemoryArray(&(*benderscut)->desc, desc, strlen(desc)+1) );
129  (*benderscut)->priority = priority;
130  (*benderscut)->islpcut = islpcut;
131  (*benderscut)->benderscutcopy = benderscutcopy;
132  (*benderscut)->benderscutfree = benderscutfree;
133  (*benderscut)->benderscutinit = benderscutinit;
134  (*benderscut)->benderscutexit = benderscutexit;
135  (*benderscut)->benderscutinitsol = benderscutinitsol;
136  (*benderscut)->benderscutexitsol = benderscutexitsol;
137  (*benderscut)->benderscutexec = benderscutexec;
138  (*benderscut)->benderscutdata = benderscutdata;
139  SCIP_CALL( SCIPclockCreate(&(*benderscut)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
140  SCIP_CALL( SCIPclockCreate(&(*benderscut)->benderscutclock, SCIP_CLOCKTYPE_DEFAULT) );
141  (*benderscut)->ncalls = 0;
142  (*benderscut)->nfound = 0;
143  (*benderscut)->initialized = FALSE;
144  (*benderscut)->addedconss = NULL;
145  (*benderscut)->addedcuts = NULL;
146  (*benderscut)->addedconsssize = 0;
147  (*benderscut)->addedcutssize = 0;
148  (*benderscut)->naddedconss = 0;
149  (*benderscut)->naddedcuts = 0;
150 
151  /* add parameters */
152  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "benders/%s/benderscut/%s/priority", SCIPbendersGetName(benders), name);
153  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of Benders' cut <%s>", name);
154  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
155  &(*benderscut)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4,
156  paramChgdBenderscutPriority, (SCIP_PARAMDATA*)(*benderscut)) ); /*lint !e740*/
157 
158  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "benders/%s/benderscut/%s/enabled", SCIPbendersGetName(benders), name);
159  SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname,
160  "is this Benders' decomposition cut method used to generate cuts?", &(*benderscut)->enabled, FALSE,
161  SCIP_DEFAULT_ENABLED, NULL, NULL) ); /*lint !e740*/
162 
163  return SCIP_OKAY;
164 }
165 
166 /** calls destructor and frees memory of the Benders' decomposition cut */
168  SCIP_BENDERSCUT** benderscut, /**< pointer to the Benders' decomposition cut data structure */
169  SCIP_SET* set /**< global SCIP settings */
170  )
171 {
172  assert(benderscut != NULL);
173  assert(*benderscut != NULL);
174  assert(!(*benderscut)->initialized);
175  assert(set != NULL);
176 
177  /* call destructor of the Benders' decomposition cut */
178  if( (*benderscut)->benderscutfree != NULL )
179  {
180  SCIP_CALL( (*benderscut)->benderscutfree(set->scip, *benderscut) );
181  }
182 
183  SCIPclockFree(&(*benderscut)->benderscutclock);
184  SCIPclockFree(&(*benderscut)->setuptime);
185  BMSfreeMemoryArray(&(*benderscut)->name);
186  BMSfreeMemoryArray(&(*benderscut)->desc);
187  BMSfreeMemory(benderscut);
188 
189  return SCIP_OKAY;
190 }
191 
192 /** initializes the Benders' decomposition cut */
194  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
195  SCIP_SET* set /**< global SCIP settings */
196  )
197 {
198  assert(benderscut != NULL);
199  assert(set != NULL);
200 
201  if( benderscut->initialized )
202  {
203  SCIPerrorMessage("Benders' decomposition cut <%s> already initialized\n", benderscut->name);
204  return SCIP_INVALIDCALL;
205  }
206 
207  if( set->misc_resetstat )
208  {
209  SCIPclockReset(benderscut->setuptime);
210  SCIPclockReset(benderscut->benderscutclock);
211 
212  benderscut->ncalls = 0;
213  benderscut->nfound = 0;
214  }
215 
216  /* allocating memory for the added constraint/cut arrays */
217  if( benderscut->addedconsssize == 0 )
218  {
220  benderscut->addedconsssize = BENDERSCUT_ARRAYSIZE;
221  }
222 
223  if( benderscut->addedcutssize == 0 )
224  {
226  benderscut->addedcutssize = BENDERSCUT_ARRAYSIZE;
227  }
228 
229  if( benderscut->benderscutinit != NULL )
230  {
231  /* start timing */
232  SCIPclockStart(benderscut->setuptime, set);
233 
234  SCIP_CALL( benderscut->benderscutinit(set->scip, benderscut) );
235 
236  /* stop timing */
237  SCIPclockStop(benderscut->setuptime, set);
238  }
239  benderscut->initialized = TRUE;
240 
241  return SCIP_OKAY;
242 }
243 
244 /** calls exit method of the Benders' decomposition cut */
246  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
247  SCIP_SET* set /**< global SCIP settings */
248  )
249 {
250  int i;
251 
252  assert(benderscut != NULL);
253  assert(set != NULL);
254 
255  if( !benderscut->initialized )
256  {
257  SCIPerrorMessage("Benders' decomposition cut <%s> not initialized\n", benderscut->name);
258  return SCIP_INVALIDCALL;
259  }
260 
261  /* releasing the stored rows and constraints */
262  for( i = 0; i < benderscut->naddedcuts; i++ )
263  {
264  SCIP_CALL( SCIPreleaseRow(set->scip, &benderscut->addedcuts[i]) );
265  }
266 
267  for( i = 0; i < benderscut->naddedconss; i++ )
268  {
269  SCIP_CALL( SCIPreleaseCons(set->scip, &benderscut->addedconss[i]) );
270  }
271 
272  BMSfreeBlockMemoryArray(SCIPblkmem(set->scip), &benderscut->addedcuts, benderscut->addedcutssize);
273  BMSfreeBlockMemoryArray(SCIPblkmem(set->scip), &benderscut->addedconss, benderscut->addedconsssize);
274  benderscut->addedconsssize = 0;
275  benderscut->addedcutssize = 0;
276  benderscut->naddedconss = 0;
277  benderscut->naddedcuts = 0;
278 
279  if( benderscut->benderscutexit != NULL )
280  {
281  /* start timing */
282  SCIPclockStart(benderscut->setuptime, set);
283 
284  SCIP_CALL( benderscut->benderscutexit(set->scip, benderscut) );
285 
286  /* stop timing */
287  SCIPclockStop(benderscut->setuptime, set);
288  }
289  benderscut->initialized = FALSE;
290 
291  return SCIP_OKAY;
292 }
293 
294 /** informs Benders' cut that the branch and bound process is being started */
296  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
297  SCIP_SET* set /**< global SCIP settings */
298  )
299 {
300  assert(benderscut != NULL);
301  assert(set != NULL);
302 
303  /* call solving process initialization method of the Benders' decomposition cut */
304  if( benderscut->benderscutinitsol != NULL )
305  {
306  /* start timing */
307  SCIPclockStart(benderscut->setuptime, set);
308 
309  SCIP_CALL( benderscut->benderscutinitsol(set->scip, benderscut) );
310 
311  /* stop timing */
312  SCIPclockStop(benderscut->setuptime, set);
313  }
314 
315  return SCIP_OKAY;
316 }
317 
318 /** informs Benders' decomposition that the branch and bound process data is being freed */
320  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition */
321  SCIP_SET* set /**< global SCIP settings */
322  )
323 {
324  assert(benderscut != NULL);
325  assert(set != NULL);
326 
327  /* call solving process deinitialization method of Benders' decomposition cut */
328  if( benderscut->benderscutexitsol != NULL )
329  {
330  /* start timing */
331  SCIPclockStart(benderscut->setuptime, set);
332 
333  SCIP_CALL( benderscut->benderscutexitsol(set->scip, benderscut) );
334 
335  /* stop timing */
336  SCIPclockStop(benderscut->setuptime, set);
337  }
338 
339  return SCIP_OKAY;
340 }
341 
342 /** calls execution method of the Benders' decomposition cut */
344  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
345  SCIP_SET* set, /**< global SCIP settings */
346  SCIP_BENDERS* benders, /**< Benders' decomposition */
347  SCIP_SOL* sol, /**< primal CIP solution */
348  int probnumber, /**< the number of the subproblem for which the cut is generated */
349  SCIP_BENDERSENFOTYPE type, /**< the enforcement type calling this function */
350  SCIP_RESULT* result /**< pointer to store the result of the callback method */
351  )
352 {
353  SCIP_RESULT cutresult;
354 
355  assert(benderscut != NULL);
356  assert(benderscut->benderscutexec != NULL);
357  assert(set != NULL);
358  assert(set->scip != NULL);
359  assert(result != NULL);
360 
361  cutresult = SCIP_DIDNOTRUN;
362 
363  SCIPsetDebugMsg(set, "executing Benders' decomposition cut <%s>\n", benderscut->name);
364 
365  /* start timing */
366  SCIPclockStart(benderscut->benderscutclock, set);
367 
368  /* call the Benders' decomposition cut if it is enabled */
369  if( benderscut->enabled )
370  {
371  SCIP_CALL( benderscut->benderscutexec(set->scip, benders, benderscut, sol, probnumber, type, &cutresult) );
372  }
373 
374  /* stop timing */
375  SCIPclockStop(benderscut->benderscutclock, set);
376 
377  /* evaluate result */
378  if( cutresult != SCIP_DIDNOTRUN
379  && cutresult != SCIP_DIDNOTFIND
380  && cutresult != SCIP_CONSADDED
381  && cutresult != SCIP_FEASIBLE
382  && cutresult != SCIP_SEPARATED )
383  {
384  SCIPerrorMessage("execution method of Benders' decomposition cut <%s> returned invalid result <%d>\n",
385  benderscut->name, cutresult);
386  return SCIP_INVALIDRESULT;
387  }
388 
389  benderscut->ncalls++;
390 
391  if( cutresult == SCIP_CONSADDED || cutresult == SCIP_SEPARATED )
392  benderscut->nfound++;
393 
394  (*result) = cutresult;
395 
396  return SCIP_OKAY;
397 }
398 
399 /** gets user data of the Benders' decomposition cut */
401  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
402  )
403 {
404  assert(benderscut != NULL);
405 
406  return benderscut->benderscutdata;
407 }
408 
409 /** sets user data of the Benders' decomposition cut; user has to free old data in advance! */
411  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
412  SCIP_BENDERSCUTDATA* benderscutdata /**< new Benders' decomposition cut user data */
413  )
414 {
415  assert(benderscut != NULL);
416 
417  benderscut->benderscutdata = benderscutdata;
418 }
419 
420 /* new callback setter methods */
421 
422 /** sets copy callback of the Benders' decomposition cut */
424  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
425  SCIP_DECL_BENDERSCUTCOPY((*benderscutcopy))/**< copy callback of the Benders' decomposition cut or NULL if you don't want to copy your plugin into sub-SCIPs */
426  )
427 {
428  assert(benderscut != NULL);
429 
430  benderscut->benderscutcopy = benderscutcopy;
431 }
432 
433 /** sets destructor callback of the Benders' decomposition cut */
435  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
436  SCIP_DECL_BENDERSCUTFREE((*benderscutfree))/**< destructor of the Benders' decomposition cut */
437  )
438 {
439  assert(benderscut != NULL);
440 
441  benderscut->benderscutfree = benderscutfree;
442 }
443 
444 /** sets initialization callback of the Benders' decomposition cut */
446  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
447  SCIP_DECL_BENDERSCUTINIT((*benderscutinit))/**< initialize the Benders' decomposition cut */
448  )
449 {
450  assert(benderscut != NULL);
451 
452  benderscut->benderscutinit = benderscutinit;
453 }
454 
455 /** sets deinitialization callback of the Benders' decomposition cut */
457  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
458  SCIP_DECL_BENDERSCUTEXIT((*benderscutexit))/**< deinitialize the Benders' decomposition cut */
459  )
460 {
461  assert(benderscut != NULL);
462 
463  benderscut->benderscutexit = benderscutexit;
464 }
465 
466 /** sets solving process initialization callback of the Benders' decomposition cut */
468  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
469  SCIP_DECL_BENDERSCUTINITSOL((*benderscutinitsol))/**< solving process initialization callback of the Benders' decomposition cut */
470  )
471 {
472  assert(benderscut != NULL);
473 
474  benderscut->benderscutinitsol = benderscutinitsol;
475 }
476 
477 /** sets solving process deinitialization callback of Benders' decomposition cut */
479  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
480  SCIP_DECL_BENDERSCUTEXITSOL((*benderscutexitsol))/**< solving process deinitialization callback of the Benders' decomposition cut */
481  )
482 {
483  assert(benderscut != NULL);
484 
485  benderscut->benderscutexitsol = benderscutexitsol;
486 }
487 
488 /** gets name of the Benders' decomposition cut */
490  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
491  )
492 {
493  assert(benderscut != NULL);
494 
495  return benderscut->name;
496 }
497 
498 /** gets description of the Benders' decomposition cut */
500  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
501  )
502 {
503  assert(benderscut != NULL);
504 
505  return benderscut->desc;
506 }
507 
508 /** gets priority of the Benders' decomposition cut */
510  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
511  )
512 {
513  assert(benderscut != NULL);
514 
515  return benderscut->priority;
516 }
517 
518 /** sets priority of the Benders' decomposition cut */
520  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
521  int priority /**< new priority of the Benders' decomposition cut */
522  )
523 {
524  assert(benderscut != NULL);
525 
526  benderscut->priority = priority;
527 }
528 
529 /** gets the number of times, the heuristic was called and tried to find a solution */
531  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
532  )
533 {
534  assert(benderscut != NULL);
535 
536  return benderscut->ncalls;
537 }
538 
539 /** gets the number of Benders' cuts found by this Benders' decomposition cut */
541  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
542  )
543 {
544  assert(benderscut != NULL);
545 
546  return benderscut->nfound;
547 }
548 
549 /** is the Benders' decomposition cut initialized? */
551  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
552  )
553 {
554  assert(benderscut != NULL);
555 
556  return benderscut->initialized;
557 }
558 
559 /** gets time in seconds used by this Benders' decomposition cut for setting up */
561  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
562  )
563 {
564  assert(benderscut != NULL);
565 
566  return SCIPclockGetTime(benderscut->setuptime);
567 }
568 
569 /** gets time in seconds used in this Benders' decomposition cut */
571  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
572  )
573 {
574  assert(benderscut != NULL);
575 
576  return SCIPclockGetTime(benderscut->benderscutclock);
577 }
578 
579 /** returns the constraints that have been added by the Benders' cut plugin */
581  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
582  SCIP_CONS*** addedconss, /**< pointer to store the constraint array, can be NULL */
583  int* naddedconss /**< pointer to store the number of added constraints, can be NULL */
584  )
585 {
586  assert(benderscut != NULL);
587 
588  if( addedconss != NULL )
589  (*addedconss) = benderscut->addedconss;
590 
591  if( naddedconss != NULL )
592  (*naddedconss) = benderscut->naddedconss;
593 
594  return SCIP_OKAY;
595 }
596 
597 /** returns the cuts that have been added by the Benders' cut plugin */
599  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
600  SCIP_ROW*** addedcuts, /**< pointer to store the cuts array, can be NULL */
601  int* naddedcuts /**< pointer to store the number of added cut, can be NULL */
602  )
603 {
604  assert(benderscut != NULL);
605 
606  if( addedcuts != NULL )
607  (*addedcuts) = benderscut->addedcuts;
608 
609  if( naddedcuts != NULL )
610  (*naddedcuts) = benderscut->naddedcuts;
611 
612  return SCIP_OKAY;
613 }
614 
615 /** adds the generated constraint to the Benders' cut storage */
617  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
618  SCIP_SET* set, /**< global SCIP settings */
619  SCIP_CONS* cons /**< the constraint to be added to the Benders' cut storage */
620  )
621 {
622  assert(benderscut != NULL);
623  assert(set != NULL);
624  assert(cons != NULL);
625 
626  /* ensuring the required memory is available for the added constraints array */
627  if( benderscut->addedconsssize < benderscut->naddedconss + 1 )
628  {
629  int newsize;
630 
631  newsize = SCIPsetCalcMemGrowSize(set, benderscut->naddedconss + 1);
633  benderscut->addedconsssize, newsize) );
634  benderscut->addedconsssize = newsize;
635  }
636  assert(benderscut->addedconsssize >= benderscut->naddedconss + 1);
637 
638  /* adding the constraint to the Benders' cut storage */
639  benderscut->addedconss[benderscut->naddedconss] = cons;
640  benderscut->naddedconss++;
641 
642  return SCIP_OKAY;
643 }
644 
645 /** adds the generated cuts to the Benders' cut storage */
647  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
648  SCIP_SET* set, /**< global SCIP settings */
649  SCIP_ROW* cut /**< the cut to be added to the Benders' cut storage */
650  )
651 {
652  assert(benderscut != NULL);
653  assert(set != NULL);
654  assert(cut != NULL);
655 
656  /* ensuring the required memory is available for the added cuts array */
657  if( benderscut->addedcutssize < benderscut->naddedcuts + 1 )
658  {
659  int newsize;
660 
661  newsize = SCIPsetCalcMemGrowSize(set, benderscut->naddedcuts + 1);
662  SCIP_ALLOC( BMSreallocBlockMemoryArray(SCIPblkmem(set->scip), &benderscut->addedcuts,
663  benderscut->addedcutssize, newsize) );
664 
665  benderscut->addedcutssize = newsize;
666  }
667  assert(benderscut->addedcutssize >= benderscut->naddedcuts + 1);
668 
669  /* adding the cuts to the Benders' cut storage */
670  benderscut->addedcuts[benderscut->naddedcuts] = cut;
671  benderscut->naddedcuts++;
672 
673  return SCIP_OKAY;
674 }
675 
676 /** returns whether the Benders' cut uses the LP information */
678  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
679  )
680 {
681  assert(benderscut != NULL);
682 
683  return benderscut->islpcut;
684 }
685 
686 /** sets the enabled flag of the Benders' decomposition cut method */
688  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
689  SCIP_Bool enabled /**< flag to indicate whether the Benders' decomposition cut is enabled */
690  )
691 {
692  assert(benderscut != NULL);
693 
694  benderscut->enabled = enabled;
695 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
SCIP_RETCODE SCIPbenderscutExec(SCIP_BENDERSCUT *benderscut, SCIP_SET *set, SCIP_BENDERS *benders, SCIP_SOL *sol, int probnumber, SCIP_BENDERSENFOTYPE type, SCIP_RESULT *result)
Definition: benderscut.c:343
const char * SCIPbenderscutGetName(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:489
#define NULL
Definition: def.h:239
struct SCIP_BenderscutData SCIP_BENDERSCUTDATA
SCIP_BENDERSCUTDATA * SCIPbenderscutGetData(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:400
SCIP_RETCODE SCIPbenderscutStoreCut(SCIP_BENDERSCUT *benderscut, SCIP_SET *set, SCIP_ROW *cut)
Definition: benderscut.c:646
SCIP_PARAMDATA * SCIPparamGetData(SCIP_PARAM *param)
Definition: paramset.c:661
#define SCIP_MAXSTRLEN
Definition: def.h:260
const char * SCIPbendersGetName(SCIP_BENDERS *benders)
Definition: benders.c:4194
void SCIPbenderscutSetPriority(SCIP_BENDERSCUT *benderscut, int priority)
Definition: benderscut.c:519
internal methods for clocks and timing issues
#define SCIP_DECL_BENDERSCUTFREE(x)
struct SCIP_ParamData SCIP_PARAMDATA
Definition: type_paramset.h:76
void SCIPbenderscutSetInitsol(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTINITSOL((*benderscutinitsol)))
Definition: benderscut.c:467
void SCIPbenderscutSetData(SCIP_BENDERSCUT *benderscut, SCIP_BENDERSCUTDATA *benderscutdata)
Definition: benderscut.c:410
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:350
#define FALSE
Definition: def.h:65
public methods for Benders&#39; decomposition
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:280
#define BENDERSCUT_ARRAYSIZE
Definition: benderscut.c:39
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10017
#define TRUE
Definition: def.h:64
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
enum SCIP_BendersEnfoType SCIP_BENDERSENFOTYPE
Definition: type_benders.h:42
SCIP_Bool SCIPbenderscutIsInitialized(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:550
const char * SCIPbenderscutGetDesc(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:499
SCIP_Longint ncalls
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5503
#define SCIP_DECL_BENDERSCUTEXEC(x)
SCIP_RETCODE SCIPbenderscutStoreCons(SCIP_BENDERSCUT *benderscut, SCIP_SET *set, SCIP_CONS *cons)
Definition: benderscut.c:616
SCIP_RETCODE SCIPbenderscutCopyInclude(SCIP_BENDERS *benders, SCIP_BENDERSCUT *benderscut, SCIP_SET *set)
Definition: benderscut.c:78
internal methods for handling parameter settings
#define BMSfreeMemory(ptr)
Definition: memory.h:127
#define SCIP_DECL_BENDERSCUTCOPY(x)
SCIP_RETCODE SCIPbenderscutGetAddedCuts(SCIP_BENDERSCUT *benderscut, SCIP_ROW ***addedcuts, int *naddedcuts)
Definition: benderscut.c:598
SCIP_Real SCIPbenderscutGetTime(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:570
SCIP_Longint SCIPbenderscutGetNFound(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:540
#define SCIP_DEFAULT_ENABLED
Definition: benderscut.c:42
datastructures for Benders&#39; decomposition cuts techniques
#define SCIP_DECL_BENDERSCUTINIT(x)
static SCIP_DECL_PARAMCHGD(paramChgdBenderscutPriority)
Definition: benderscut.c:64
void SCIPbenderscutSetExit(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTEXIT((*benderscutexit)))
Definition: benderscut.c:456
SCIP_CONS ** addedconss
SCIP_CLOCK * setuptime
void SCIPbenderscutSetEnabled(SCIP_BENDERSCUT *benderscut, SCIP_Bool enabled)
Definition: benderscut.c:687
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:129
#define SCIPerrorMessage
Definition: pub_message.h:45
SCIP_Longint SCIPbenderscutGetNCalls(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:530
int SCIPbenderscutGetPriority(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:509
void SCIPclockReset(SCIP_CLOCK *clck)
Definition: clock.c:199
SCIP_RETCODE SCIPbenderscutFree(SCIP_BENDERSCUT **benderscut, SCIP_SET *set)
Definition: benderscut.c:167
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:128
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:428
#define SCIP_DECL_BENDERSCUTEXIT(x)
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:351
void SCIPbenderscutSetExitsol(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTEXITSOL((*benderscutexitsol)))
Definition: benderscut.c:478
SCIP_RETCODE SCIPsetAddIntParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: set.c:2879
SCIP_RETCODE SCIPsetBenderscutPriority(SCIP *scip, SCIP_BENDERSCUT *benderscut, int priority)
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:125
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:160
data structures and methods for collecting reoptimization information
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:62
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:435
void SCIPbenderscutSetFree(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTFREE((*benderscutfree)))
Definition: benderscut.c:434
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:175
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:448
SCIP_DECL_SORTPTRCOMP(SCIPbenderscutComp)
Definition: benderscut.c:45
#define SCIPsetDebugMsg
Definition: set.h:1940
SCIP_CLOCK * benderscutclock
SCIP_RETCODE SCIPbenderscutInitsol(SCIP_BENDERSCUT *benderscut, SCIP_SET *set)
Definition: benderscut.c:295
SCIP_RETCODE SCIPbenderscutGetAddedConss(SCIP_BENDERSCUT *benderscut, SCIP_CONS ***addedconss, int *naddedconss)
Definition: benderscut.c:580
SCIP_Real SCIPbenderscutGetSetupTime(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:560
void SCIPbenderscutSetInit(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTINIT((*benderscutinit)))
Definition: benderscut.c:445
int SCIPparamGetInt(SCIP_PARAM *param)
Definition: paramset.c:716
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip_lp.c:1474
SCIP_Bool SCIPbenderscutIsLPCut(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:677
SCIP_Longint nfound
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1187
SCIP_RETCODE SCIPbenderscutExit(SCIP_BENDERSCUT *benderscut, SCIP_SET *set)
Definition: benderscut.c:245
public methods for message output
#define SCIP_Real
Definition: def.h:150
#define SCIP_DECL_BENDERSCUTEXITSOL(x)
#define BMSallocMemory(ptr)
Definition: memory.h:101
#define SCIP_Longint
Definition: def.h:135
SCIP_BENDERSCUTDATA * benderscutdata
SCIP_RETCODE SCIPbenderscutExitsol(SCIP_BENDERSCUT *benderscut, SCIP_SET *set)
Definition: benderscut.c:319
common defines and data types used in all packages of SCIP
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:419
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:98
void SCIPbenderscutSetCopy(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTCOPY((*benderscutcopy)))
Definition: benderscut.c:423
#define SCIP_ALLOC(x)
Definition: def.h:362
SCIP_RETCODE SCIPsetAddBoolParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: set.c:2857
#define BMSreallocBlockMemoryArray(mem, ptr, oldnum, newnum)
Definition: memory.h:439
internal methods for Benders&#39; decomposition cuts
SCIP_RETCODE SCIPbenderscutInit(SCIP_BENDERSCUT *benderscut, SCIP_SET *set)
Definition: benderscut.c:193
SCIP_ROW ** addedcuts
#define SCIP_DECL_BENDERSCUTINITSOL(x)
SCIP callable library.