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-2017 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 {
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  return SCIP_OKAY;
176 }
177 
178 /** calls destructor and frees memory of separator */
180  SCIP_SEPA** sepa, /**< pointer to separator data structure */
181  SCIP_SET* set /**< global SCIP settings */
182  )
183 {
184  assert(sepa != NULL);
185  assert(*sepa != NULL);
186  assert(!(*sepa)->initialized);
187  assert(set != NULL);
188 
189  /* call destructor of separator */
190  if( (*sepa)->sepafree != NULL )
191  {
192  SCIP_CALL( (*sepa)->sepafree(set->scip, *sepa) );
193  }
194 
195  SCIPclockFree(&(*sepa)->sepaclock);
196  SCIPclockFree(&(*sepa)->setuptime);
197  BMSfreeMemoryArray(&(*sepa)->name);
198  BMSfreeMemoryArray(&(*sepa)->desc);
199  BMSfreeMemory(sepa);
200 
201  return SCIP_OKAY;
202 }
203 
204 /** initializes separator */
206  SCIP_SEPA* sepa, /**< separator */
207  SCIP_SET* set /**< global SCIP settings */
208  )
209 {
210  assert(sepa != NULL);
211  assert(set != NULL);
212 
213  if( sepa->initialized )
214  {
215  SCIPerrorMessage("separator <%s> already initialized\n", sepa->name);
216  return SCIP_INVALIDCALL;
217  }
218 
219  if( set->misc_resetstat )
220  {
221  SCIPclockReset(sepa->setuptime);
222  SCIPclockReset(sepa->sepaclock);
223 
224  sepa->lastsepanode = -1;
225  sepa->ncalls = 0;
226  sepa->ncutoffs = 0;
227  sepa->ncutsfound = 0;
228  sepa->ncutsapplied = 0;
229  sepa->nconssfound = 0;
230  sepa->ndomredsfound = 0;
231  sepa->ncallsatnode = 0;
232  sepa->ncutsfoundatnode = 0;
233  sepa->lpwasdelayed = FALSE;
234  sepa->solwasdelayed = FALSE;
235  }
236 
237  if( sepa->sepainit != NULL )
238  {
239  /* start timing */
240  SCIPclockStart(sepa->setuptime, set);
241 
242  SCIP_CALL( sepa->sepainit(set->scip, sepa) );
243 
244  /* stop timing */
245  SCIPclockStop(sepa->setuptime, set);
246  }
247  sepa->initialized = TRUE;
248 
249  return SCIP_OKAY;
250 }
251 
252 /** calls exit method of separator */
254  SCIP_SEPA* sepa, /**< separator */
255  SCIP_SET* set /**< global SCIP settings */
256  )
257 {
258  assert(sepa != NULL);
259  assert(set != NULL);
260 
261  if( !sepa->initialized )
262  {
263  SCIPerrorMessage("separator <%s> not initialized\n", sepa->name);
264  return SCIP_INVALIDCALL;
265  }
266 
267  if( sepa->sepaexit != NULL )
268  {
269  /* start timing */
270  SCIPclockStart(sepa->setuptime, set);
271 
272  SCIP_CALL( sepa->sepaexit(set->scip, sepa) );
273 
274  /* stop timing */
275  SCIPclockStop(sepa->setuptime, set);
276  }
277  sepa->initialized = FALSE;
278 
279  return SCIP_OKAY;
280 }
281 
282 /** informs separator that the branch and bound process is being started */
284  SCIP_SEPA* sepa, /**< separator */
285  SCIP_SET* set /**< global SCIP settings */
286  )
287 {
288  assert(sepa != NULL);
289  assert(set != NULL);
290 
291  sepa->lpwasdelayed = FALSE;
292  sepa->solwasdelayed = FALSE;
293 
294  /* call solving process initialization method of separator */
295  if( sepa->sepainitsol != NULL )
296  {
297  /* start timing */
298  SCIPclockStart(sepa->setuptime, set);
299 
300  SCIP_CALL( sepa->sepainitsol(set->scip, sepa) );
301 
302  /* stop timing */
303  SCIPclockStop(sepa->setuptime, set);
304  }
305 
306  return SCIP_OKAY;
307 }
308 
309 /** informs separator that the branch and bound process data is being freed */
311  SCIP_SEPA* sepa, /**< separator */
312  SCIP_SET* set /**< global SCIP settings */
313  )
314 {
315  assert(sepa != NULL);
316  assert(set != NULL);
317 
318  /* call solving process deinitialization method of separator */
319  if( sepa->sepaexitsol != NULL )
320  {
321  /* start timing */
322  SCIPclockStart(sepa->setuptime, set);
323 
324  SCIP_CALL( sepa->sepaexitsol(set->scip, sepa) );
325 
326  /* stop timing */
327  SCIPclockStop(sepa->setuptime, set);
328  }
329 
330  return SCIP_OKAY;
331 }
332 
333 /** calls LP separation method of separator */
335  SCIP_SEPA* sepa, /**< separator */
336  SCIP_SET* set, /**< global SCIP settings */
337  SCIP_STAT* stat, /**< dynamic problem statistics */
338  SCIP_SEPASTORE* sepastore, /**< separation storage */
339  int depth, /**< depth of current node */
340  SCIP_Real bounddist, /**< current relative distance of local dual bound to global dual bound */
341  SCIP_Bool execdelayed, /**< execute separator even if it is marked to be delayed */
342  SCIP_RESULT* result /**< pointer to store the result of the callback method */
343  )
344 {
345  assert(sepa != NULL);
346  assert(sepa->freq >= -1);
347  assert(0.0 <= sepa->maxbounddist && sepa->maxbounddist <= 1.0);
348  assert(0.0 <= bounddist && bounddist <= 1.0);
349  assert(set != NULL);
350  assert(set->scip != NULL);
351  assert(stat != NULL);
352  assert(depth >= 0);
353  assert(result != NULL);
354 
355  if( sepa->sepaexeclp != NULL
356  && SCIPsetIsLE(set, bounddist, sepa->maxbounddist)
357  && ((depth == 0 && sepa->freq == 0) || (sepa->freq > 0 && depth % sepa->freq == 0) || sepa->lpwasdelayed) )
358  {
359  if( (!sepa->delay && !sepa->lpwasdelayed) || execdelayed )
360  {
361  SCIP_Longint oldndomchgs;
362  SCIP_Longint oldnprobdomchgs;
363  int oldncuts;
364  int oldnactiveconss;
365  int ncutsfound;
366 
367  SCIPsetDebugMsg(set, "executing separator <%s> on LP solution\n", sepa->name);
368 
369  oldndomchgs = stat->nboundchgs + stat->nholechgs;
370  oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
371  oldncuts = SCIPsepastoreGetNCuts(sepastore);
372  oldnactiveconss = stat->nactiveconss;
373 
374  /* reset the statistics for current node */
375  if( sepa->lastsepanode != stat->ntotalnodes )
376  {
377  sepa->ncallsatnode = 0;
378  sepa->ncutsfoundatnode = 0;
379  }
380 
381  /* start timing */
382  SCIPclockStart(sepa->sepaclock, set);
383 
384  /* call external separation method */
385  SCIP_CALL( sepa->sepaexeclp(set->scip, sepa, result) );
386 
387  /* stop timing */
388  SCIPclockStop(sepa->sepaclock, set);
389 
390  /* update statistics */
391  if( *result != SCIP_DIDNOTRUN && *result != SCIP_DELAYED )
392  {
393  sepa->ncalls++;
394  sepa->ncallsatnode++;
395  sepa->lastsepanode = stat->ntotalnodes;
396  }
397  if( *result == SCIP_CUTOFF )
398  sepa->ncutoffs++;
399  ncutsfound = SCIPsepastoreGetNCuts(sepastore) - oldncuts;
400  sepa->ncutsfound += ncutsfound;
401  sepa->ncutsfoundatnode += ncutsfound;
402  sepa->nconssfound += MAX(stat->nactiveconss - oldnactiveconss, 0); /*lint !e776*/
403 
404  /* update domain reductions; therefore remove the domain
405  * reduction counts which were generated in probing mode */
406  sepa->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
407  sepa->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
408 
409  /* evaluate result */
410  if( *result != SCIP_CUTOFF
411  && *result != SCIP_CONSADDED
412  && *result != SCIP_REDUCEDDOM
413  && *result != SCIP_SEPARATED
414  && *result != SCIP_NEWROUND
415  && *result != SCIP_DIDNOTFIND
416  && *result != SCIP_DIDNOTRUN
417  && *result != SCIP_DELAYED )
418  {
419  SCIPerrorMessage("execution method of separator <%s> returned invalid result <%d>\n",
420  sepa->name, *result);
421  return SCIP_INVALIDRESULT;
422  }
423  }
424  else
425  {
426  SCIPsetDebugMsg(set, "separator <%s> was delayed\n", sepa->name);
427  *result = SCIP_DELAYED;
428  }
429 
430  /* remember whether separator was delayed */
431  sepa->lpwasdelayed = (*result == SCIP_DELAYED);
432  }
433  else
434  *result = SCIP_DIDNOTRUN;
435 
436  return SCIP_OKAY;
437 }
438 
439 /** calls primal solution separation method of separator */
441  SCIP_SEPA* sepa, /**< separator */
442  SCIP_SET* set, /**< global SCIP settings */
443  SCIP_STAT* stat, /**< dynamic problem statistics */
444  SCIP_SEPASTORE* sepastore, /**< separation storage */
445  SCIP_SOL* sol, /**< primal solution that should be separated */
446  int depth, /**< depth of current node */
447  SCIP_Bool execdelayed, /**< execute separator even if it is marked to be delayed */
448  SCIP_RESULT* result /**< pointer to store the result of the callback method */
449  )
450 {
451  assert(sepa != NULL);
452  assert(sepa->freq >= -1);
453  assert(set != NULL);
454  assert(set->scip != NULL);
455  assert(stat != NULL);
456  assert(depth >= 0);
457  assert(result != NULL);
458 
459  if( sepa->sepaexecsol != NULL
460  && ((depth == 0 && sepa->freq == 0) || (sepa->freq > 0 && depth % sepa->freq == 0) || sepa->solwasdelayed) )
461  {
462  if( (!sepa->delay && !sepa->solwasdelayed) || execdelayed )
463  {
464  SCIP_Longint oldndomchgs;
465  SCIP_Longint oldnprobdomchgs;
466  int oldncuts;
467  int oldnactiveconss;
468  int ncutsfound;
469 
470  SCIPsetDebugMsg(set, "executing separator <%s> on solution %p\n", sepa->name, (void*)sol);
471 
472  oldndomchgs = stat->nboundchgs + stat->nholechgs;
473  oldnprobdomchgs = stat->nprobboundchgs + stat->nprobholechgs;
474  oldncuts = SCIPsepastoreGetNCuts(sepastore);
475  oldnactiveconss = stat->nactiveconss;
476 
477  /* reset the statistics for current node */
478  if( sepa->lastsepanode != stat->ntotalnodes )
479  {
480  sepa->ncallsatnode = 0;
481  sepa->ncutsfoundatnode = 0;
482  }
483 
484  /* start timing */
485  SCIPclockStart(sepa->sepaclock, set);
486 
487  /* call external separation method */
488  SCIP_CALL( sepa->sepaexecsol(set->scip, sepa, sol, result) );
489 
490  /* stop timing */
491  SCIPclockStop(sepa->sepaclock, set);
492 
493  /* update statistics */
494  if( *result != SCIP_DIDNOTRUN && *result != SCIP_DELAYED )
495  {
496  sepa->ncalls++;
497  sepa->ncallsatnode++;
498  sepa->lastsepanode = stat->ntotalnodes;
499  }
500  if( *result == SCIP_CUTOFF )
501  sepa->ncutoffs++;
502  ncutsfound = SCIPsepastoreGetNCuts(sepastore) - oldncuts;
503  sepa->ncutsfound += ncutsfound;
504  sepa->ncutsfoundatnode += ncutsfound;
505  sepa->nconssfound += MAX(stat->nactiveconss - oldnactiveconss, 0); /*lint !e776*/
506 
507  /* update domain reductions; therefore remove the domain
508  * reduction counts which were generated in probing mode */
509  sepa->ndomredsfound += stat->nboundchgs + stat->nholechgs - oldndomchgs;
510  sepa->ndomredsfound -= (stat->nprobboundchgs + stat->nprobholechgs - oldnprobdomchgs);
511 
512  /* evaluate result */
513  if( *result != SCIP_CUTOFF
514  && *result != SCIP_CONSADDED
515  && *result != SCIP_REDUCEDDOM
516  && *result != SCIP_SEPARATED
517  && *result != SCIP_NEWROUND
518  && *result != SCIP_DIDNOTFIND
519  && *result != SCIP_DIDNOTRUN
520  && *result != SCIP_DELAYED )
521  {
522  SCIPerrorMessage("execution method of separator <%s> returned invalid result <%d>\n",
523  sepa->name, *result);
524  return SCIP_INVALIDRESULT;
525  }
526  }
527  else
528  {
529  SCIPsetDebugMsg(set, "separator <%s> was delayed\n", sepa->name);
530  *result = SCIP_DELAYED;
531  }
532 
533  /* remember whether separator was delayed */
534  sepa->solwasdelayed = (*result == SCIP_DELAYED);
535  }
536  else
537  *result = SCIP_DIDNOTRUN;
538 
539  return SCIP_OKAY;
540 }
541 
542 /** gets user data of separator */
544  SCIP_SEPA* sepa /**< separator */
545  )
546 {
547  assert(sepa != NULL);
548 
549  return sepa->sepadata;
550 }
551 
552 /** sets user data of separator; user has to free old data in advance! */
554  SCIP_SEPA* sepa, /**< separator */
555  SCIP_SEPADATA* sepadata /**< new separator user data */
556  )
557 {
558  assert(sepa != NULL);
559 
560  sepa->sepadata = sepadata;
561 }
562 
563 /* new callback/method setter methods */
564 
565 /** sets copy method of separator */
567  SCIP_SEPA* sepa, /**< separator */
568  SCIP_DECL_SEPACOPY ((*sepacopy)) /**< copy method of separator or NULL if you don't want to copy your plugin into sub-SCIPs */
569  )
570 {
571  assert(sepa != NULL);
572 
573  sepa->sepacopy = sepacopy;
574 }
575 
576 /** sets destructor method of separator */
578  SCIP_SEPA* sepa, /**< separator */
579  SCIP_DECL_SEPAFREE ((*sepafree)) /**< destructor of separator */
580  )
581 {
582  assert(sepa != NULL);
583 
584  sepa->sepafree = sepafree;
585 }
586 
587 /** sets initialization method of separator */
589  SCIP_SEPA* sepa, /**< separator */
590  SCIP_DECL_SEPAINIT ((*sepainit)) /**< initialize separator */
591  )
592 {
593  assert(sepa != NULL);
594 
595  sepa->sepainit = sepainit;
596 }
597 
598 /** sets deinitialization method of separator */
600  SCIP_SEPA* sepa, /**< separator */
601  SCIP_DECL_SEPAEXIT ((*sepaexit)) /**< deinitialize separator */
602  )
603 {
604  assert(sepa != NULL);
605 
606  sepa->sepaexit = sepaexit;
607 }
608 
609 /** sets solving process initialization method of separator */
611  SCIP_SEPA* sepa, /**< separator */
612  SCIP_DECL_SEPAINITSOL ((*sepainitsol)) /**< solving process initialization method of separator */
613  )
614 {
615  assert(sepa != NULL);
616 
617  sepa->sepainitsol = sepainitsol;
618 }
619 
620 /** sets solving process deinitialization method of separator */
622  SCIP_SEPA* sepa, /**< separator */
623  SCIP_DECL_SEPAEXITSOL ((*sepaexitsol)) /**< solving process deinitialization method of separator */
624  )
625 {
626  assert(sepa != NULL);
627 
628  sepa->sepaexitsol = sepaexitsol;
629 }
630 
631 /** gets name of separator */
632 const char* SCIPsepaGetName(
633  SCIP_SEPA* sepa /**< separator */
634  )
635 {
636  assert(sepa != NULL);
637 
638  return sepa->name;
639 }
640 
641 /** gets description of separator */
642 const char* SCIPsepaGetDesc(
643  SCIP_SEPA* sepa /**< separator */
644  )
645 {
646  assert(sepa != NULL);
647 
648  return sepa->desc;
649 }
650 
651 /** gets priority of separator */
653  SCIP_SEPA* sepa /**< separator */
654  )
655 {
656  assert(sepa != NULL);
657 
658  return sepa->priority;
659 }
660 
661 /** sets priority of separator */
663  SCIP_SEPA* sepa, /**< separator */
664  SCIP_SET* set, /**< global SCIP settings */
665  int priority /**< new priority of the separator */
666  )
667 {
668  assert(sepa != NULL);
669  assert(set != NULL);
670 
671  sepa->priority = priority;
672  set->sepassorted = FALSE;
673 }
674 
675 /** gets frequency of separator */
677  SCIP_SEPA* sepa /**< separator */
678  )
679 {
680  assert(sepa != NULL);
681 
682  return sepa->freq;
683 }
684 
685 /** sets frequency of separator */
687  SCIP_SEPA* sepa, /**< separator */
688  int freq /**< new frequency of separator */
689  )
690 {
691  assert(sepa != NULL);
692 
693  sepa->freq = freq;
694 }
695 
696 /** get maximal bound distance at which the separator is called */
698  SCIP_SEPA* sepa /**< separator */
699  )
700 {
701  assert(sepa != NULL);
702 
703  return sepa->maxbounddist;
704 }
705 
706 /** does the separator use a secondary SCIP instance? */
708  SCIP_SEPA* sepa /**< separator */
709  )
710 {
711  assert(sepa != NULL);
712 
713  return sepa->usessubscip;
714 }
715 
716 /** enables or disables all clocks of \p sepa, depending on the value of the flag */
718  SCIP_SEPA* sepa, /**< the separator for which all clocks should be enabled or disabled */
719  SCIP_Bool enable /**< should the clocks of the separator be enabled? */
720  )
721 {
722  assert(sepa != NULL);
723 
724  SCIPclockEnableOrDisable(sepa->setuptime, enable);
725  SCIPclockEnableOrDisable(sepa->sepaclock, enable);
726 }
727 
728 /** gets time in seconds used in this separator for setting up for next stages */
730  SCIP_SEPA* sepa /**< separator */
731  )
732 {
733  assert(sepa != NULL);
734 
735  return SCIPclockGetTime(sepa->setuptime);
736 }
737 
738 /** gets time in seconds used in this separator */
740  SCIP_SEPA* sepa /**< separator */
741  )
742 {
743  assert(sepa != NULL);
744 
745  return SCIPclockGetTime(sepa->sepaclock);
746 }
747 
748 /** gets the total number of times, the separator was called */
750  SCIP_SEPA* sepa /**< separator */
751  )
752 {
753  assert(sepa != NULL);
754 
755  return sepa->ncalls;
756 }
757 
758 /** gets the number of times, the separator was called at the current node */
760  SCIP_SEPA* sepa /**< separator */
761  )
762 {
763  assert(sepa != NULL);
764 
765  return sepa->ncallsatnode;
766 }
767 
768 /** gets total number of times, the separator detected a cutoff */
770  SCIP_SEPA* sepa /**< separator */
771  )
772 {
773  assert(sepa != NULL);
774 
775  return sepa->ncutoffs;
776 }
777 
778 /** gets the total number of cutting planes found by this separator */
780  SCIP_SEPA* sepa /**< separator */
781  )
782 {
783  assert(sepa != NULL);
784 
785  return sepa->ncutsfound;
786 }
787 
788 /** gets the total number of cutting planes applied to lp */
790  SCIP_SEPA* sepa /**< separator */
791  )
792 {
793  assert(sepa != NULL);
794 
795  return sepa->ncutsapplied;
796 }
797 
798 /** increase count of applied cuts */
800  SCIP_SEPA* sepa /**< separator */
801  )
802 {
803  assert( sepa != NULL );
804 
805  ++sepa->ncutsapplied;
806 }
807 
808 /** increase count of found cuts */
810  SCIP_SEPA* sepa /**< separator */
811  )
812 {
813  assert( sepa != NULL );
814 
815  ++sepa->ncutsfound;
816 }
817 
818 /** increase count of found cuts at current node */
820  SCIP_SEPA* sepa /**< separator */
821  )
822 {
823  assert( sepa != NULL );
824 
825  ++sepa->ncutsfoundatnode;
826 }
827 
828 /** gets the number of cutting planes found by this separator at the current node */
830  SCIP_SEPA* sepa /**< separator */
831  )
832 {
833  assert(sepa != NULL);
834 
835  return sepa->ncutsfoundatnode;
836 }
837 
838 /** gets total number of additional constraints added by this separator */
840  SCIP_SEPA* sepa /**< separator */
841  )
842 {
843  assert(sepa != NULL);
844 
845  return sepa->nconssfound;
846 }
847 
848 /** gets total number of domain reductions found by this separator */
850  SCIP_SEPA* sepa /**< separator */
851  )
852 {
853  assert(sepa != NULL);
854 
855  return sepa->ndomredsfound;
856 }
857 
858 /** should separator be delayed, if other separators found cuts? */
860  SCIP_SEPA* sepa /**< separator */
861  )
862 {
863  assert(sepa != NULL);
864 
865  return sepa->delay;
866 }
867 
868 /** was separation of the LP solution delayed at the last call? */
870  SCIP_SEPA* sepa /**< separator */
871  )
872 {
873  assert(sepa != NULL);
874 
875  return sepa->lpwasdelayed;
876 }
877 
878 /** was separation of the primal solution delayed at the last call? */
880  SCIP_SEPA* sepa /**< separator */
881  )
882 {
883  assert(sepa != NULL);
884 
885  return sepa->solwasdelayed;
886 }
887 
888 /** is separator initialized? */
890  SCIP_SEPA* sepa /**< separator */
891  )
892 {
893  assert(sepa != NULL);
894 
895  return sepa->initialized;
896 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
SCIP_Bool solwasdelayed
Definition: struct_sepa.h:68
void SCIPsepaSetFree(SCIP_SEPA *sepa, SCIP_DECL_SEPAFREE((*sepafree)))
Definition: sepa.c:577
internal methods for separators
SCIP_Bool usessubscip
Definition: struct_sepa.h:65
SCIP_SEPADATA * sepadata
Definition: struct_sepa.h:58
SCIP_Bool SCIPsetIsLE(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:5580
void SCIPsepaEnableOrDisableClocks(SCIP_SEPA *sepa, SCIP_Bool enable)
Definition: sepa.c:717
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:799
#define SCIP_MAXSTRLEN
Definition: def.h:215
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:707
SCIP_Longint SCIPsepaGetNDomredsFound(SCIP_SEPA *sepa)
Definition: sepa.c:849
SCIP_Real SCIPsepaGetSetupTime(SCIP_SEPA *sepa)
Definition: sepa.c:729
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:9340
SCIP_Real maxbounddist
Definition: struct_sepa.h:46
#define TRUE
Definition: def.h:63
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
Definition: sepa.c:632
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Bool initialized
Definition: struct_sepa.h:69
SCIP_Real SCIPsepaGetTime(SCIP_SEPA *sepa)
Definition: sepa.c:739
SCIP_Longint ncutsfound
Definition: struct_sepa.h:42
void SCIPsepaSetExit(SCIP_SEPA *sepa, SCIP_DECL_SEPAEXIT((*sepaexit)))
Definition: sepa.c:599
SCIP_Longint SCIPsepaGetNCutsFound(SCIP_SEPA *sepa)
Definition: sepa.c:779
void SCIPsepaIncNCutsFoundAtNode(SCIP_SEPA *sepa)
Definition: sepa.c:819
SCIP_RETCODE SCIPsetSepaPriority(SCIP *scip, SCIP_SEPA *sepa, int priority)
Definition: scip.c:7500
int ncallsatnode
Definition: struct_sepa.h:63
SCIP_RETCODE SCIPsepaFree(SCIP_SEPA **sepa, SCIP_SET *set)
Definition: sepa.c:179
#define SCIP_DECL_SEPAEXECLP(x)
Definition: type_sepa.h:115
internal methods for handling parameter settings
void SCIPclockEnableOrDisable(SCIP_CLOCK *clck, SCIP_Bool enable)
Definition: clock.c:250
#define BMSfreeMemory(ptr)
Definition: memory.h:100
SCIP_DECL_SORTPTRCOMP(SCIPsepaComp)
Definition: sepa.c:42
SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
Definition: sepa.c:543
SCIP_RETCODE SCIPsepaInit(SCIP_SEPA *sepa, SCIP_SET *set)
Definition: sepa.c:205
#define SCIP_DECL_SEPACOPY(x)
Definition: type_sepa.h:47
SCIP_RETCODE SCIPsepaExecSol(SCIP_SEPA *sepa, SCIP_SET *set, SCIP_STAT *stat, SCIP_SEPASTORE *sepastore, SCIP_SOL *sol, int depth, SCIP_Bool execdelayed, SCIP_RESULT *result)
Definition: sepa.c:440
int SCIPsepaGetFreq(SCIP_SEPA *sepa)
Definition: sepa.c:676
SCIP_RETCODE SCIPsepaInitsol(SCIP_SEPA *sepa, SCIP_SET *set)
Definition: sepa.c:283
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:102
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:67
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:769
int SCIPsepaGetNCallsAtNode(SCIP_SEPA *sepa)
Definition: sepa.c:759
int SCIPsepastoreGetNCuts(SCIP_SEPASTORE *sepastore)
Definition: sepastore.c:1328
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:428
void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
Definition: sepa.c:553
#define NULL
Definition: lpi_spx1.cpp:137
int ncutsfoundatnode
Definition: struct_sepa.h:64
void SCIPsepaSetFreq(SCIP_SEPA *sepa, int freq)
Definition: sepa.c:686
void SCIPsepaSetExitsol(SCIP_SEPA *sepa, SCIP_DECL_SEPAEXITSOL((*sepaexitsol)))
Definition: sepa.c:621
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:306
SCIP_Real SCIPsepaGetMaxbounddist(SCIP_SEPA *sepa)
Definition: sepa.c:697
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:2701
internal methods for storing separated cuts
const char * SCIPsepaGetDesc(SCIP_SEPA *sepa)
Definition: sepa.c:642
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:98
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:566
SCIP_Longint SCIPsepaGetNCalls(SCIP_SEPA *sepa)
Definition: sepa.c:749
SCIP_Bool SCIPsepaWasLPDelayed(SCIP_SEPA *sepa)
Definition: sepa.c:869
public data structures and miscellaneous methods
void SCIPsepaSetInitsol(SCIP_SEPA *sepa, SCIP_DECL_SEPAINITSOL((*sepainitsol)))
Definition: sepa.c:610
#define SCIP_Bool
Definition: def.h:61
#define SCIP_DECL_SEPAINIT(x)
Definition: type_sepa.h:63
static const char * paramname[]
Definition: lpi_msk.c:4268
SCIP_Longint SCIPsepaGetNConssFound(SCIP_SEPA *sepa)
Definition: sepa.c:839
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:175
#define MAX(x, y)
Definition: tclique_def.h:75
#define SCIPsetDebugMsg
Definition: set.h:1870
SCIP_RETCODE SCIPsepaExecLP(SCIP_SEPA *sepa, SCIP_SET *set, SCIP_STAT *stat, SCIP_SEPASTORE *sepastore, int depth, SCIP_Real bounddist, SCIP_Bool execdelayed, SCIP_RESULT *result)
Definition: sepa.c:334
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:138
SCIP_Bool delay
Definition: struct_sepa.h:66
#define SCIP_MAXTREEDEPTH
Definition: def.h:242
int SCIPparamGetInt(SCIP_PARAM *param)
Definition: paramset.c:716
void SCIPsepaSetPriority(SCIP_SEPA *sepa, SCIP_SET *set, int priority)
Definition: sepa.c:662
SCIP_Bool SCIPsepaWasSolDelayed(SCIP_SEPA *sepa)
Definition: sepa.c:879
int nactiveconss
Definition: struct_stat.h:214
SCIP_RETCODE SCIPsepaExit(SCIP_SEPA *sepa, SCIP_SET *set)
Definition: sepa.c:253
#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:859
#define SCIP_Real
Definition: def.h:135
internal methods for problem statistics
datastructures for separators
SCIP_Longint SCIPsepaGetNCutsApplied(SCIP_SEPA *sepa)
Definition: sepa.c:789
#define BMSallocMemory(ptr)
Definition: memory.h:74
void SCIPsepaIncNCutsFound(SCIP_SEPA *sepa)
Definition: sepa.c:809
#define SCIP_Longint
Definition: def.h:120
int priority
Definition: struct_sepa.h:61
void SCIPsepaSetInit(SCIP_SEPA *sepa, SCIP_DECL_SEPAINIT((*sepainit)))
Definition: sepa.c:588
SCIP_Bool SCIPsepaIsInitialized(SCIP_SEPA *sepa)
Definition: sepa.c:889
common defines and data types used in all packages of SCIP
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:392
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:2749
#define SCIP_ALLOC(x)
Definition: def.h:317
SCIP_RETCODE SCIPsepaExitsol(SCIP_SEPA *sepa, SCIP_SET *set)
Definition: sepa.c:310
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:2679
SCIP_Longint nprobholechgs
Definition: struct_stat.h:107
SCIP_Longint SCIPsepaGetNCutsFoundAtNode(SCIP_SEPA *sepa)
Definition: sepa.c:829
#define SCIP_DECL_SEPAFREE(x)
Definition: type_sepa.h:55
int SCIPsepaGetPriority(SCIP_SEPA *sepa)
Definition: sepa.c:652
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