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