Scippy

SCIP

Solving Constraint Integer Programs

cutpool.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 cutpool.c
17  * @brief methods for storing cuts in a cut pool
18  * @author Tobias Achterberg
19  * @author Stefan Heinz
20  * @author Gerald Gamrath
21  * @author Marc Pfetsch
22  * @author Kati Wolter
23  */
24 
25 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
26 
27 #include <assert.h>
28 
29 #include "scip/def.h"
30 #include "scip/set.h"
31 #include "scip/stat.h"
32 #include "scip/clock.h"
33 #include "scip/lp.h"
34 #include "scip/cons.h"
35 #include "scip/sepa.h"
36 #include "scip/sepastore.h"
37 #include "scip/cutpool.h"
38 #include "scip/pub_message.h"
39 #include "scip/pub_misc.h"
40 
41 #include "scip/struct_cutpool.h"
42 
43 
44 
45 /*
46  * Hash functions
47  */
48 
49 /** gets the hash key of a cut */
50 static
51 SCIP_DECL_HASHGETKEY(hashGetKeyCut)
52 { /*lint --e{715}*/
53  SCIP_CUT* cut;
54 
55  cut = (SCIP_CUT*)elem;
56  assert(cut != NULL);
57  assert(cut->row != NULL);
58 
59  /* the key of a cut is the row */
60  return cut->row;
61 }
62 
63 /** returns TRUE iff both cuts are identical */
64 static
65 SCIP_DECL_HASHKEYEQ(hashKeyEqCut)
66 { /*lint --e{715}*/
67  SCIP_ROW* row1;
68  SCIP_ROW* row2;
69  SCIP_Real row1scale;
70  SCIP_Real row2scale;
71  SCIP_SET* set;
72 
73  row1 = (SCIP_ROW*)key1;
74  row2 = (SCIP_ROW*)key2;
75  assert(row1 != NULL);
76  assert(row2 != NULL);
77 
78  /* return true if the row is the same */
79  if( row1 == row2 )
80  return TRUE;
81 
82  assert(row1->validminmaxidx);
83  assert(row2->validminmaxidx);
84 
85  /* compare the trivial characteristics of the rows */
86  if( row1->len != row2->len
87  || row1->minidx != row2->minidx
88  || row1->maxidx != row2->maxidx
89  )
90  return FALSE;
91 
92  set = (SCIP_SET*) userptr;
93 
94  /* set scale for the rows such that the largest absolute coefficient is 1.0 */
95  row1scale = 1.0 / SCIProwGetMaxval(row1, set);
96  row2scale = 1.0 / SCIProwGetMaxval(row2, set);
97 
98  /* check if scaled min value is feas equal first */
99  if( !SCIPsetIsFeasEQ(set, row1scale * SCIProwGetMinval(row1, set),
100  row2scale * SCIProwGetMinval(row2, set)) )
101  return FALSE;
102 
103  SCIProwSort(row1);
104  assert(row1->lpcolssorted);
105  assert(row1->nonlpcolssorted);
106 
107  SCIProwSort(row2);
108  assert(row2->lpcolssorted);
109  assert(row2->nonlpcolssorted);
110 
111  /* currently we are only handling rows which are completely linked or not linked at all */
112  assert(row1->nunlinked == 0 || row1->nlpcols == 0);
113  assert(row2->nunlinked == 0 || row2->nlpcols == 0);
114 
115  /* set scale sign such that the rows are of the form ax <= b */
116  if( SCIPsetIsInfinity(set, row1->rhs) )
117  row1scale = -row1scale;
118  if( SCIPsetIsInfinity(set, row2->rhs) )
119  row2scale = -row2scale;
120 
121  /* both rows have LP columns, or none of them has, or one has only LP colums and the other only non-LP columns,
122  * so we can rely on the sorting of the columns
123  */
124  if( (row1->nlpcols == 0) == (row2->nlpcols == 0)
125  || (row1->nlpcols == 0 && row2->nlpcols == row2->len)
126  || (row1->nlpcols == row1->len && row2->nlpcols == 0) )
127  {
128  int i;
129 
130  if( (row1->nlpcols == 0) == (row2->nlpcols == 0) )
131  {
132 #ifndef NDEBUG
133  /* in debug mode, we check that we can rely on the partition into LP columns and non-LP columns */
134  int i2;
135 
136  i = 0;
137  i2 = row2->nlpcols;
138  while( i < row1->nlpcols && i2 < row2->len )
139  {
140  assert(row1->cols[i] != row2->cols[i2]);
141  if( row1->cols_index[i] < row2->cols_index[i2] )
142  ++i;
143  else
144  {
145  assert(row1->cols_index[i] > row2->cols_index[i2]);
146  ++i2;
147  }
148  }
149  assert(i == row1->nlpcols || i2 == row2->len);
150 
151  i = row1->nlpcols;
152  i2 = 0;
153  while( i < row1->len && i2 < row2->nlpcols )
154  {
155  assert(row1->cols[i] != row2->cols[i2]);
156  if( row1->cols_index[i] < row2->cols_index[i2] )
157  ++i;
158  else
159  {
160  assert(row1->cols_index[i] > row2->cols_index[i2]);
161  ++i2;
162  }
163  }
164  assert(i == row1->len || i2 == row2->nlpcols);
165 #endif
166 
167  /* both rows are linked and the number of lpcolumns is not equal so they cannot be equal */
168  if( row1->nlpcols != row2->nlpcols )
169  return FALSE;
170  }
171 
172  /* compare the columns of the rows */
173  for( i = 0; i < row1->len; ++i )
174  {
175  if( row1->cols_index[i] != row2->cols_index[i] )
176  return FALSE;
177  }
178 
179  /* compare the coefficients of the rows */
180  for( i = 0; i < row1->len; ++i )
181  {
182  if( !SCIPsetIsFeasEQ(set, row1scale * row1->vals[i], row2scale * row2->vals[i]) )
183  return FALSE;
184  }
185  }
186  /* one row has LP columns, but the other not, that could be because the one without was just created and isn't
187  * linked yet; in this case, one column could be an LP column in one row and a non-LP column in the other row, so we
188  * cannot rely on the partition; thus, we iteratively check whether the next column of row1 is either the next LP
189  * column of row2 or the next non-LP column of row2 and the coefficients are equal
190  */
191  else
192  {
193  int i1;
194  int ilp;
195  int inlp;
196 
197  /* ensure that row1 is the row without LP columns, switch the rows, if neccessary */
198  if( row2->nlpcols == 0 )
199  {
200  SCIP_ROW* tmprow;
201  SCIP_Real tmpscale;
202 
203  tmprow = row2;
204  row2 = row1;
205  row1 = tmprow;
206 
207  tmpscale = row2scale;
208  row2scale = row1scale;
209  row1scale = tmpscale;
210  }
211  assert(row1->nlpcols == 0 && row2->nlpcols > 0);
212 
213  ilp = 0;
214  inlp = row2->nlpcols;
215 
216  /* compare the columns and coefficients of the rows */
217  for( i1 = 0; i1 < row1->len; ++i1 )
218  {
219  /* current column of row1 is the current LP column of row2, check the coefficient */
220  if( ilp < row2->nlpcols && row1->cols[i1] == row2->cols[ilp] )
221  {
222  if( !SCIPsetIsFeasEQ(set, row1scale * row1->vals[i1], row2scale * row2->vals[ilp]) )
223  return FALSE;
224  else
225  ++ilp;
226  }
227  /* current column of row1 is the current non-LP column of row2, check the coefficient */
228  else if( inlp < row2->len && row1->cols[i1] == row2->cols[inlp] )
229  {
230  if( !SCIPsetIsFeasEQ(set, row1scale * row1->vals[i1], row2scale * row2->vals[inlp]) )
231  return FALSE;
232  else
233  ++inlp;
234  }
235  /* current column of row1 is neither the current LP column of row2, nor the current non-LP column of row 2 */
236  else
237  return FALSE;
238  }
239  }
240 
241  return TRUE;
242 }
243 
244 static
245 SCIP_DECL_HASHKEYVAL(hashKeyValCut)
246 { /*lint --e{715}*/
247  SCIP_ROW* row;
248  int i;
249  SCIP_Real scale;
250  SCIP_SET* set;
251  uint64_t hash;
252 
253  set = (SCIP_SET*) userptr;
254  row = (SCIP_ROW*)key;
255  assert(row != NULL);
256  assert(row->len > 0);
257 
258  scale = 1.0 / SCIProwGetMaxval(row, set);
259  if( SCIPsetIsInfinity(set, row->rhs) )
260  scale = -scale;
261 
262  hash = (uint64_t) (long) row->len;
263 
264  for( i = 0; i < row->len; ++i )
265  {
266  SCIP_Real val = scale * row->vals[i];
267 
268  hash += SCIPhashTwo(SCIPrealHashCode(val), row->cols_index[i]);
269  }
270 
271  return hash;
272 }
273 
274 
275 /*
276  * dynamic memory arrays
277  */
278 
279 /** resizes cuts array to be able to store at least num entries */
280 static
282  SCIP_CUTPOOL* cutpool, /**< cut pool */
283  SCIP_SET* set, /**< global SCIP settings */
284  int num /**< minimal number of slots in array */
285  )
286 {
287  assert(cutpool != NULL);
288  assert(set != NULL);
289 
290  if( num > cutpool->cutssize )
291  {
292  int newsize;
293 
294  newsize = SCIPsetCalcMemGrowSize(set, num);
295  SCIP_ALLOC( BMSreallocMemoryArray(&cutpool->cuts, newsize) );
296  cutpool->cutssize = newsize;
297  }
298  assert(num <= cutpool->cutssize);
299 
300  return SCIP_OKAY;
301 }
302 
303 
304 
305 /*
306  * Cut methods
307  */
308 
309 /** creates a cut and captures the row */
310 static
312  SCIP_CUT** cut, /**< pointer to store the cut */
313  BMS_BLKMEM* blkmem, /**< block memory */
314  SCIP_ROW* row /**< row this cut represents */
315  )
316 {
317  assert(cut != NULL);
318  assert(blkmem != NULL);
319  assert(row != NULL);
320 
321  /* allocate cut memory */
322  SCIP_ALLOC( BMSallocBlockMemory(blkmem, cut) );
323  (*cut)->row = row;
324  (*cut)->age = 0;
325  (*cut)->processedlp = -1;
326  (*cut)->processedlpsol = -1;
327  (*cut)->pos = -1;
328 
329  /* capture row */
330  SCIProwCapture(row);
331 
332  return SCIP_OKAY;
333 }
334 
335 /** frees a cut and releases the row */
336 static
338  SCIP_CUT** cut, /**< pointer to store the cut */
339  BMS_BLKMEM* blkmem, /**< block memory */
340  SCIP_SET* set, /**< global SCIP settings */
341  SCIP_LP* lp /**< current LP data */
342  )
343 {
344  assert(cut != NULL);
345  assert(*cut != NULL);
346  assert((*cut)->row != NULL);
347  assert(blkmem != NULL);
348 
349  /* release row */
350  SCIP_CALL( SCIProwRelease(&(*cut)->row, blkmem, set, lp) );
351 
352  /* free cut memory */
353  BMSfreeBlockMemory(blkmem, cut);
354 
355  return SCIP_OKAY;
356 }
357 
358 /** returns whether the cut's age exceeds the age limit */
359 static
361  SCIP_CUT* cut, /**< cut to check */
362  int agelimit /**< maximum age a cut can reach before it is deleted from the pool, or -1 */
363  )
364 {
365  assert(cut != NULL);
366 
367  /* since agelimit can be -1 cast to unsigned before comparison, then it is the maximum unsigned value in that case */
368  return (unsigned int)cut->age > (unsigned int)agelimit;
369 }
370 
371 /** gets the row of the cut */
373  SCIP_CUT* cut /**< cut */
374  )
375 {
376  assert(cut != NULL);
377 
378  return cut->row;
379 }
380 
381 /** gets the age of the cut: the number of consecutive cut pool separation rounds where the cut was neither in the LP nor violated */
383  SCIP_CUT* cut /**< cut */
384  )
385 {
386  assert(cut != NULL);
387 
388  return cut->age;
389 }
390 
391 /** returns the ratio of LPs where the row belonging to this cut was active in an LP solution, i.e.
392  * where the age of its row has not been increased
393  *
394  * @see SCIPcutGetAge() to get the age of a cut
395  */
397  SCIP_CUT* cut /**< cut */
398  )
399 {
400  SCIP_Longint nlpsaftercreation;
401  SCIP_Longint activeinlpcounter;
402 
403  assert(cut != NULL);
404  assert(cut->row != NULL);
405 
406  nlpsaftercreation = SCIProwGetNLPsAfterCreation(cut->row);
407  activeinlpcounter = SCIProwGetActiveLPCount(cut->row);
408 
409  return (nlpsaftercreation > 0 ? activeinlpcounter / (SCIP_Real)nlpsaftercreation : 0.0);
410 }
411 
412 /*
413  * Cutpool methods
414  */
415 
416 /** creates cut pool */
418  SCIP_CUTPOOL** cutpool, /**< pointer to store cut pool */
419  BMS_BLKMEM* blkmem, /**< block memory */
420  SCIP_SET* set, /**< global SCIP settings */
421  int agelimit, /**< maximum age a cut can reach before it is deleted from the pool */
422  SCIP_Bool globalcutpool /**< is this the global cut pool of SCIP? */
423  )
424 {
425  assert(cutpool != NULL);
426  assert(agelimit >= -1);
427 
428  SCIP_ALLOC( BMSallocMemory(cutpool) );
429 
430  SCIP_CALL( SCIPclockCreate(&(*cutpool)->poolclock, SCIP_CLOCKTYPE_DEFAULT) );
431 
432  SCIP_CALL( SCIPhashtableCreate(&(*cutpool)->hashtable, blkmem,
433  (set->misc_usesmalltables ? SCIP_HASHSIZE_CUTPOOLS_SMALL : SCIP_HASHSIZE_CUTPOOLS),
434  hashGetKeyCut, hashKeyEqCut, hashKeyValCut, (void*) set) );
435 
436  (*cutpool)->cuts = NULL;
437  (*cutpool)->cutssize = 0;
438  (*cutpool)->ncuts = 0;
439  (*cutpool)->nremovablecuts = 0;
440  (*cutpool)->agelimit = agelimit;
441  (*cutpool)->processedlp = -1;
442  (*cutpool)->processedlpsol = -1;
443  (*cutpool)->processedlpefficacy = SCIP_INVALID;
444  (*cutpool)->processedlpsolefficacy = SCIP_INVALID;
445  (*cutpool)->firstunprocessed = 0;
446  (*cutpool)->firstunprocessedsol = 0;
447  (*cutpool)->maxncuts = 0;
448  (*cutpool)->ncalls = 0;
449  (*cutpool)->ncutsfound = 0;
450  (*cutpool)->globalcutpool = globalcutpool;
451 
452  return SCIP_OKAY;
453 }
454 
455 /** frees cut pool */
457  SCIP_CUTPOOL** cutpool, /**< pointer to store cut pool */
458  BMS_BLKMEM* blkmem, /**< block memory */
459  SCIP_SET* set, /**< global SCIP settings */
460  SCIP_LP* lp /**< current LP data */
461  )
462 {
463  assert(cutpool != NULL);
464  assert(*cutpool != NULL);
465 
466  /* remove all cuts from the pool */
467  SCIP_CALL( SCIPcutpoolClear(*cutpool, blkmem, set, lp) );
468 
469  /* free clock */
470  SCIPclockFree(&(*cutpool)->poolclock);
471 
472  /* free hash table */
473  SCIPhashtableFree(&(*cutpool)->hashtable);
474 
475  BMSfreeMemoryArrayNull(&(*cutpool)->cuts);
476  BMSfreeMemory(cutpool);
477 
478  return SCIP_OKAY;
479 }
480 
481 /** removes all rows from the cut pool */
483  SCIP_CUTPOOL* cutpool, /**< cut pool */
484  BMS_BLKMEM* blkmem, /**< block memory */
485  SCIP_SET* set, /**< global SCIP settings */
486  SCIP_LP* lp /**< current LP data */
487  )
488 {
489  int i;
490 
491  assert(cutpool != NULL);
492 
493  /* free cuts */
494  for( i = 0; i < cutpool->ncuts; ++i )
495  {
496  if( cutpool->globalcutpool )
497  cutpool->cuts[i]->row->inglobalcutpool = FALSE;
498  SCIProwUnlock(cutpool->cuts[i]->row);
499  SCIP_CALL( cutFree(&cutpool->cuts[i], blkmem, set, lp) );
500  }
501 
502  cutpool->ncuts = 0;
503  cutpool->nremovablecuts = 0;
504 
505  return SCIP_OKAY;
506 }
507 
508 /** removes the cut from the cut pool */
509 static
511  SCIP_CUTPOOL* cutpool, /**< cut pool */
512  BMS_BLKMEM* blkmem, /**< block memory */
513  SCIP_SET* set, /**< global SCIP settings */
514  SCIP_STAT* stat, /**< problem statistics data */
515  SCIP_LP* lp, /**< current LP data */
516  SCIP_CUT* cut /**< cut to remove */
517  )
518 {
519  int pos;
520 
521  assert(cutpool != NULL);
522  assert(cutpool->firstunprocessed <= cutpool->ncuts);
523  assert(cutpool->firstunprocessedsol <= cutpool->ncuts);
524  assert(blkmem != NULL);
525  assert(stat != NULL);
526  assert(cutpool->processedlp <= stat->lpcount);
527  assert(cutpool->processedlpsol <= stat->lpcount);
528  assert(cut != NULL);
529  assert(cut->row != NULL);
530 
531  pos = cut->pos;
532  assert(0 <= pos && pos < cutpool->ncuts);
533  assert(cutpool->cuts[pos] == cut);
534 
535  /* decrease the number of removable cuts counter (row might have changed its removable status -> counting might not
536  * be correct
537  */
538  if( SCIProwIsRemovable(cut->row) && cutpool->nremovablecuts > 0 )
539  cutpool->nremovablecuts--;
540 
541  /* if this is the global cut pool of SCIP, mark the row to not be member anymore */
542  if( cutpool->globalcutpool )
543  {
544  assert(cut->row->inglobalcutpool);
545  cut->row->inglobalcutpool = FALSE;
546  }
547 
548  /* remove the cut from the hash table */
549  assert(SCIPhashtableExists(cutpool->hashtable, (void*)cut));
550  SCIP_CALL( SCIPhashtableRemove(cutpool->hashtable, (void*)cut) );
551  assert(! SCIPhashtableExists(cutpool->hashtable, (void*)cut));
552 
553  /* unlock the row */
554  SCIProwUnlock(cut->row);
555 
556  /* free the cut */
557  SCIP_CALL( cutFree(&cutpool->cuts[pos], blkmem, set, lp) );
558 
559  --cutpool->ncuts;
560  cutpool->firstunprocessed = MIN(cutpool->firstunprocessed, cutpool->ncuts);
561  cutpool->firstunprocessedsol = MIN(cutpool->firstunprocessedsol, cutpool->ncuts);
562 
563  /* move the last cut of the pool to the free position */
564  if( pos < cutpool->ncuts )
565  {
566  cutpool->cuts[pos] = cutpool->cuts[cutpool->ncuts];
567  cutpool->cuts[pos]->pos = pos;
568  assert(cutpool->cuts[pos]->processedlp <= stat->lpcount);
569  assert(cutpool->cuts[pos]->processedlpsol <= stat->lpcount);
570  if( cutpool->cuts[pos]->processedlp < stat->lpcount )
571  cutpool->firstunprocessed = MIN(cutpool->firstunprocessed, pos);
572  if( cutpool->cuts[pos]->processedlpsol < stat->lpcount )
573  cutpool->firstunprocessedsol = MIN(cutpool->firstunprocessedsol, pos);
574  }
575 
576  return SCIP_OKAY;
577 }
578 
579 /** checks if cut is already existing */
581  SCIP_CUTPOOL* cutpool, /**< cut pool */
582  SCIP_SET* set, /**< global SCIP settings */
583  SCIP_ROW* row /**< cutting plane to add */
584  )
585 {
586  SCIP_CUT* othercut;
587  assert(cutpool != NULL);
588  assert(row != NULL);
589 
590  if( row->len == 0 )
591  {
592  /* trivial cut is only new if it proves infeasibility */
593  return SCIPsetIsFeasLT(set, row->constant, row->lhs) || SCIPsetIsFeasGT(set, row->constant, row->rhs);
594  }
595 
596  othercut = (SCIP_CUT*)SCIPhashtableRetrieve(cutpool->hashtable, (void*)row);
597  /* check in hash table, if cut already exists in the pool */
598  if( othercut == NULL )
599  {
600  return TRUE;
601  }
602  else if( othercut->row != row )
603  {
604  SCIP_ROW* otherrow = othercut->row;
605  SCIP_Real otherrhs;
606  SCIP_Real rhs;
607  SCIP_Real scale;
608  SCIP_Real otherscale;
609 
610  /* since we are comparing the improvement with an absolute value, we apply a
611  * scale to both rows such that the max absolute value is 1.0.
612  * Then bring the cut into the form ax <= b
613  */
614  scale = 1.0 / SCIProwGetMaxval(row, set);
615  otherscale = 1.0 / SCIProwGetMaxval(otherrow, set);
616 
617  if( SCIPsetIsInfinity(set, otherrow->rhs) )
618  {
619  otherrhs = otherscale * (otherrow->constant - otherrow->lhs);
620  }
621  else
622  {
623  otherrhs = otherscale * (otherrow->rhs - otherrow->constant);
624  }
625 
626  if( SCIPsetIsInfinity(set, row->rhs) )
627  {
628  rhs = scale * (row->constant - row->lhs);
629  }
630  else
631  {
632  rhs = scale * (row->rhs - row->constant);
633  }
634 
635  if( SCIPsetIsFeasLT(set, rhs, otherrhs) )
636  return TRUE;
637  }
638 
639  return FALSE;
640 }
641 
642 /** if not already existing, adds row to cut pool and captures it */
644  SCIP_CUTPOOL* cutpool, /**< cut pool */
645  BMS_BLKMEM* blkmem, /**< block memory */
646  SCIP_SET* set, /**< global SCIP settings */
647  SCIP_STAT* stat, /**< problem statistics data */
648  SCIP_LP* lp, /**< current LP data */
649  SCIP_ROW* row /**< cutting plane to add */
650  )
651 {
652  SCIP_CUT* othercut;
653  assert(cutpool != NULL);
654  assert(row != NULL);
655 
656  if( row->len == 0 )
657  return SCIP_OKAY;
658 
659  othercut = (SCIP_CUT*)SCIPhashtableRetrieve(cutpool->hashtable, (void*)row);
660  /* check in hash table, if cut already exists in the pool */
661  if( othercut == NULL )
662  {
663  SCIP_CALL( SCIPcutpoolAddNewRow(cutpool, blkmem, set, stat, lp, row) );
664  }
665  else
666  {
667  SCIP_ROW* otherrow = othercut->row;
668  SCIP_Real otherrhs;
669  SCIP_Real rhs;
670  SCIP_Real scale;
671  SCIP_Real otherscale;
672 
673  /* since we are comparing the improvement with an absolute value, we apply a
674  * scale to both rows such that the max absolute value is 1.0.
675  * Then bring the cut into the form ax <= b
676  */
677  scale = 1.0 / SCIProwGetMaxval(row, set);
678  otherscale = 1.0 / SCIProwGetMaxval(otherrow, set);
679 
680  if( SCIPsetIsInfinity(set, otherrow->rhs) )
681  {
682  otherrhs = otherscale * (otherrow->constant - otherrow->lhs);
683  }
684  else
685  {
686  otherrhs = otherscale * (otherrow->rhs - otherrow->constant);
687  }
688 
689  if( SCIPsetIsInfinity(set, row->rhs) )
690  {
691  rhs = scale * (row->constant - row->lhs);
692  }
693  else
694  {
695  rhs = scale * (row->rhs - row->constant);
696  }
697 
698  if( SCIPsetIsFeasLT(set, rhs, otherrhs) )
699  {
700  SCIP_CALL( cutpoolDelCut(cutpool, blkmem, set, stat, lp, othercut) );
701 
702  /* use recursion, since in rare cases new cut might compare equal to multiple other cuts
703  * that do not compare equal themselve due to non-transitivity of epsilon comparisons
704  */
705  SCIP_CALL( SCIPcutpoolAddRow(cutpool, blkmem, set, stat, lp, row) );
706  }
707  }
708 
709  return SCIP_OKAY;
710 }
711 
712 /** adds row to cut pool and captures it; doesn't check for multiple cuts */
714  SCIP_CUTPOOL* cutpool, /**< cut pool */
715  BMS_BLKMEM* blkmem, /**< block memory */
716  SCIP_SET* set, /**< global SCIP settings */
717  SCIP_STAT* stat, /**< problem statistics data */
718  SCIP_LP* lp, /**< current LP data */
719  SCIP_ROW* row /**< cutting plane to add */
720  )
721 {
722  SCIP_Real thisefficacy;
723  SCIP_CUT* cut;
724 
725  assert(cutpool != NULL);
726  assert(row != NULL);
727 
728  /* check, if row is modifiable or local */
729  if( SCIProwIsModifiable(row) )
730  {
731  SCIPerrorMessage("cannot store modifiable row <%s> in a cut pool\n", SCIProwGetName(row));
732  return SCIP_INVALIDDATA;
733  }
734  if( SCIProwIsLocal(row) )
735  {
736  SCIPerrorMessage("cannot store locally valid row <%s> in a cut pool\n", SCIProwGetName(row));
737  return SCIP_INVALIDDATA;
738  }
739 
740  assert(! row->inglobalcutpool);
741 
742  /* only called to ensure that minidx and maxidx are up-to-date */
743  (void) SCIProwGetMaxidx(row, set);
744  assert(row->validminmaxidx);
745 
746  /* create the cut */
747  SCIP_CALL( cutCreate(&cut, blkmem, row) );
748  cut->pos = cutpool->ncuts;
749 
750  /* add cut to the pool */
751  SCIP_CALL( cutpoolEnsureCutsMem(cutpool, set, cutpool->ncuts+1) );
752  cutpool->cuts[cutpool->ncuts] = cut;
753  cutpool->ncuts++;
754  cutpool->maxncuts = MAX(cutpool->maxncuts, cutpool->ncuts);
755  if( SCIProwIsRemovable(row) )
756  cutpool->nremovablecuts++;
757 
758  assert(!SCIPhashtableExists(cutpool->hashtable, (void*)cut));
759 
760  /* insert cut in the hash table */
761  SCIP_CALL( SCIPhashtableInsert(cutpool->hashtable, (void*)cut) );
762 
763  assert(SCIPhashtableExists(cutpool->hashtable, (void*)cut));
764 
766  {
767  thisefficacy = SCIProwGetLPEfficacy(row, set, stat, lp);
768  stat->bestefficacy = MAX(thisefficacy, stat->bestefficacy);
769  }
770 
771  /* if this is the global cut pool of SCIP, mark the row to be member of the pool */
772  if( cutpool->globalcutpool )
773  row->inglobalcutpool = TRUE;
774 
775  /* lock the row */
776  SCIProwLock(row);
777 
778  return SCIP_OKAY;
779 }
780 
781 /** removes the LP row from the cut pool */
783  SCIP_CUTPOOL* cutpool, /**< cut pool */
784  BMS_BLKMEM* blkmem, /**< block memory */
785  SCIP_SET* set, /**< global SCIP settings */
786  SCIP_STAT* stat, /**< problem statistics data */
787  SCIP_LP* lp, /**< current LP data */
788  SCIP_ROW* row /**< row to remove */
789  )
790 {
791  SCIP_CUT* cut;
792 
793  assert(cutpool != NULL);
794  assert(row != NULL);
795 
796  /* find the cut in hash table */
797  cut = (SCIP_CUT*)SCIPhashtableRetrieve(cutpool->hashtable, (void*)row);
798  if( cut == NULL )
799  {
800  SCIPerrorMessage("row <%s> is not existing in cutpool %p\n", SCIProwGetName(row), cutpool);
801  return SCIP_INVALIDDATA;
802  }
803 
804  SCIP_CALL( cutpoolDelCut(cutpool, blkmem, set, stat, lp, cut) );
805 
806  return SCIP_OKAY;
807 }
808 
809 
810 /** separates cuts of the cut pool */
812  SCIP_CUTPOOL* cutpool, /**< cut pool */
813  BMS_BLKMEM* blkmem, /**< block memory */
814  SCIP_SET* set, /**< global SCIP settings */
815  SCIP_STAT* stat, /**< problem statistics data */
816  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
817  SCIP_EVENTFILTER* eventfilter, /**< event filter for global events */
818  SCIP_LP* lp, /**< current LP data */
819  SCIP_SEPASTORE* sepastore, /**< separation storage */
820  SCIP_SOL* sol, /**< solution to be separated (or NULL for LP-solution) */
821  SCIP_Bool cutpoolisdelayed, /**< is the cutpool delayed (count cuts found)? */
822  SCIP_Bool root, /**< are we at the root node? */
823  SCIP_RESULT* result /**< pointer to store the result of the separation call */
824  )
825 {
826  SCIP_CUT* cut;
827  SCIP_Bool found;
828  SCIP_Bool cutoff;
829  SCIP_Real minefficacy;
830  SCIP_Bool retest;
831  int firstunproc;
832  int oldncuts;
833  int nefficaciouscuts;
834  int c;
835 
836  assert(cutpool != NULL);
837  assert(stat != NULL);
838  assert(cutpool->processedlp <= stat->lpcount);
839  assert(cutpool->processedlpsol <= stat->lpcount);
840  assert(cutpool->firstunprocessed <= cutpool->ncuts);
841  assert(cutpool->firstunprocessedsol <= cutpool->ncuts);
842  assert(result != NULL);
843 
844  *result = SCIP_DIDNOTRUN;
845 
846  /* don't separate cut pool in the root node, if there are no removable cuts */
847  if( root && cutpool->nremovablecuts == 0 )
848  return SCIP_OKAY;
849 
850  if ( sol == NULL )
851  {
852  if( cutpool->processedlp < stat->lpcount )
853  cutpool->firstunprocessed = 0;
854  if( cutpool->firstunprocessed == cutpool->ncuts )
855  return SCIP_OKAY;
856  firstunproc = cutpool->firstunprocessed;
857  }
858  else
859  {
860  if( cutpool->processedlpsol < stat->lpcount )
861  cutpool->firstunprocessedsol = 0;
862  if( cutpool->firstunprocessedsol == cutpool->ncuts )
863  return SCIP_OKAY;
864  firstunproc = cutpool->firstunprocessedsol;
865  }
866 
867  *result = SCIP_DIDNOTFIND;
868  cutpool->ncalls++;
869  found = FALSE;
870  minefficacy = stat->bestefficacy * stat->minefficacyfac;
871 
872  if( sol == NULL )
873  {
874  retest = cutpool->processedlpefficacy > minefficacy;
875  cutpool->processedlpefficacy = minefficacy;
876  }
877  else
878  {
879  retest = cutpool->processedlpsolefficacy > minefficacy;
880  cutpool->processedlpsolefficacy = minefficacy;
881  }
882 
883  SCIPsetDebugMsg(set, "separating%s cut pool %p with %d cuts, beginning with cut %d\n", ( sol == NULL ) ? "" : " solution from", (void*)cutpool, cutpool->ncuts, firstunproc);
884 
885  /* start timing */
886  SCIPclockStart(cutpool->poolclock, set);
887 
888  /* remember the current total number of found cuts */
889  oldncuts = SCIPsepastoreGetNCuts(sepastore);
890  nefficaciouscuts = 0;
891 
892  /* process all unprocessed cuts in the pool */
893  cutoff = FALSE;
894  for( c = firstunproc; c < cutpool->ncuts; ++c )
895  {
896  SCIP_Longint proclp;
897 
898  cut = cutpool->cuts[c];
899  assert(cut != NULL);
900  assert(cut->processedlp <= stat->lpcount);
901  assert(cut->processedlpsol <= stat->lpcount);
902  assert(cut->pos == c);
903 
904  proclp = ( sol == NULL ) ? cut->processedlp : cut->processedlpsol;
905 
906  if( retest || proclp < stat->lpcount )
907  {
908  SCIP_ROW* row;
909 
910  if ( sol == NULL )
911  cut->processedlp = stat->lpcount;
912  else
913  cut->processedlpsol = stat->lpcount;
914 
915  row = cut->row;
916  if( !SCIProwIsInLP(row) )
917  {
918  SCIP_Real efficacy;
919 
920  /* if the cut is a bound change (i.e. a row with only one variable), add it as bound change instead of LP
921  * row; hence, we want to remove the bound change cut from the SCIP cut pool
922  */
923  if( !SCIProwIsModifiable(row) && SCIProwGetNNonz(row) == 1 )
924  {
925  /* insert bound change cut into separation store which will force that cut */
926  SCIP_CALL( SCIPsepastoreAddCut(sepastore, blkmem, set, stat, eventqueue, eventfilter, lp, row, FALSE, root, &cutoff) );
927  SCIP_CALL( cutpoolDelCut(cutpool, blkmem, set, stat, lp, cut) );
928 
929  if ( cutoff )
930  break;
931 
932  continue;
933  }
934 
935  efficacy = sol == NULL ? SCIProwGetLPEfficacy(row, set, stat, lp) : SCIProwGetSolEfficacy(row, set, stat, sol);
936  if( SCIPsetIsFeasPositive(set, efficacy) )
937  ++nefficaciouscuts;
938 
939  if( efficacy >= minefficacy )
940  {
941  /* insert cut in separation storage */
942  SCIPsetDebugMsg(set, " -> separated cut <%s> from the cut pool (feasibility: %g)\n",
943  SCIProwGetName(row), ( sol == NULL ) ? SCIProwGetLPFeasibility(row, set, stat, lp) : SCIProwGetSolFeasibility(row, set, stat, sol) );
944  SCIP_CALL( SCIPsepastoreAddCut(sepastore, blkmem, set, stat, eventqueue, eventfilter, lp, row, FALSE, root, &cutoff) );
945 
946  /* count cuts */
947  if ( cutpoolisdelayed )
948  {
949  if ( SCIProwGetOriginSepa(row) != NULL )
950  {
951  SCIP_SEPA* sepa;
952 
953  sepa = SCIProwGetOriginSepa(row);
954  SCIPsepaIncNCutsFound(sepa);
956  }
957  else if ( SCIProwGetOriginCons(row) != NULL )
958  {
959  SCIP_CONSHDLR* conshdlr;
960 
961  conshdlr = SCIProwGetOriginCons(row);
962  SCIPconshdlrIncNCutsFound(conshdlr);
963  }
964  }
965 
966  found = TRUE;
967  cut->age = 0;
968 
969  if ( cutoff )
970  break;
971  }
972  else
973  {
974  cut->age++;
975  if( cutIsAged(cut, cutpool->agelimit) )
976  {
977  SCIP_CALL( cutpoolDelCut(cutpool, blkmem, set, stat, lp, cut) );
978  }
979  }
980  }
981  }
982  }
983 
984  if ( sol == NULL )
985  {
986  cutpool->processedlp = stat->lpcount;
987  cutpool->firstunprocessed = cutpool->ncuts;
988  }
989  else
990  {
991  cutpool->processedlpsol = stat->lpcount;
992  cutpool->firstunprocessedsol = cutpool->ncuts;
993  }
994 
995  if( nefficaciouscuts > 0 )
996  {
997  int maxncuts = SCIPsetGetSepaMaxcuts(set, root);
998  int ncuts = SCIPsepastoreGetNCuts(sepastore) - oldncuts;
999 
1000  maxncuts = MIN(maxncuts, nefficaciouscuts);
1001 
1002  /* update the number of found cuts */
1003  cutpool->ncutsfound += ncuts;
1004 
1005  if( ncuts > (0.5 * maxncuts) )
1006  {
1007  stat->ncutpoolfails = MIN(stat->ncutpoolfails - 1, -1);
1008  }
1009  else if( ncuts == 0 || (ncuts < (0.05 * maxncuts)) )
1010  {
1011  stat->ncutpoolfails = MAX(stat->ncutpoolfails + 1, 1);
1012  }
1013  }
1014 
1015  if( stat->ncutpoolfails == (root ? 2 : 10) )
1016  {
1017  cutpool->firstunprocessed = 0;
1018  cutpool->firstunprocessedsol = 0;
1019  stat->minefficacyfac *= 0.5;
1020  stat->ncutpoolfails = 0;
1021  }
1022  else if( stat->ncutpoolfails == -2 )
1023  {
1024  stat->minefficacyfac *= 1.2;
1025  stat->ncutpoolfails = 0;
1026  }
1027 
1028  /* stop timing */
1029  SCIPclockStop(cutpool->poolclock, set);
1030 
1031  if ( cutoff )
1032  *result = SCIP_CUTOFF;
1033  else if( found )
1034  *result = SCIP_SEPARATED;
1035 
1036  return SCIP_OKAY;
1037 }
1038 
1039 /** gets array of cuts in the cut pool */
1041  SCIP_CUTPOOL* cutpool /**< cut pool */
1042  )
1043 {
1044  assert(cutpool != NULL);
1045 
1046  return cutpool->cuts;
1047 }
1048 
1049 /** gets number of cuts in the cut pool */
1051  SCIP_CUTPOOL* cutpool /**< cut pool */
1052  )
1053 {
1054  assert(cutpool != NULL);
1055 
1056  return cutpool->ncuts;
1057 }
1058 
1059 /** gets maximum number of cuts that were stored in the cut pool at the same time */
1061  SCIP_CUTPOOL* cutpool /**< cut pool */
1062  )
1063 {
1064  assert(cutpool != NULL);
1065 
1066  return cutpool->maxncuts;
1067 }
1068 
1069 /** gets time in seconds used for separating cuts from the pool */
1071  SCIP_CUTPOOL* cutpool /**< cut pool */
1072  )
1073 {
1074  assert(cutpool != NULL);
1075 
1076  return SCIPclockGetTime(cutpool->poolclock);
1077 }
1078 
1079 /** get number of times, the cut pool was separated */
1081  SCIP_CUTPOOL* cutpool /**< cut pool */
1082  )
1083 {
1084  assert(cutpool != NULL);
1085 
1086  return cutpool->ncalls;
1087 }
1088 
1089 /** get total number of cuts that were separated from the cut pool */
1091  SCIP_CUTPOOL* cutpool /**< cut pool */
1092  )
1093 {
1094  assert(cutpool != NULL);
1095 
1096  return cutpool->ncutsfound;
1097 }
1098 
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
SCIP_Longint SCIProwGetActiveLPCount(SCIP_ROW *row)
Definition: lp.c:17199
internal methods for separators
SCIP_ROW * row
int nunlinked
Definition: struct_lp.h:228
SCIP_Real SCIProwGetSolFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6415
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:17075
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:5953
int SCIProwGetMaxidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6610
#define NULL
Definition: def.h:253
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2364
SCIP_HASHTABLE * hashtable
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:138
#define SCIP_HASHSIZE_CUTPOOLS
Definition: def.h:285
SCIP_Longint processedlp
SCIP_Real SCIProwGetMinval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6594
int * cols_index
Definition: struct_lp.h:219
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6351
SCIP_CUT ** cuts
SCIP_Bool SCIProwIsRemovable(SCIP_ROW *row)
Definition: lp.c:17095
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2476
internal methods for clocks and timing issues
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
Definition: misc.c:2425
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:16887
void SCIProwCapture(SCIP_ROW *row)
Definition: lp.c:5246
int SCIPcutpoolGetMaxNCuts(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1060
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:350
#define FALSE
Definition: def.h:73
SCIP_Longint processedlpsol
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:280
#define TRUE
Definition: def.h:72
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6715
SCIP_RETCODE SCIPcutpoolAddNewRow(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_ROW *row)
Definition: cutpool.c:713
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5503
void SCIPsepaIncNCutsFoundAtNode(SCIP_SEPA *sepa)
Definition: sepa.c:883
SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2494
int SCIPcutpoolGetNCuts(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1050
SCIP_Real processedlpefficacy
static SCIP_RETCODE cutpoolDelCut(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_CUT *cut)
Definition: cutpool.c:510
static SCIP_RETCODE cutFree(SCIP_CUT **cut, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: cutpool.c:337
#define BMSfreeMemory(ptr)
Definition: memory.h:135
SCIP_Longint processedlp
SCIP_RETCODE SCIPcutpoolFree(SCIP_CUTPOOL **cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: cutpool.c:456
int nlpcols
Definition: struct_lp.h:227
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:12902
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:17085
internal methods for LP management
SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
Definition: misc.c:2113
int SCIPsetGetSepaMaxcuts(SCIP_SET *set, SCIP_Bool root)
Definition: set.c:5681
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17177
int ncutpoolfails
Definition: struct_stat.h:203
SCIP_Real * vals
Definition: struct_lp.h:220
SCIP_Real SCIPcutGetLPActivityQuot(SCIP_CUT *cut)
Definition: cutpool.c:396
SCIP_RETCODE SCIPcutpoolDelRow(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_ROW *row)
Definition: cutpool.c:782
#define SCIPerrorMessage
Definition: pub_message.h:45
SCIP_Longint lpcount
Definition: struct_stat.h:174
static SCIP_RETCODE cutCreate(SCIP_CUT **cut, BMS_BLKMEM *blkmem, SCIP_ROW *row)
Definition: cutpool.c:311
SCIP_CONSHDLR * SCIProwGetOriginCons(SCIP_ROW *row)
Definition: lp.c:17115
SCIP_COL ** cols
Definition: struct_lp.h:218
SCIP_Real SCIPcutpoolGetTime(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1070
static INLINE uint32_t SCIPrealHashCode(double x)
Definition: pub_misc.h:509
static SCIP_DECL_HASHKEYVAL(hashKeyValCut)
Definition: cutpool.c:245
SCIP_Real lhs
Definition: struct_lp.h:195
SCIP_Longint processedlpsol
int SCIPsepastoreGetNCuts(SCIP_SEPASTORE *sepastore)
Definition: sepastore.c:1086
SCIP_Real SCIPclockGetTime(SCIP_CLOCK *clck)
Definition: clock.c:428
datastructures for storing cuts in a cut pool
int maxidx
Definition: struct_lp.h:234
SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
Definition: lp.c:17209
SCIP_Longint SCIPcutpoolGetNCutsFound(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1090
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:365
#define SCIPhashTwo(a, b)
Definition: pub_misc.h:493
SCIP_Real processedlpsolefficacy
SCIP_RETCODE SCIPcutpoolClear(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: cutpool.c:482
Definition: grphload.c:88
SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
Definition: lp.c:17130
internal methods for storing separated cuts
SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5259
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:160
void SCIPconshdlrIncNCutsFound(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4877
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:454
SCIP_Real bestefficacy
Definition: struct_stat.h:141
public data structures and miscellaneous methods
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2163
#define SCIP_Bool
Definition: def.h:70
SCIP_Real minefficacyfac
Definition: struct_stat.h:142
SCIP_Bool SCIPcutpoolIsCutNew(SCIP_CUTPOOL *cutpool, SCIP_SET *set, SCIP_ROW *row)
Definition: cutpool.c:580
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:175
SCIP_CUT ** SCIPcutpoolGetCuts(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1040
#define SCIP_HASHSIZE_CUTPOOLS_SMALL
Definition: def.h:288
#define MIN(x, y)
Definition: def.h:223
#define SCIPsetDebugMsg
Definition: set.h:1720
int minidx
Definition: struct_lp.h:233
SCIP_RETCODE SCIPcutpoolCreate(SCIP_CUTPOOL **cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, int agelimit, SCIP_Bool globalcutpool)
Definition: cutpool.c:417
int SCIPcutGetAge(SCIP_CUT *cut)
Definition: cutpool.c:382
unsigned int lpcolssorted
Definition: struct_lp.h:241
internal methods for storing cuts in a cut pool
SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6772
int firstunprocessedsol
void SCIProwSort(SCIP_ROW *row)
Definition: lp.c:5923
SCIP_CLOCK * poolclock
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6373
SCIP_Real rhs
Definition: struct_lp.h:196
SCIP_Real constant
Definition: struct_lp.h:194
SCIP_Longint ncalls
#define MAX(x, y)
Definition: def.h:222
unsigned int inglobalcutpool
Definition: struct_lp.h:252
public methods for message output
SCIP_Longint ncutsfound
SCIP_Real SCIProwGetLPFeasibility(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6161
#define SCIP_Real
Definition: def.h:164
internal methods for problem statistics
void SCIProwUnlock(SCIP_ROW *row)
Definition: lp.c:5300
SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6472
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:17025
#define BMSallocMemory(ptr)
Definition: memory.h:109
#define SCIP_INVALID
Definition: def.h:184
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:117
internal methods for constraints and constraint handlers
void SCIPsepaIncNCutsFound(SCIP_SEPA *sepa)
Definition: sepa.c:873
SCIP_RETCODE SCIPcutpoolAddRow(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_ROW *row)
Definition: cutpool.c:643
SCIP_ROW * SCIPcutGetRow(SCIP_CUT *cut)
Definition: cutpool.c:372
SCIP_RETCODE SCIPcutpoolSeparate(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_LP *lp, SCIP_SEPASTORE *sepastore, SCIP_SOL *sol, SCIP_Bool cutpoolisdelayed, SCIP_Bool root, SCIP_RESULT *result)
Definition: cutpool.c:811
#define SCIP_Longint
Definition: def.h:149
SCIP_Longint SCIPcutpoolGetNCalls(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1080
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6417
SCIP_Real SCIProwGetMaxval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6578
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:441
SCIP_Bool globalcutpool
common defines and data types used in all packages of SCIP
void SCIProwLock(SCIP_ROW *row)
Definition: lp.c:5285
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:427
unsigned int validminmaxidx
Definition: struct_lp.h:244
#define SCIP_ALLOC(x)
Definition: def.h:376
unsigned int nonlpcolssorted
Definition: struct_lp.h:242
static SCIP_Bool cutIsAged(SCIP_CUT *cut, int agelimit)
Definition: cutpool.c:360
static SCIP_DECL_HASHGETKEY(hashGetKeyCut)
Definition: cutpool.c:51
static SCIP_DECL_HASHKEYEQ(hashKeyEqCut)
Definition: cutpool.c:65
static SCIP_RETCODE cutpoolEnsureCutsMem(SCIP_CUTPOOL *cutpool, SCIP_SET *set, int num)
Definition: cutpool.c:281
SCIP_RETCODE SCIPsepastoreAddCut(SCIP_SEPASTORE *sepastore, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_EVENTQUEUE *eventqueue, SCIP_EVENTFILTER *eventfilter, SCIP_LP *lp, SCIP_ROW *cut, SCIP_Bool forcecut, SCIP_Bool root, SCIP_Bool *infeasible)
Definition: sepastore.c:400
int len
Definition: struct_lp.h:226
int age
Definition: struct_lp.h:238