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-2019 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scip.zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file 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 /** internal method for creating a Benders' decomposition structure */
98 static
100  SCIP_BENDERS* benders, /**< Benders' decomposition */
101  SCIP_BENDERSCUT** benderscut, /**< pointer to the Benders' decomposition cut data structure */
102  SCIP_SET* set, /**< global SCIP settings */
103  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
104  BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
105  const char* name, /**< name of the Benders' decomposition cut */
106  const char* desc, /**< description of the Benders' decomposition cut */
107  int priority, /**< priority of the the Benders' decomposition cut */
108  SCIP_Bool islpcut, /**< indicates whether the cut is generated from the LP solution */
109  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 */
110  SCIP_DECL_BENDERSCUTFREE((*benderscutfree)),/**< destructor of the Benders' decomposition cut */
111  SCIP_DECL_BENDERSCUTINIT((*benderscutinit)),/**< initialize the Benders' decomposition cut */
112  SCIP_DECL_BENDERSCUTEXIT((*benderscutexit)),/**< deinitialize the Benders' decomposition cut */
113  SCIP_DECL_BENDERSCUTINITSOL((*benderscutinitsol)),/**< solving process initialization method of the Benders' decomposition cut */
114  SCIP_DECL_BENDERSCUTEXITSOL((*benderscutexitsol)),/**< solving process deinitialization method of the Benders' decomposition cut */
115  SCIP_DECL_BENDERSCUTEXEC((*benderscutexec)),/**< execution method of the Benders' decomposition cut */
116  SCIP_BENDERSCUTDATA* benderscutdata /**< Benders' decomposition cut data */
117  )
118 {
119  char paramname[SCIP_MAXSTRLEN];
120  char paramdesc[SCIP_MAXSTRLEN];
121 
122  assert(benderscut != NULL);
123  assert(name != NULL);
124  assert(desc != NULL);
125  assert(benderscutexec != NULL);
126 
127  SCIP_ALLOC( BMSallocMemory(benderscut) );
128  SCIP_ALLOC( BMSduplicateMemoryArray(&(*benderscut)->name, name, strlen(name)+1) );
129  SCIP_ALLOC( BMSduplicateMemoryArray(&(*benderscut)->desc, desc, strlen(desc)+1) );
130  (*benderscut)->priority = priority;
131  (*benderscut)->islpcut = islpcut;
132  (*benderscut)->benderscutcopy = benderscutcopy;
133  (*benderscut)->benderscutfree = benderscutfree;
134  (*benderscut)->benderscutinit = benderscutinit;
135  (*benderscut)->benderscutexit = benderscutexit;
136  (*benderscut)->benderscutinitsol = benderscutinitsol;
137  (*benderscut)->benderscutexitsol = benderscutexitsol;
138  (*benderscut)->benderscutexec = benderscutexec;
139  (*benderscut)->benderscutdata = benderscutdata;
140  SCIP_CALL( SCIPclockCreate(&(*benderscut)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
141  SCIP_CALL( SCIPclockCreate(&(*benderscut)->benderscutclock, SCIP_CLOCKTYPE_DEFAULT) );
142  (*benderscut)->ncalls = 0;
143  (*benderscut)->nfound = 0;
144  (*benderscut)->initialized = FALSE;
145  (*benderscut)->addedcuts = NULL;
146  (*benderscut)->addedcutssize = 0;
147  (*benderscut)->naddedcuts = 0;
148 
149  /* add parameters */
150  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "benders/%s/benderscut/%s/priority", SCIPbendersGetName(benders), name);
151  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of Benders' cut <%s>", name);
152  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
153  &(*benderscut)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4,
154  paramChgdBenderscutPriority, (SCIP_PARAMDATA*)(*benderscut)) ); /*lint !e740*/
155 
156  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "benders/%s/benderscut/%s/enabled", SCIPbendersGetName(benders), name);
157  SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname,
158  "is this Benders' decomposition cut method used to generate cuts?", &(*benderscut)->enabled, FALSE,
159  SCIP_DEFAULT_ENABLED, NULL, NULL) ); /*lint !e740*/
160 
161  return SCIP_OKAY;
162 }
163 
164 /** creates a Benders' decomposition cut */
166  SCIP_BENDERS* benders, /**< Benders' decomposition */
167  SCIP_BENDERSCUT** benderscut, /**< pointer to the Benders' decomposition cut data structure */
168  SCIP_SET* set, /**< global SCIP settings */
169  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
170  BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
171  const char* name, /**< name of the Benders' decomposition cut */
172  const char* desc, /**< description of the Benders' decomposition cut */
173  int priority, /**< priority of the the Benders' decomposition cut */
174  SCIP_Bool islpcut, /**< indicates whether the cut is generated from the LP solution */
175  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 */
176  SCIP_DECL_BENDERSCUTFREE((*benderscutfree)),/**< destructor of the Benders' decomposition cut */
177  SCIP_DECL_BENDERSCUTINIT((*benderscutinit)),/**< initialize the Benders' decomposition cut */
178  SCIP_DECL_BENDERSCUTEXIT((*benderscutexit)),/**< deinitialize the Benders' decomposition cut */
179  SCIP_DECL_BENDERSCUTINITSOL((*benderscutinitsol)),/**< solving process initialization method of the Benders' decomposition cut */
180  SCIP_DECL_BENDERSCUTEXITSOL((*benderscutexitsol)),/**< solving process deinitialization method of the Benders' decomposition cut */
181  SCIP_DECL_BENDERSCUTEXEC((*benderscutexec)),/**< execution method of the Benders' decomposition cut */
182  SCIP_BENDERSCUTDATA* benderscutdata /**< Benders' decomposition cut data */
183  )
184 {
185  assert(benderscut != NULL);
186  assert(name != NULL);
187  assert(desc != NULL);
188  assert(benderscutexec != NULL);
189 
190  SCIP_CALL_FINALLY( doBenderscutCreate(benders, benderscut, set, messagehdlr, blkmem, name, desc, priority, islpcut,
191  benderscutcopy, benderscutfree, benderscutinit, benderscutexit, benderscutinitsol, benderscutexitsol,
192  benderscutexec, benderscutdata), (void)SCIPbenderscutFree(benderscut, set) );
193 
194  return SCIP_OKAY;
195 }
196 
197 /** calls destructor and frees memory of the Benders' decomposition cut */
199  SCIP_BENDERSCUT** benderscut, /**< pointer to the Benders' decomposition cut data structure */
200  SCIP_SET* set /**< global SCIP settings */
201  )
202 {
203  assert(benderscut != NULL);
204  assert(*benderscut != NULL);
205  assert(!(*benderscut)->initialized);
206  assert(set != NULL);
207 
208  /* call destructor of the Benders' decomposition cut */
209  if( (*benderscut)->benderscutfree != NULL )
210  {
211  SCIP_CALL( (*benderscut)->benderscutfree(set->scip, *benderscut) );
212  }
213 
214  SCIPclockFree(&(*benderscut)->benderscutclock);
215  SCIPclockFree(&(*benderscut)->setuptime);
216  BMSfreeMemoryArray(&(*benderscut)->name);
217  BMSfreeMemoryArray(&(*benderscut)->desc);
218  BMSfreeMemory(benderscut);
219 
220  return SCIP_OKAY;
221 }
222 
223 /** initializes the Benders' decomposition cut */
225  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
226  SCIP_SET* set /**< global SCIP settings */
227  )
228 {
229  assert(benderscut != NULL);
230  assert(set != NULL);
231 
232  if( benderscut->initialized )
233  {
234  SCIPerrorMessage("Benders' decomposition cut <%s> already initialized\n", benderscut->name);
235  return SCIP_INVALIDCALL;
236  }
237 
238  if( set->misc_resetstat )
239  {
240  SCIPclockReset(benderscut->setuptime);
241  SCIPclockReset(benderscut->benderscutclock);
242 
243  benderscut->ncalls = 0;
244  benderscut->nfound = 0;
245  }
246 
247  /* allocating memory for the added constraint/cut arrays */
248  if( benderscut->addedcutssize == 0 )
249  {
251  benderscut->addedcutssize = BENDERSCUT_ARRAYSIZE;
252  }
253 
254  if( benderscut->benderscutinit != NULL )
255  {
256  /* start timing */
257  SCIPclockStart(benderscut->setuptime, set);
258 
259  SCIP_CALL( benderscut->benderscutinit(set->scip, benderscut) );
260 
261  /* stop timing */
262  SCIPclockStop(benderscut->setuptime, set);
263  }
264  benderscut->initialized = TRUE;
265 
266  return SCIP_OKAY;
267 }
268 
269 /** calls exit method of the Benders' decomposition cut */
271  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
272  SCIP_SET* set /**< global SCIP settings */
273  )
274 {
275  int i;
276 
277  assert(benderscut != NULL);
278  assert(set != NULL);
279 
280  if( !benderscut->initialized )
281  {
282  SCIPerrorMessage("Benders' decomposition cut <%s> not initialized\n", benderscut->name);
283  return SCIP_INVALIDCALL;
284  }
285 
286  /* releasing the stored rows and constraints */
287  for( i = benderscut->naddedcuts - 1; i >= 0; i-- )
288  {
289  SCIPfreeBlockMemoryArray(set->scip, &benderscut->addedcuts[i]->vals, benderscut->addedcuts[i]->nvars);
290  SCIPfreeBlockMemoryArray(set->scip, &benderscut->addedcuts[i]->vars, benderscut->addedcuts[i]->nvars);
291  SCIPfreeBlockMemory(set->scip, &benderscut->addedcuts[i]); /*lint !e866*/
292  }
293 
294  BMSfreeBlockMemoryArray(SCIPblkmem(set->scip), &benderscut->addedcuts, benderscut->addedcutssize);
295  benderscut->addedcutssize = 0;
296  benderscut->naddedcuts = 0;
297 
298  if( benderscut->benderscutexit != NULL )
299  {
300  /* start timing */
301  SCIPclockStart(benderscut->setuptime, set);
302 
303  SCIP_CALL( benderscut->benderscutexit(set->scip, benderscut) );
304 
305  /* stop timing */
306  SCIPclockStop(benderscut->setuptime, set);
307  }
308  benderscut->initialized = FALSE;
309 
310  return SCIP_OKAY;
311 }
312 
313 /** informs Benders' cut that the branch and bound process is being started */
315  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
316  SCIP_SET* set /**< global SCIP settings */
317  )
318 {
319  assert(benderscut != NULL);
320  assert(set != NULL);
321 
322  /* call solving process initialization method of the Benders' decomposition cut */
323  if( benderscut->benderscutinitsol != NULL )
324  {
325  /* start timing */
326  SCIPclockStart(benderscut->setuptime, set);
327 
328  SCIP_CALL( benderscut->benderscutinitsol(set->scip, benderscut) );
329 
330  /* stop timing */
331  SCIPclockStop(benderscut->setuptime, set);
332  }
333 
334  return SCIP_OKAY;
335 }
336 
337 /** informs Benders' decomposition that the branch and bound process data is being freed */
339  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition */
340  SCIP_SET* set /**< global SCIP settings */
341  )
342 {
343  assert(benderscut != NULL);
344  assert(set != NULL);
345 
346  /* call solving process deinitialization method of Benders' decomposition cut */
347  if( benderscut->benderscutexitsol != NULL )
348  {
349  /* start timing */
350  SCIPclockStart(benderscut->setuptime, set);
351 
352  SCIP_CALL( benderscut->benderscutexitsol(set->scip, benderscut) );
353 
354  /* stop timing */
355  SCIPclockStop(benderscut->setuptime, set);
356  }
357 
358  return SCIP_OKAY;
359 }
360 
361 /** calls execution method of the Benders' decomposition cut */
363  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
364  SCIP_SET* set, /**< global SCIP settings */
365  SCIP_BENDERS* benders, /**< Benders' decomposition */
366  SCIP_SOL* sol, /**< primal CIP solution */
367  int probnumber, /**< the number of the subproblem for which the cut is generated */
368  SCIP_BENDERSENFOTYPE type, /**< the enforcement type calling this function */
369  SCIP_RESULT* result /**< pointer to store the result of the callback method */
370  )
371 {
372  SCIP_RESULT cutresult;
373 
374  assert(benderscut != NULL);
375  assert(benderscut->benderscutexec != NULL);
376  assert(set != NULL);
377  assert(set->scip != NULL);
378  assert(result != NULL);
379 
380  cutresult = SCIP_DIDNOTRUN;
381 
382  SCIPsetDebugMsg(set, "executing Benders' decomposition cut <%s>\n", benderscut->name);
383 
384  /* start timing */
385  SCIPclockStart(benderscut->benderscutclock, set);
386 
387  /* call the Benders' decomposition cut if it is enabled */
388  if( benderscut->enabled )
389  {
390  SCIP_CALL( benderscut->benderscutexec(set->scip, benders, benderscut, sol, probnumber, type, &cutresult) );
391  }
392 
393  /* stop timing */
394  SCIPclockStop(benderscut->benderscutclock, set);
395 
396  /* evaluate result */
397  if( cutresult != SCIP_DIDNOTRUN
398  && cutresult != SCIP_DIDNOTFIND
399  && cutresult != SCIP_CONSADDED
400  && cutresult != SCIP_FEASIBLE
401  && cutresult != SCIP_SEPARATED )
402  {
403  SCIPerrorMessage("execution method of Benders' decomposition cut <%s> returned invalid result <%d>\n",
404  benderscut->name, cutresult);
405  return SCIP_INVALIDRESULT;
406  }
407 
408  benderscut->ncalls++;
409 
410  if( cutresult == SCIP_CONSADDED || cutresult == SCIP_SEPARATED )
411  benderscut->nfound++;
412 
413  (*result) = cutresult;
414 
415  return SCIP_OKAY;
416 }
417 
418 /** gets user data of the Benders' decomposition cut */
420  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
421  )
422 {
423  assert(benderscut != NULL);
424 
425  return benderscut->benderscutdata;
426 }
427 
428 /** sets user data of the Benders' decomposition cut; user has to free old data in advance! */
430  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
431  SCIP_BENDERSCUTDATA* benderscutdata /**< new Benders' decomposition cut user data */
432  )
433 {
434  assert(benderscut != NULL);
435 
436  benderscut->benderscutdata = benderscutdata;
437 }
438 
439 /* new callback setter methods */
440 
441 /** sets copy callback of the Benders' decomposition cut */
443  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
444  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 */
445  )
446 {
447  assert(benderscut != NULL);
448 
449  benderscut->benderscutcopy = benderscutcopy;
450 }
451 
452 /** sets destructor callback of the Benders' decomposition cut */
454  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
455  SCIP_DECL_BENDERSCUTFREE((*benderscutfree))/**< destructor of the Benders' decomposition cut */
456  )
457 {
458  assert(benderscut != NULL);
459 
460  benderscut->benderscutfree = benderscutfree;
461 }
462 
463 /** sets initialization callback of the Benders' decomposition cut */
465  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
466  SCIP_DECL_BENDERSCUTINIT((*benderscutinit))/**< initialize the Benders' decomposition cut */
467  )
468 {
469  assert(benderscut != NULL);
470 
471  benderscut->benderscutinit = benderscutinit;
472 }
473 
474 /** sets deinitialization callback of the Benders' decomposition cut */
476  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
477  SCIP_DECL_BENDERSCUTEXIT((*benderscutexit))/**< deinitialize the Benders' decomposition cut */
478  )
479 {
480  assert(benderscut != NULL);
481 
482  benderscut->benderscutexit = benderscutexit;
483 }
484 
485 /** sets solving process initialization callback of the Benders' decomposition cut */
487  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
488  SCIP_DECL_BENDERSCUTINITSOL((*benderscutinitsol))/**< solving process initialization callback of the Benders' decomposition cut */
489  )
490 {
491  assert(benderscut != NULL);
492 
493  benderscut->benderscutinitsol = benderscutinitsol;
494 }
495 
496 /** sets solving process deinitialization callback of Benders' decomposition cut */
498  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
499  SCIP_DECL_BENDERSCUTEXITSOL((*benderscutexitsol))/**< solving process deinitialization callback of the Benders' decomposition cut */
500  )
501 {
502  assert(benderscut != NULL);
503 
504  benderscut->benderscutexitsol = benderscutexitsol;
505 }
506 
507 /** gets name of the Benders' decomposition cut */
509  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
510  )
511 {
512  assert(benderscut != NULL);
513 
514  return benderscut->name;
515 }
516 
517 /** gets description of the Benders' decomposition cut */
519  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
520  )
521 {
522  assert(benderscut != NULL);
523 
524  return benderscut->desc;
525 }
526 
527 /** gets priority of the Benders' decomposition cut */
529  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
530  )
531 {
532  assert(benderscut != NULL);
533 
534  return benderscut->priority;
535 }
536 
537 /** sets priority of the Benders' decomposition cut */
539  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
540  int priority /**< new priority of the Benders' decomposition cut */
541  )
542 {
543  assert(benderscut != NULL);
544 
545  benderscut->priority = priority;
546 }
547 
548 /** gets the number of times, the heuristic was called and tried to find a solution */
550  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
551  )
552 {
553  assert(benderscut != NULL);
554 
555  return benderscut->ncalls;
556 }
557 
558 /** gets the number of Benders' cuts found by this Benders' decomposition cut */
560  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
561  )
562 {
563  assert(benderscut != NULL);
564 
565  return benderscut->nfound;
566 }
567 
568 /** is the Benders' decomposition cut initialized? */
570  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
571  )
572 {
573  assert(benderscut != NULL);
574 
575  return benderscut->initialized;
576 }
577 
578 /** gets time in seconds used by this Benders' decomposition cut for setting up */
580  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
581  )
582 {
583  assert(benderscut != NULL);
584 
585  return SCIPclockGetTime(benderscut->setuptime);
586 }
587 
588 /** gets time in seconds used in this Benders' decomposition cut */
590  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
591  )
592 {
593  assert(benderscut != NULL);
594 
595  return SCIPclockGetTime(benderscut->benderscutclock);
596 }
597 
598 /** returns the number of cuts that have been added for storage */
600  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
601  )
602 {
603  assert(benderscut != NULL);
604 
605  return benderscut->naddedcuts;
606 }
607 
608 /** returns the cuts that have been added by the Benders' cut plugin */
610  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
611  int cutidx, /**< the index for the cut data that is requested */
612  SCIP_VAR*** vars, /**< the variables that have non-zero coefficients in the cut */
613  SCIP_Real** vals, /**< the coefficients of the variables in the cut */
614  SCIP_Real* lhs, /**< the left hand side of the cut */
615  SCIP_Real* rhs, /**< the right hand side of the cut */
616  int* nvars /**< the number of variables with non-zero coefficients in the cut */
617  )
618 {
619  assert(benderscut != NULL);
620  assert(vars != NULL);
621  assert(vals != NULL);
622  assert(lhs != NULL);
623  assert(rhs != NULL);
624  assert(nvars != NULL);
625  assert(cutidx >= 0 && cutidx < benderscut->naddedcuts);
626 
627  (*vars) = benderscut->addedcuts[cutidx]->vars;
628  (*vals) = benderscut->addedcuts[cutidx]->vals;
629  (*lhs) = benderscut->addedcuts[cutidx]->lhs;
630  (*rhs) = benderscut->addedcuts[cutidx]->rhs;
631  (*nvars) = benderscut->addedcuts[cutidx]->nvars;
632 
633  return SCIP_OKAY;
634 }
635 
636 /** adds the data for the generated cuts to the Benders' cut storage */
638  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
639  SCIP_SET* set, /**< global SCIP settings */
640  SCIP_VAR** vars, /**< the variables that have non-zero coefficients in the cut */
641  SCIP_Real* vals, /**< the coefficients of the variables in the cut */
642  SCIP_Real lhs, /**< the left hand side of the cut */
643  SCIP_Real rhs, /**< the right hand side of the cut */
644  int nvars /**< the number of variables with non-zero coefficients in the cut */
645  )
646 {
647  SCIP_BENDERSCUTCUT* cut;
648 
649  assert(benderscut != NULL);
650  assert(set != NULL);
651  assert(vars != NULL);
652  assert(vals != NULL);
653 
654  /* allocating the block memory for the cut storage */
655  SCIP_CALL( SCIPallocBlockMemory(set->scip, &cut) );
656 
657  /* storing the cut data */
658  SCIP_CALL( SCIPduplicateBlockMemoryArray(set->scip, &cut->vars, vars, nvars) );
659  SCIP_CALL( SCIPduplicateBlockMemoryArray(set->scip, &cut->vals, vals, nvars) );
660  cut->lhs = lhs;
661  cut->rhs = rhs;
662  cut->nvars = nvars;
663 
664  /* ensuring the required memory is available for the added cuts array */
665  if( benderscut->addedcutssize < benderscut->naddedcuts + 1 )
666  {
667  int newsize;
668 
669  newsize = SCIPsetCalcMemGrowSize(set, benderscut->naddedcuts + 1);
670  SCIP_ALLOC( BMSreallocBlockMemoryArray(SCIPblkmem(set->scip), &benderscut->addedcuts,
671  benderscut->addedcutssize, newsize) );
672 
673  benderscut->addedcutssize = newsize;
674  }
675  assert(benderscut->addedcutssize >= benderscut->naddedcuts + 1);
676 
677  /* adding the cuts to the Benders' cut storage */
678  benderscut->addedcuts[benderscut->naddedcuts] = cut;
679  benderscut->naddedcuts++;
680 
681  return SCIP_OKAY;
682 }
683 
684 /** returns whether the Benders' cut uses the LP information */
686  SCIP_BENDERSCUT* benderscut /**< Benders' decomposition cut */
687  )
688 {
689  assert(benderscut != NULL);
690 
691  return benderscut->islpcut;
692 }
693 
694 /** sets the enabled flag of the Benders' decomposition cut method */
696  SCIP_BENDERSCUT* benderscut, /**< Benders' decomposition cut */
697  SCIP_Bool enabled /**< flag to indicate whether the Benders' decomposition cut is enabled */
698  )
699 {
700  assert(benderscut != NULL);
701 
702  benderscut->enabled = enabled;
703 }
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:362
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:116
const char * SCIPbenderscutGetName(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:508
#define NULL
Definition: def.h:246
struct SCIP_BenderscutData SCIP_BENDERSCUTDATA
SCIP_BENDERSCUTDATA * SCIPbenderscutGetData(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:419
SCIP_PARAMDATA * SCIPparamGetData(SCIP_PARAM *param)
Definition: paramset.c:661
#define SCIP_MAXSTRLEN
Definition: def.h:267
const char * SCIPbendersGetName(SCIP_BENDERS *benders)
Definition: benders.c:4191
void SCIPbenderscutSetPriority(SCIP_BENDERSCUT *benderscut, int priority)
Definition: benderscut.c:538
internal methods for clocks and timing issues
#define SCIP_DECL_BENDERSCUTFREE(x)
struct SCIP_ParamData SCIP_PARAMDATA
Definition: type_paramset.h:76
#define SCIP_CALL_FINALLY(x, y)
Definition: def.h:400
void SCIPbenderscutSetInitsol(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTINITSOL((*benderscutinitsol)))
Definition: benderscut.c:486
void SCIPbenderscutSetData(SCIP_BENDERSCUT *benderscut, SCIP_BENDERSCUTDATA *benderscutdata)
Definition: benderscut.c:429
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:350
#define FALSE
Definition: def.h:72
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
SCIP_RETCODE SCIPbenderscutGetAddedCutData(SCIP_BENDERSCUT *benderscut, int cutidx, SCIP_VAR ***vars, SCIP_Real **vals, SCIP_Real *lhs, SCIP_Real *rhs, int *nvars)
Definition: benderscut.c:609
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10253
#define TRUE
Definition: def.h:71
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:569
SCIP_RETCODE SCIPbenderscutStoreCut(SCIP_BENDERSCUT *benderscut, SCIP_SET *set, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, int nvars)
Definition: benderscut.c:637
const char * SCIPbenderscutGetDesc(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:518
SCIP_Longint ncalls
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5503
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:114
#define SCIP_DECL_BENDERSCUTEXEC(x)
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:134
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:97
#define SCIP_DECL_BENDERSCUTCOPY(x)
SCIP_Real SCIPbenderscutGetTime(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:589
SCIP_Longint SCIPbenderscutGetNFound(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:559
#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:475
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:111
static SCIP_RETCODE doBenderscutCreate(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:99
SCIP_CLOCK * setuptime
void SCIPbenderscutSetEnabled(SCIP_BENDERSCUT *benderscut, SCIP_Bool enabled)
Definition: benderscut.c:695
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:136
#define SCIPerrorMessage
Definition: pub_message.h:45
SCIP_Longint SCIPbenderscutGetNCalls(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:549
int SCIPbenderscutGetPriority(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:528
void SCIPclockReset(SCIP_CLOCK *clck)
Definition: clock.c:199
SCIP_RETCODE SCIPbenderscutFree(SCIP_BENDERSCUT **benderscut, SCIP_SET *set)
Definition: benderscut.c:198
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:358
void SCIPbenderscutSetExitsol(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTEXITSOL((*benderscutexitsol)))
Definition: benderscut.c:497
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:132
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:69
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:442
void SCIPbenderscutSetFree(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTFREE((*benderscutfree)))
Definition: benderscut.c:453
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:175
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:455
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:314
SCIP_Real SCIPbenderscutGetSetupTime(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:579
void SCIPbenderscutSetInit(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTINIT((*benderscutinit)))
Definition: benderscut.c:464
int SCIPparamGetInt(SCIP_PARAM *param)
Definition: paramset.c:716
SCIP_Bool SCIPbenderscutIsLPCut(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:685
SCIP_Longint nfound
SCIP_RETCODE SCIPbenderscutExit(SCIP_BENDERSCUT *benderscut, SCIP_SET *set)
Definition: benderscut.c:270
public methods for message output
#define SCIP_Real
Definition: def.h:157
#define SCIP_DECL_BENDERSCUTEXITSOL(x)
#define BMSallocMemory(ptr)
Definition: memory.h:108
int SCIPbenderscutGetNAddedCuts(SCIP_BENDERSCUT *benderscut)
Definition: benderscut.c:599
#define SCIP_Longint
Definition: def.h:142
SCIP_BENDERSCUTDATA * benderscutdata
SCIP_BENDERSCUTCUT ** addedcuts
SCIP_RETCODE SCIPbenderscutExitsol(SCIP_BENDERSCUT *benderscut, SCIP_SET *set)
Definition: benderscut.c:338
common defines and data types used in all packages of SCIP
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:426
SCIP_RETCODE SCIPbenderscutCreate(SCIP_BENDERS *benders, SCIP_BENDERSCUT **benderscut, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int priority, SCIP_Bool islpcut, SCIP_DECL_BENDERSCUTCOPY((*benderscutcopy)), SCIP_DECL_BENDERSCUTFREE((*benderscutfree)), SCIP_DECL_BENDERSCUTINIT((*benderscutinit)), SCIP_DECL_BENDERSCUTEXIT((*benderscutexit)), SCIP_DECL_BENDERSCUTINITSOL((*benderscutinitsol)), SCIP_DECL_BENDERSCUTEXITSOL((*benderscutexitsol)), SCIP_DECL_BENDERSCUTEXEC((*benderscutexec)), SCIP_BENDERSCUTDATA *benderscutdata)
Definition: benderscut.c:165
void SCIPbenderscutSetCopy(SCIP_BENDERSCUT *benderscut, SCIP_DECL_BENDERSCUTCOPY((*benderscutcopy)))
Definition: benderscut.c:442
#define SCIP_ALLOC(x)
Definition: def.h:369
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:446
internal methods for Benders&#39; decomposition cuts
SCIP_RETCODE SCIPbenderscutInit(SCIP_BENDERSCUT *benderscut, SCIP_SET *set)
Definition: benderscut.c:224
#define SCIP_DECL_BENDERSCUTINITSOL(x)
SCIP callable library.