Scippy

SCIP

Solving Constraint Integer Programs

sepa.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 email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file sepa.c
17  * @brief methods and datastructures for separators
18  * @author Tobias Achterberg
19  * @author Timo Berthold
20  */
21 
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
23 
24 #include <assert.h>
25 #include <string.h>
26 
27 #include "scip/def.h"
28 #include "scip/set.h"
29 #include "scip/stat.h"
30 #include "scip/clock.h"
31 #include "scip/paramset.h"
32 #include "scip/sepastore.h"
33 #include "scip/scip.h"
34 #include "scip/sepa.h"
35 #include "scip/pub_message.h"
36 #include "scip/pub_misc.h"
37 
38 #include "scip/struct_sepa.h"
39 
40 
41 /** compares two separators w. r. to their priority */
42 SCIP_DECL_SORTPTRCOMP(SCIPsepaComp)
43 { /*lint --e{715}*/
44  return ((SCIP_SEPA*)elem2)->priority - ((SCIP_SEPA*)elem1)->priority;
45 }
46 
47 /** comparison method for sorting separators w.r.t. to their name */
48 SCIP_DECL_SORTPTRCOMP(SCIPsepaCompName)
49 {
50  return strcmp(SCIPsepaGetName((SCIP_SEPA*)elem1), SCIPsepaGetName((SCIP_SEPA*)elem2));
51 }
52 
53 /** method to call, when the priority of a separator was changed */
54 static
55 SCIP_DECL_PARAMCHGD(paramChgdSepaPriority)
56 { /*lint --e{715}*/
57  SCIP_PARAMDATA* paramdata;
58 
59  paramdata = SCIPparamGetData(param);
60  assert(paramdata != NULL);
61 
62  /* use SCIPsetSepaPriority() to mark the sepas unsorted */
63  SCIP_CALL( SCIPsetSepaPriority(scip, (SCIP_SEPA*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
64 
65  return SCIP_OKAY;
66 }
67 
68 /** copies the given separator to a new scip */
70  SCIP_SEPA* sepa, /**< separator */
71  SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
72  )
73 {
74  assert(sepa != NULL);
75  assert(set != NULL);
76  assert(set->scip != NULL);
77 
78  if( sepa->sepacopy != NULL )
79  {
80  SCIPsetDebugMsg(set, "including separator %s in subscip %p\n", SCIPsepaGetName(sepa), (void*)set->scip);
81  SCIP_CALL( sepa->sepacopy(set->scip, sepa) );
82  }
83  return SCIP_OKAY;
84 }
85 
86 /** creates a separator */
88  SCIP_SEPA** sepa, /**< pointer to separator data structure */
89  SCIP_SET* set, /**< global SCIP settings */
90  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
91  BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
92  const char* name, /**< name of separator */
93  const char* desc, /**< description of separator */
94  int priority, /**< priority of separator (>= 0: before, < 0: after constraint handlers) */
95  int freq, /**< frequency for calling separator */
96  SCIP_Real maxbounddist, /**< maximal relative distance from current node's dual bound to primal bound compared
97  * to best node's dual bound for applying separation */
98  SCIP_Bool usessubscip, /**< does the separator use a secondary SCIP instance? */
99  SCIP_Bool delay, /**< should separator be delayed, if other separators found cuts? */
100  SCIP_DECL_SEPACOPY ((*sepacopy)), /**< copy method of separator or NULL if you don't want to copy your plugin into sub-SCIPs */
101  SCIP_DECL_SEPAFREE ((*sepafree)), /**< destructor of separator */
102  SCIP_DECL_SEPAINIT ((*sepainit)), /**< initialize separator */
103  SCIP_DECL_SEPAEXIT ((*sepaexit)), /**< deinitialize separator */
104  SCIP_DECL_SEPAINITSOL ((*sepainitsol)), /**< solving process initialization method of separator */
105  SCIP_DECL_SEPAEXITSOL ((*sepaexitsol)), /**< solving process deinitialization method of separator */
106  SCIP_DECL_SEPAEXECLP ((*sepaexeclp)), /**< LP solution separation method of separator */
107  SCIP_DECL_SEPAEXECSOL ((*sepaexecsol)), /**< arbitrary primal solution separation method of separator */
108  SCIP_SEPADATA* sepadata /**< separator data */
109  )
110 {
111  char paramname[SCIP_MAXSTRLEN];
112  char paramdesc[SCIP_MAXSTRLEN];
113 
114  assert(sepa != NULL);
115  assert(name != NULL);
116  assert(desc != NULL);
117  assert(freq >= -1);
118  assert(0.0 <= maxbounddist && maxbounddist <= 1.0);
119  assert(sepaexeclp != NULL || sepaexecsol != NULL);
120 
121  SCIP_ALLOC( BMSallocMemory(sepa) );
122  SCIP_ALLOC( BMSduplicateMemoryArray(&(*sepa)->name, name, strlen(name)+1) );
123  SCIP_ALLOC( BMSduplicateMemoryArray(&(*sepa)->desc, desc, strlen(desc)+1) );
124  (*sepa)->priority = priority;
125  (*sepa)->freq = freq;
126  (*sepa)->maxbounddist = maxbounddist;
127  (*sepa)->usessubscip = usessubscip;
128  (*sepa)->sepacopy = sepacopy;
129  (*sepa)->sepafree = sepafree;
130  (*sepa)->sepainit = sepainit;
131  (*sepa)->sepaexit = sepaexit;
132  (*sepa)->sepainitsol = sepainitsol;
133  (*sepa)->sepaexitsol = sepaexitsol;
134  (*sepa)->sepaexeclp = sepaexeclp;
135  (*sepa)->sepaexecsol = sepaexecsol;
136  (*sepa)->sepadata = sepadata;
137  SCIP_CALL( SCIPclockCreate(&(*sepa)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
138  SCIP_CALL( SCIPclockCreate(&(*sepa)->sepaclock, SCIP_CLOCKTYPE_DEFAULT) );
139  (*sepa)->lastsepanode = -1;
140  (*sepa)->ncalls = 0;
141  (*sepa)->ncutoffs = 0;
142  (*sepa)->ncutsfound = 0;
143  (*sepa)->ncutsapplied = 0;
144  (*sepa)->nconssfound = 0;
145  (*sepa)->ndomredsfound = 0;
146  (*sepa)->ncallsatnode = 0;
147  (*sepa)->ncutsfoundatnode = 0;
148  (*sepa)->lpwasdelayed = FALSE;
149  (*sepa)->solwasdelayed = FALSE;
150  (*sepa)->initialized = FALSE;
151 
152  /* add parameters */
153  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "separating/%s/priority", name);
154  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of separator <%s>", name);
155  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
156  &(*sepa)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4,
157  paramChgdSepaPriority, (SCIP_PARAMDATA*)(*sepa)) ); /*lint !e740*/
158 
159  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "separating/%s/freq", name);
160  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency for calling separator <%s> (-1: never, 0: only in root node)", name);
161  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
162  &(*sepa)->freq, FALSE, freq, -1, SCIP_MAXTREEDEPTH, NULL, NULL) );
163 
164  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "separating/%s/maxbounddist", name);
165  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for applying separator <%s> (0.0: only on current best node, 1.0: on all nodes)",
166  name);
167  SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, paramdesc,
168  &(*sepa)->maxbounddist, TRUE, maxbounddist, 0.0, 1.0, NULL, NULL) );
169 
170  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "separating/%s/delay", name);
171  SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname,
172  "should separator be delayed, if other separators found cuts?",
173  &(*sepa)->delay, TRUE, delay, NULL, NULL) ); /*lint !e740*/
174 
175  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "separating/%s/expbackoff", name);
176  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "base for exponential increase of frequency at which separator <%s> is called (1: call at each multiple of frequency)", name);
177  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
178  &(*sepa)->expbackoff, TRUE, 4, 1, 100, NULL, NULL) ); /*lint !e740*/
179 
180  return SCIP_OKAY;
181 }
182 
183 /** calls destructor and frees memory of separator */
185  SCIP_SEPA** sepa, /**< pointer to separator data structure */
186  SCIP_SET* set /**< global SCIP settings */
187  )
188 {
189  assert(sepa != NULL);
190  assert(*sepa != NULL);
191  assert(!(*sepa)->initialized);
192  assert(set != NULL);
193 
194  /* call destructor of separator */
195  if( (*sepa)->sepafree != NULL )
196  {
197  SCIP_CALL( (*sepa)->sepafree(set->scip, *sepa) );
198  }
199 
200  SCIPclockFree(&(*sepa)->sepaclock);
201  SCIPclockFree(&(*sepa)->setuptime);
202  BMSfreeMemoryArray(&(*sepa)->name);
203  BMSfreeMemoryArray(&(*sepa)->desc);
204  BMSfreeMemory(sepa);
205 
206  return SCIP_OKAY;
207 }
208 
209 /** initializes separator */
211  SCIP_SEPA* sepa, /**< separator */
212  SCIP_SET* set /**< global SCIP settings */
213  )
214 {
215  assert(sepa != NULL);
216  assert(set != NULL);
217 
218  if( sepa->initialized )
219  {
220  SCIPerrorMessage("separator <%s> already initialized\n", sepa->name);
221  return SCIP_INVALIDCALL;
222  }
223 
224  if( set->misc_resetstat )
225  {
226  SCIPclockReset(sepa->setuptime);
227  SCIPclockReset(sepa->sepaclock);
228 
229  sepa->lastsepanode = -1;
230  sepa->ncalls = 0;
231  sepa->ncutoffs = 0;
232  sepa->ncutsfound = 0;
233  sepa->ncutsapplied = 0;
234  sepa->nconssfound = 0;
235  sepa->ndomredsfound = 0;
236  sepa->ncallsatnode = 0;
237  sepa->ncutsfoundatnode = 0;
238  sepa->lpwasdelayed = FALSE;
239  sepa->solwasdelayed = FALSE;
240  }
241 
242  if( sepa->sepainit != NULL )
243  {
244  /* start timing */
245  SCIPclockStart(sepa->setuptime, set);
246 
247  SCIP_CALL( sepa->sepainit(set->scip, sepa) );
248 
249  /* stop timing */
250  SCIPclockStop(sepa->setuptime, set);
251  }
252  sepa->initialized = TRUE;
253 
254  return SCIP_OKAY;
255 }
256 
257 /** calls exit method of separator */
259  SCIP_SEPA* sepa, /**< separator */
260  SCIP_SET* set /**< global SCIP settings */
261  )
262 {
263  assert(sepa != NULL);
264  assert(set != NULL);
265 
266  if( !sepa->initialized )
267  {
268  SCIPerrorMessage("separator <%s> not initialized\n", sepa->name);
269  return SCIP_INVALIDCALL;
270  }
271 
272  if( sepa->sepaexit != NULL )
273  {
274  /* start timing */
275  SCIPclockStart(sepa->setuptime, set);
276 
277  SCIP_CALL( sepa->sepaexit(set->scip, sepa) );
278 
279  /* stop timing */
280  SCIPclockStop(sepa->setuptime, set);
281  }
282  sepa->initialized = FALSE;
283 
284  return SCIP_OKAY;
285 }
286 
287 /** informs separator that the branch and bound process is being started */
289  SCIP_SEPA* sepa, /**< separator */
290  SCIP_SET* set /**< global SCIP settings */
291  )
292 {
293  assert(sepa != NULL);
294  assert(set != NULL);
295 
296  sepa->lpwasdelayed = FALSE;
297  sepa->solwasdelayed = FALSE;
298 
299  /* call solving process initialization method of separator */
300  if( sepa->sepainitsol != NULL )
301  {
302  /* start timing */
303  SCIPclockStart(sepa->setuptime, set);
304 
305  SCIP_CALL( sepa->sepainitsol(set->scip, sepa) );
306 
307  /* stop timing */
308  SCIPclockStop(sepa->setuptime, set);
309  }
310 
311  return SCIP_OKAY;
312 }
313 
314 /** informs separator that the branch and bound process data is being freed */
316  SCIP_SEPA* sepa, /**< separator */
317  SCIP_SET* set /**< global SCIP settings */
318  )
319 {
320  assert(sepa != NULL);
321  assert(set != NULL);
322 
323  /* call solving process deinitialization method of separator */
324  if( sepa->sepaexitsol != NULL )
325  {
326  /* start timing */
327  SCIPclockStart(sepa->setuptime, set);
328 
329  SCIP_CALL( sepa->sepaexitsol(set->scip, sepa) );
330 
331  /* stop timing */
332  SCIPclockStop(sepa->setuptime, set);
333  }
334 
335  return SCIP_OKAY;
336 }
337 
338 /** calls LP separation method of separator */
340  SCIP_SEPA* sepa, /**< separator */
341  SCIP_SET* set, /**< global SCIP settings */
342  SCIP_STAT* stat, /**< dynamic problem statistics */
343  SCIP_SEPASTORE* sepastore, /**< separation storage */
344  int depth, /**< depth of current node */
345  SCIP_Real bounddist, /**< current relative distance of local dual bound to global dual bound */
346  SCIP_Bool allowlocal, /**< should the separator be asked to separate local cuts */
347  SCIP_Bool execdelayed, /**< execute separator even if it is marked to be delayed */
348  SCIP_RESULT* result /**< pointer to store the result of the callback method */
349  )
350 {
351  assert(sepa != NULL);
352  assert(sepa->freq >= -1);
353  assert(0.0 <= sepa->maxbounddist && sepa->maxbounddist <= 1.0);
354  assert(0.0 <= bounddist && bounddist <= 1.0);
355  assert(set != NULL);
356  assert(set->scip != NULL);
357  assert(stat != NULL);
358  assert(depth >= 0);
359  assert(result != NULL);
360 
361  if( sepa->sepaexeclp != NULL && SCIPsetIsLE(set, bounddist, sepa->maxbounddist) &&
362  ( (depth == 0 && sepa->freq != -1) ||
363  (sepa->freq > 0 && depth % sepa->freq == 0 &&
364  (sepa->expbackoff == 1 || SCIPsetIsIntegral(set, LOG2(depth * (1.0 / sepa->freq)) / LOG2((SCIP_Real)sepa->expbackoff)))) ||
365  sepa->lpwasdelayed )
366  )
367  {
368  if( (!sepa->delay && !sepa->lpwasdelayed) || execdelayed )
369  {
370  SCIP_Longint oldndomchgs;
371  SCIP_Longint oldnprobdomchgs;
372  int oldncuts;
373  int oldnactiveconss;
374  int ncutsfound;
375 
376  SCIPsetDebugMsg(set, "executing separator <%s> on LP solution\n", sepa->name);
377 
378  oldndomchgs = stat->nboundchgs + stat->nholechgs;
379  oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
380  oldncuts = SCIPsepastoreGetNCuts(sepastore);
381  oldnactiveconss = stat->nactiveconss;
382 
383  /* reset the statistics for current node */
384  if( sepa->lastsepanode != stat->ntotalnodes )
385  {
386  sepa->ncallsatnode = 0;
387  sepa->ncutsfoundatnode = 0;
388  }
389 
390  /* start timing */
391  SCIPclockStart(sepa->sepaclock, set);
392 
393  /* call external separation method */
394  SCIP_CALL( sepa->sepaexeclp(set->scip, sepa, result, allowlocal) );
395 
396  /* stop timing */
397  SCIPclockStop(sepa->sepaclock, set);
398 
399  /* update statistics */
400  if( *result != SCIP_DIDNOTRUN && *result != SCIP_DELAYED )
401  {
402  sepa->ncalls++;
403  sepa->ncallsatnode++;
404  sepa->lastsepanode = stat->ntotalnodes;
405  }
406  if( *result == SCIP_CUTOFF )
407  sepa->ncutoffs++;
408  ncutsfound = SCIPsepastoreGetNCuts(sepastore) - oldncuts;
409  sepa->ncutsfound += ncutsfound;
410  sepa->ncutsfoundatnode += ncutsfound;
411  sepa->nconssfound += MAX(stat->nactiveconss - oldnactiveconss, 0); /*lint !e776*/
412 
413  /* update domain reductions; therefore remove the domain
414  * reduction counts which were generated in probing mode */
415  sepa->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
416  sepa->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
417 
418  /* evaluate result */
419  if( *result != SCIP_CUTOFF
420  && *result != SCIP_CONSADDED
421  && *result != SCIP_REDUCEDDOM
422  && *result != SCIP_SEPARATED
423  && *result != SCIP_NEWROUND
424  && *result != SCIP_DIDNOTFIND
425  && *result != SCIP_DIDNOTRUN
426  && *result != SCIP_DELAYED )
427  {
428  SCIPerrorMessage("execution method of separator <%s> returned invalid result <%d>\n",
429  sepa->name, *result);
430  return SCIP_INVALIDRESULT;
431  }
432  }
433  else
434  {
435  SCIPsetDebugMsg(set, "separator <%s> was delayed\n", sepa->name);
436  *result = SCIP_DELAYED;
437  }
438 
439  /* remember whether separator was delayed */
440  sepa->lpwasdelayed = (*result == SCIP_DELAYED);
441  }
442  else
443  *result = SCIP_DIDNOTRUN;
444 
445  return SCIP_OKAY;
446 }
447 
448 /** calls primal solution separation method of separator */
450  SCIP_SEPA* sepa, /**< separator */
451  SCIP_SET* set, /**< global SCIP settings */
452  SCIP_STAT* stat, /**< dynamic problem statistics */
453  SCIP_SEPASTORE* sepastore, /**< separation storage */
454  SCIP_SOL* sol, /**< primal solution that should be separated */
455  int depth, /**< depth of current node */
456  SCIP_Bool allowlocal, /**< should the separator allow local cuts */
457  SCIP_Bool execdelayed, /**< execute separator even if it is marked to be delayed */
458  SCIP_RESULT* result /**< pointer to store the result of the callback method */
459  )
460 {
461  assert(sepa != NULL);
462  assert(sepa->freq >= -1);
463  assert(set != NULL);
464  assert(set->scip != NULL);
465  assert(stat != NULL);
466  assert(depth >= 0);
467  assert(result != NULL);
468 
469  if( sepa->sepaexecsol != NULL &&
470  ( (depth == 0 && sepa->freq != -1) ||
471  (sepa->freq > 0 && depth % sepa->freq == 0 &&
472  (sepa->expbackoff == 1 || SCIPsetIsIntegral(set, LOG2(depth * (1.0 / sepa->freq) / LOG2((SCIP_Real)sepa->expbackoff))))) ||
473  sepa->solwasdelayed )
474  )
475  {
476  if( (!sepa->delay && !sepa->solwasdelayed) || execdelayed )
477  {
478  SCIP_Longint oldndomchgs;
479  SCIP_Longint oldnprobdomchgs;
480  int oldncuts;
481  int oldnactiveconss;
482  int ncutsfound;
483 
484  SCIPsetDebugMsg(set, "executing separator <%s> on solution %p\n", sepa->name, (void*)sol);
485 
486  oldndomchgs = stat->nboundchgs + stat->nholechgs;
487  oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
488  oldncuts = SCIPsepastoreGetNCuts(sepastore);
489  oldnactiveconss = stat->nactiveconss;
490 
491  /* reset the statistics for current node */
492  if( sepa->lastsepanode != stat->ntotalnodes )
493  {
494  sepa->ncallsatnode = 0;
495  sepa->ncutsfoundatnode = 0;
496  }
497 
498  /* start timing */
499  SCIPclockStart(sepa->sepaclock, set);
500 
501  /* call external separation method */
502  SCIP_CALL( sepa->sepaexecsol(set->scip, sepa, sol, result, allowlocal) );
503 
504  /* stop timing */
505  SCIPclockStop(sepa->sepaclock, set);
506 
507  /* update statistics */
508  if( *result != SCIP_DIDNOTRUN && *result != SCIP_DELAYED )
509  {
510  sepa->ncalls++;
511  sepa->ncallsatnode++;
512  sepa->lastsepanode = stat->ntotalnodes;
513  }
514  if( *result == SCIP_CUTOFF )
515  sepa->ncutoffs++;
516  ncutsfound = SCIPsepastoreGetNCuts(sepastore) - oldncuts;
517  sepa->ncutsfound += ncutsfound;
518  sepa->ncutsfoundatnode += ncutsfound;
519  sepa->nconssfound += MAX(stat->nactiveconss - oldnactiveconss, 0); /*lint !e776*/
520 
521  /* update domain reductions; therefore remove the domain
522  * reduction counts which were generated in probing mode */
523  sepa->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
524  sepa->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
525 
526  /* evaluate result */
527  if( *result != SCIP_CUTOFF
528  && *result != SCIP_CONSADDED
529  && *result != SCIP_REDUCEDDOM
530  && *result != SCIP_SEPARATED
531  && *result != SCIP_NEWROUND
532  && *result != SCIP_DIDNOTFIND
533  && *result != SCIP_DIDNOTRUN
534  && *result != SCIP_DELAYED )
535  {
536  SCIPerrorMessage("execution method of separator <%s> returned invalid result <%d>\n",
537  sepa->name, *result);
538  return SCIP_INVALIDRESULT;
539  }
540  }
541  else
542  {
543  SCIPsetDebugMsg(set, "separator <%s> was delayed\n", sepa->name);
544  *result = SCIP_DELAYED;
545  }
546 
547  /* remember whether separator was delayed */
548  sepa->solwasdelayed = (*result == SCIP_DELAYED);
549  }
550  else
551  *result = SCIP_DIDNOTRUN;
552 
553  return SCIP_OKAY;
554 }
555 
556 /** gets user data of separator */
558  SCIP_SEPA* sepa /**< separator */
559  )
560 {
561  assert(sepa != NULL);
562 
563  return sepa->sepadata;
564 }
565 
566 /** sets user data of separator; user has to free old data in advance! */
568  SCIP_SEPA* sepa, /**< separator */
569  SCIP_SEPADATA* sepadata /**< new separator user data */
570  )
571 {
572  assert(sepa != NULL);
573 
574  sepa->sepadata = sepadata;
575 }
576 
577 /* new callback/method setter methods */
578 
579 /** sets copy method of separator */
581  SCIP_SEPA* sepa, /**< separator */
582  SCIP_DECL_SEPACOPY ((*sepacopy)) /**< copy method of separator or NULL if you don't want to copy your plugin into sub-SCIPs */
583  )
584 {
585  assert(sepa != NULL);
586 
587  sepa->sepacopy = sepacopy;
588 }
589 
590 /** sets destructor method of separator */
592  SCIP_SEPA* sepa, /**< separator */
593  SCIP_DECL_SEPAFREE ((*sepafree)) /**< destructor of separator */
594  )
595 {
596  assert(sepa != NULL);
597 
598  sepa->sepafree = sepafree;
599 }
600 
601 /** sets initialization method of separator */
603  SCIP_SEPA* sepa, /**< separator */
604  SCIP_DECL_SEPAINIT ((*sepainit)) /**< initialize separator */
605  )
606 {
607  assert(sepa != NULL);
608 
609  sepa->sepainit = sepainit;
610 }
611 
612 /** sets deinitialization method of separator */
614  SCIP_SEPA* sepa, /**< separator */
615  SCIP_DECL_SEPAEXIT ((*sepaexit)) /**< deinitialize separator */
616  )
617 {
618  assert(sepa != NULL);
619 
620  sepa->sepaexit = sepaexit;
621 }
622 
623 /** sets solving process initialization method of separator */
625  SCIP_SEPA* sepa, /**< separator */
626  SCIP_DECL_SEPAINITSOL ((*sepainitsol)) /**< solving process initialization method of separator */
627  )
628 {
629  assert(sepa != NULL);
630 
631  sepa->sepainitsol = sepainitsol;
632 }
633 
634 /** sets solving process deinitialization method of separator */
636  SCIP_SEPA* sepa, /**< separator */
637  SCIP_DECL_SEPAEXITSOL ((*sepaexitsol)) /**< solving process deinitialization method of separator */
638  )
639 {
640  assert(sepa != NULL);
641 
642  sepa->sepaexitsol = sepaexitsol;
643 }
644 
645 /** gets name of separator */
646 const char* SCIPsepaGetName(
647  SCIP_SEPA* sepa /**< separator */
648  )
649 {
650  assert(sepa != NULL);
651 
652  return sepa->name;
653 }
654 
655 /** gets description of separator */
656 const char* SCIPsepaGetDesc(
657  SCIP_SEPA* sepa /**< separator */
658  )
659 {
660  assert(sepa != NULL);
661 
662  return sepa->desc;
663 }
664 
665 /** gets priority of separator */
667  SCIP_SEPA* sepa /**< separator */
668  )
669 {
670  assert(sepa != NULL);
671 
672  return sepa->priority;
673 }
674 
675 /** sets priority of separator */
677  SCIP_SEPA* sepa, /**< separator */
678  SCIP_SET* set, /**< global SCIP settings */
679  int priority /**< new priority of the separator */
680  )
681 {
682  assert(sepa != NULL);
683  assert(set != NULL);
684 
685  sepa->priority = priority;
686  set->sepassorted = FALSE;
687 }
688 
689 /** gets frequency of separator */
691  SCIP_SEPA* sepa /**< separator */
692  )
693 {
694  assert(sepa != NULL);
695 
696  return sepa->freq;
697 }
698 
699 /** sets frequency of separator */
701  SCIP_SEPA* sepa, /**< separator */
702  int freq /**< new frequency of separator */
703  )
704 {
705  assert(sepa != NULL);
706 
707  sepa->freq = freq;
708 }
709 
710 /** get maximal bound distance at which the separator is called */
712  SCIP_SEPA* sepa /**< separator */
713  )
714 {
715  assert(sepa != NULL);
716 
717  return sepa->maxbounddist;
718 }
719 
720 /** does the separator use a secondary SCIP instance? */
722  SCIP_SEPA* sepa /**< separator */
723  )
724 {
725  assert(sepa != NULL);
726 
727  return sepa->usessubscip;
728 }
729 
730 /** enables or disables all clocks of \p sepa, depending on the value of the flag */
732  SCIP_SEPA* sepa, /**< the separator for which all clocks should be enabled or disabled */
733  SCIP_Bool enable /**< should the clocks of the separator be enabled? */
734  )
735 {
736  assert(sepa != NULL);
737 
738  SCIPclockEnableOrDisable(sepa->setuptime, enable);
739  SCIPclockEnableOrDisable(sepa->sepaclock, enable);
740 }
741 
742 /** gets time in seconds used in this separator for setting up for next stages */
744  SCIP_SEPA* sepa /**< separator */
745  )
746 {
747  assert(sepa != NULL);
748 
749  return SCIPclockGetTime(sepa->setuptime);
750 }
751 
752 /** gets time in seconds used in this separator */
754  SCIP_SEPA* sepa /**< separator */
755  )
756 {
757  assert(sepa != NULL);
758 
759  return SCIPclockGetTime(sepa->sepaclock);
760 }
761 
762 /** gets the total number of times, the separator was called */
764  SCIP_SEPA* sepa /**< separator */
765  )
766 {
767  assert(sepa != NULL);
768 
769  return sepa->ncalls;
770 }
771 
772 /** gets the number of times, the separator was called at the current node */
774  SCIP_SEPA* sepa /**< separator */
775  )
776 {
777  assert(sepa != NULL);
778 
779  return sepa->ncallsatnode;
780 }
781 
782 /** gets total number of times, the separator detected a cutoff */
784  SCIP_SEPA* sepa /**< separator */
785  )
786 {
787  assert(sepa != NULL);
788 
789  return sepa->ncutoffs;
790 }
791 
792 /** gets the total number of cutting planes found by this separator */
794  SCIP_SEPA* sepa /**< separator */
795  )
796 {
797  assert(sepa != NULL);
798 
799  return sepa->ncutsfound;
800 }
801 
802 /** gets the total number of cutting planes applied to lp */
804  SCIP_SEPA* sepa /**< separator */
805  )
806 {
807  assert(sepa != NULL);
808 
809  return sepa->ncutsapplied;
810 }
811 
812 /** increase count of applied cuts */
814  SCIP_SEPA* sepa /**< separator */
815  )
816 {
817  assert( sepa != NULL );
818 
819  ++sepa->ncutsapplied;
820 }
821 
822 /** increase count of found cuts */
824  SCIP_SEPA* sepa /**< separator */
825  )
826 {
827  assert( sepa != NULL );
828 
829  ++sepa->ncutsfound;
830 }
831 
832 /** increase count of found cuts at current node */
834  SCIP_SEPA* sepa /**< separator */
835  )
836 {
837  assert( sepa != NULL );
838 
839  ++sepa->ncutsfoundatnode;
840 }
841 
842 /** gets the number of cutting planes found by this separator at the current node */
844  SCIP_SEPA* sepa /**< separator */
845  )
846 {
847  assert(sepa != NULL);
848 
849  return sepa->ncutsfoundatnode;
850 }
851 
852 /** gets total number of additional constraints added by this separator */
854  SCIP_SEPA* sepa /**< separator */
855  )
856 {
857  assert(sepa != NULL);
858 
859  return sepa->nconssfound;
860 }
861 
862 /** gets total number of domain reductions found by this separator */
864  SCIP_SEPA* sepa /**< separator */
865  )
866 {
867  assert(sepa != NULL);
868 
869  return sepa->ndomredsfound;
870 }
871 
872 /** should separator be delayed, if other separators found cuts? */
874  SCIP_SEPA* sepa /**< separator */
875  )
876 {
877  assert(sepa != NULL);
878 
879  return sepa->delay;
880 }
881 
882 /** was separation of the LP solution delayed at the last call? */
884  SCIP_SEPA* sepa /**< separator */
885  )
886 {
887  assert(sepa != NULL);
888 
889  return sepa->lpwasdelayed;
890 }
891 
892 /** was separation of the primal solution delayed at the last call? */
894  SCIP_SEPA* sepa /**< separator */
895  )
896 {
897  assert(sepa != NULL);
898 
899  return sepa->solwasdelayed;
900 }
901 
902 /** is separator initialized? */
904  SCIP_SEPA* sepa /**< separator */
905  )
906 {
907  assert(sepa != NULL);
908 
909  return sepa->initialized;
910 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
SCIP_Bool solwasdelayed
Definition: struct_sepa.h:69
void SCIPsepaSetFree(SCIP_SEPA *sepa, SCIP_DECL_SEPAFREE((*sepafree)))
Definition: sepa.c:591
internal methods for separators
SCIP_Bool usessubscip
Definition: struct_sepa.h:66
SCIP_SEPADATA * sepadata
Definition: struct_sepa.h:58
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5834
void SCIPsepaEnableOrDisableClocks(SCIP_SEPA *sepa, SCIP_Bool enable)
Definition: sepa.c:731
SCIP_CLOCK * setuptime
Definition: struct_sepa.h:59
SCIP_RETCODE SCIPsepaCopyInclude(SCIP_SEPA *sepa, SCIP_SET *set)
Definition: sepa.c:69
SCIP_PARAMDATA * SCIPparamGetData(SCIP_PARAM *param)
Definition: paramset.c:661
SCIP_CLOCK * sepaclock
Definition: struct_sepa.h:60
void SCIPsepaIncNAppliedCuts(SCIP_SEPA *sepa)
Definition: sepa.c:813
#define SCIP_MAXSTRLEN
Definition: def.h:259
internal methods for clocks and timing issues
SCIP_Longint ntotalnodes
Definition: struct_stat.h:76
char * name
Definition: struct_sepa.h:48
struct SCIP_ParamData SCIP_PARAMDATA
Definition: type_paramset.h:76
SCIP_Bool SCIPsepaUsesSubscip(SCIP_SEPA *sepa)
Definition: sepa.c:721
SCIP_Longint SCIPsepaGetNDomredsFound(SCIP_SEPA *sepa)
Definition: sepa.c:863
SCIP_RETCODE SCIPsepaExecSol(SCIP_SEPA *sepa, SCIP_SET *set, SCIP_STAT *stat, SCIP_SEPASTORE *sepastore, SCIP_SOL *sol, int depth, SCIP_Bool allowlocal, SCIP_Bool execdelayed, SCIP_RESULT *result)
Definition: sepa.c:449
SCIP_Real SCIPsepaGetSetupTime(SCIP_SEPA *sepa)
Definition: sepa.c:743
SCIP_Longint nholechgs
Definition: struct_stat.h:105
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:350
#define FALSE
Definition: def.h:64
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:280
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10011
SCIP_Real maxbounddist
Definition: struct_sepa.h:46
#define TRUE
Definition: def.h:63
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
Definition: sepa.c:646
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Bool initialized
Definition: struct_sepa.h:70
SCIP_Real SCIPsepaGetTime(SCIP_SEPA *sepa)
Definition: sepa.c:753
SCIP_Longint ncutsfound
Definition: struct_sepa.h:42
void SCIPsepaSetExit(SCIP_SEPA *sepa, SCIP_DECL_SEPAEXIT((*sepaexit)))
Definition: sepa.c:613
SCIP_Longint SCIPsepaGetNCutsFound(SCIP_SEPA *sepa)
Definition: sepa.c:793
void SCIPsepaIncNCutsFoundAtNode(SCIP_SEPA *sepa)
Definition: sepa.c:833
SCIP_RETCODE SCIPsetSepaPriority(SCIP *scip, SCIP_SEPA *sepa, int priority)
Definition: scip.c:7560
int ncallsatnode
Definition: struct_sepa.h:63
SCIP_RETCODE SCIPsepaFree(SCIP_SEPA **sepa, SCIP_SET *set)
Definition: sepa.c:184
#define SCIP_DECL_SEPAEXECLP(x)
Definition: type_sepa.h:116
internal methods for handling parameter settings
void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
Definition: clock.c:250
#define BMSfreeMemory(ptr)
Definition: memory.h:127
SCIP_DECL_SORTPTRCOMP(SCIPsepaComp)
Definition: sepa.c:42
SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
Definition: sepa.c:557
SCIP_RETCODE SCIPsepaInit(SCIP_SEPA *sepa, SCIP_SET *set)
Definition: sepa.c:210
#define SCIP_DECL_SEPACOPY(x)
Definition: type_sepa.h:47
int SCIPsepaGetFreq(SCIP_SEPA *sepa)
Definition: sepa.c:690
SCIP_RETCODE SCIPsepaInitsol(SCIP_SEPA *sepa, SCIP_SET *set)
Definition: sepa.c:288
SCIP_RETCODE SCIPsepaExecLP(SCIP_SEPA *sepa, SCIP_SET *set, SCIP_STAT *stat, SCIP_SEPASTORE *sepastore, int depth, SCIP_Real bounddist, SCIP_Bool allowlocal, SCIP_Bool execdelayed, SCIP_RESULT *result)
Definition: sepa.c:339
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:129
SCIP_Longint nconssfound
Definition: struct_sepa.h:44
#define SCIPerrorMessage
Definition: pub_message.h:45
SCIP_Longint lastsepanode
Definition: struct_sepa.h:39
SCIP_Bool lpwasdelayed
Definition: struct_sepa.h:68
SCIP_Longint ncalls
Definition: struct_sepa.h:40
void SCIPclockReset(SCIP_CLOCK *clck)
Definition: clock.c:199
static SCIP_DECL_PARAMCHGD(paramChgdSepaPriority)
Definition: sepa.c:55
SCIP_Longint SCIPsepaGetNCutoffs(SCIP_SEPA *sepa)
Definition: sepa.c:783
int SCIPsepaGetNCallsAtNode(SCIP_SEPA *sepa)
Definition: sepa.c:773
int SCIPsepastoreGetNCuts(SCIP_SEPASTORE *sepastore)
Definition: sepastore.c:1237
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:428
void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
Definition: sepa.c:567
int ncutsfoundatnode
Definition: struct_sepa.h:64
void SCIPsepaSetFreq(SCIP_SEPA *sepa, int freq)
Definition: sepa.c:700
void SCIPsepaSetExitsol(SCIP_SEPA *sepa, SCIP_DECL_SEPAEXITSOL((*sepaexitsol)))
Definition: sepa.c:635
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:350
SCIP_Real SCIPsepaGetMaxbounddist(SCIP_SEPA *sepa)
Definition: sepa.c:711
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:2813
internal methods for storing separated cuts
const char * SCIPsepaGetDesc(SCIP_SEPA *sepa)
Definition: sepa.c:656
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:125
SCIP_Longint nprobboundchgs
Definition: struct_stat.h:106
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:160
void SCIPsepaSetCopy(SCIP_SEPA *sepa, SCIP_DECL_SEPACOPY((*sepacopy)))
Definition: sepa.c:580
SCIP_Longint SCIPsepaGetNCalls(SCIP_SEPA *sepa)
Definition: sepa.c:763
SCIP_Bool SCIPsepaWasLPDelayed(SCIP_SEPA *sepa)
Definition: sepa.c:883
SCIP_Bool SCIPsetIsIntegral(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5921
public data structures and miscellaneous methods
void SCIPsepaSetInitsol(SCIP_SEPA *sepa, SCIP_DECL_SEPAINITSOL((*sepainitsol)))
Definition: sepa.c:624
#define SCIP_Bool
Definition: def.h:61
#define SCIP_DECL_SEPAINIT(x)
Definition: type_sepa.h:63
SCIP_Longint SCIPsepaGetNConssFound(SCIP_SEPA *sepa)
Definition: sepa.c:853
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:175
#define MAX(x, y)
Definition: tclique_def.h:75
#define SCIPsetDebugMsg
Definition: set.h:1913
SCIP_Longint ncutoffs
Definition: struct_sepa.h:41
#define SCIP_DECL_SEPAEXITSOL(x)
Definition: type_sepa.h:93
#define SCIP_DECL_SEPAEXECSOL(x)
Definition: type_sepa.h:140
SCIP_Bool delay
Definition: struct_sepa.h:67
#define SCIP_MAXTREEDEPTH
Definition: def.h:286
int SCIPparamGetInt(SCIP_PARAM *param)
Definition: paramset.c:716
void SCIPsepaSetPriority(SCIP_SEPA *sepa, SCIP_SET *set, int priority)
Definition: sepa.c:676
SCIP_Bool SCIPsepaWasSolDelayed(SCIP_SEPA *sepa)
Definition: sepa.c:893
int nactiveconss
Definition: struct_stat.h:220
SCIP_RETCODE SCIPsepaExit(SCIP_SEPA *sepa, SCIP_SET *set)
Definition: sepa.c:258
#define SCIP_DECL_SEPAEXIT(x)
Definition: type_sepa.h:71
#define SCIP_DECL_SEPAINITSOL(x)
Definition: type_sepa.h:82
public methods for message output
SCIP_Longint ncutsapplied
Definition: struct_sepa.h:43
SCIP_Longint ndomredsfound
Definition: struct_sepa.h:45
SCIP_Longint nboundchgs
Definition: struct_stat.h:104
SCIP_Bool SCIPsepaIsDelayed(SCIP_SEPA *sepa)
Definition: sepa.c:873
#define SCIP_Real
Definition: def.h:149
internal methods for problem statistics
datastructures for separators
SCIP_Longint SCIPsepaGetNCutsApplied(SCIP_SEPA *sepa)
Definition: sepa.c:803
#define BMSallocMemory(ptr)
Definition: memory.h:101
void SCIPsepaIncNCutsFound(SCIP_SEPA *sepa)
Definition: sepa.c:823
#define SCIP_Longint
Definition: def.h:134
int priority
Definition: struct_sepa.h:61
void SCIPsepaSetInit(SCIP_SEPA *sepa, SCIP_DECL_SEPAINIT((*sepainit)))
Definition: sepa.c:602
SCIP_Bool SCIPsepaIsInitialized(SCIP_SEPA *sepa)
Definition: sepa.c:903
common defines and data types used in all packages of SCIP
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:419
SCIP_RETCODE SCIPsetAddRealParam(SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: set.c:2861
#define SCIP_ALLOC(x)
Definition: def.h:361
int expbackoff
Definition: struct_sepa.h:65
SCIP_RETCODE SCIPsepaExitsol(SCIP_SEPA *sepa, SCIP_SET *set)
Definition: sepa.c:315
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:2791
SCIP_Longint nprobholechgs
Definition: struct_stat.h:107
SCIP_Longint SCIPsepaGetNCutsFoundAtNode(SCIP_SEPA *sepa)
Definition: sepa.c:843
#define SCIP_DECL_SEPAFREE(x)
Definition: type_sepa.h:55
int SCIPsepaGetPriority(SCIP_SEPA *sepa)
Definition: sepa.c:666
struct SCIP_SepaData SCIP_SEPADATA
Definition: type_sepa.h:38
SCIP_RETCODE SCIPsepaCreate(SCIP_SEPA **sepa, SCIP_SET *set, SCIP_MESSAGEHDLR *messagehdlr, BMS_BLKMEM *blkmem, const char *name, const char *desc, int priority, int freq, SCIP_Real maxbounddist, SCIP_Bool usessubscip, SCIP_Bool delay, SCIP_DECL_SEPACOPY((*sepacopy)), SCIP_DECL_SEPAFREE((*sepafree)), SCIP_DECL_SEPAINIT((*sepainit)), SCIP_DECL_SEPAEXIT((*sepaexit)), SCIP_DECL_SEPAINITSOL((*sepainitsol)), SCIP_DECL_SEPAEXITSOL((*sepaexitsol)), SCIP_DECL_SEPAEXECLP((*sepaexeclp)), SCIP_DECL_SEPAEXECSOL((*sepaexecsol)), SCIP_SEPADATA *sepadata)
Definition: sepa.c:87
SCIP callable library.
char * desc
Definition: struct_sepa.h:49