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-2022 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)->nrootcalls = 0;
451  (*cutpool)->ncutsfound = 0;
452  (*cutpool)->ncutsadded = 0;
453  (*cutpool)->globalcutpool = globalcutpool;
454 
455  return SCIP_OKAY;
456 }
457 
458 /** frees cut pool */
460  SCIP_CUTPOOL** cutpool, /**< pointer to store cut pool */
461  BMS_BLKMEM* blkmem, /**< block memory */
462  SCIP_SET* set, /**< global SCIP settings */
463  SCIP_LP* lp /**< current LP data */
464  )
465 {
466  assert(cutpool != NULL);
467  assert(*cutpool != NULL);
468 
469  /* remove all cuts from the pool */
470  SCIP_CALL( SCIPcutpoolClear(*cutpool, blkmem, set, lp) );
471 
472  /* free clock */
473  SCIPclockFree(&(*cutpool)->poolclock);
474 
475  /* free hash table */
476  SCIPhashtableFree(&(*cutpool)->hashtable);
477 
478  BMSfreeMemoryArrayNull(&(*cutpool)->cuts);
479  BMSfreeMemory(cutpool);
480 
481  return SCIP_OKAY;
482 }
483 
484 /** removes all rows from the cut pool */
486  SCIP_CUTPOOL* cutpool, /**< cut pool */
487  BMS_BLKMEM* blkmem, /**< block memory */
488  SCIP_SET* set, /**< global SCIP settings */
489  SCIP_LP* lp /**< current LP data */
490  )
491 {
492  int i;
493 
494  assert(cutpool != NULL);
495 
496  /* free cuts */
498  for( i = 0; i < cutpool->ncuts; ++i )
499  {
500  if( cutpool->globalcutpool )
501  cutpool->cuts[i]->row->inglobalcutpool = FALSE;
502  SCIProwUnlock(cutpool->cuts[i]->row);
503  SCIP_CALL( cutFree(&cutpool->cuts[i], blkmem, set, lp) );
504  }
505 
506  cutpool->ncuts = 0;
507  cutpool->nremovablecuts = 0;
508 
509  return SCIP_OKAY;
510 }
511 
512 /** removes the cut from the cut pool */
513 static
515  SCIP_CUTPOOL* cutpool, /**< cut pool */
516  BMS_BLKMEM* blkmem, /**< block memory */
517  SCIP_SET* set, /**< global SCIP settings */
518  SCIP_STAT* stat, /**< problem statistics data */
519  SCIP_LP* lp, /**< current LP data */
520  SCIP_CUT* cut /**< cut to remove */
521  )
522 {
523  int pos;
524 
525  assert(cutpool != NULL);
526  assert(cutpool->firstunprocessed <= cutpool->ncuts);
527  assert(cutpool->firstunprocessedsol <= cutpool->ncuts);
528  assert(blkmem != NULL);
529  assert(stat != NULL);
530  assert(cutpool->processedlp <= stat->lpcount);
531  assert(cutpool->processedlpsol <= stat->lpcount);
532  assert(cut != NULL);
533  assert(cut->row != NULL);
534 
535  pos = cut->pos;
536  assert(0 <= pos && pos < cutpool->ncuts);
537  assert(cutpool->cuts[pos] == cut);
538 
539  /* decrease the number of removable cuts counter (row might have changed its removable status -> counting might not
540  * be correct
541  */
542  if( SCIProwIsRemovable(cut->row) && cutpool->nremovablecuts > 0 )
543  cutpool->nremovablecuts--;
544 
545  /* if this is the global cut pool of SCIP, mark the row to not be member anymore */
546  if( cutpool->globalcutpool )
547  {
548  assert(cut->row->inglobalcutpool);
549  cut->row->inglobalcutpool = FALSE;
550  }
551 
552  /* remove the cut from the hash table */
553  assert(SCIPhashtableExists(cutpool->hashtable, (void*)cut));
554  SCIP_CALL( SCIPhashtableRemove(cutpool->hashtable, (void*)cut) );
555  assert(! SCIPhashtableExists(cutpool->hashtable, (void*)cut));
556 
557  /* unlock the row */
558  SCIProwUnlock(cut->row);
559 
560  /* free the cut */
561  SCIP_CALL( cutFree(&cutpool->cuts[pos], blkmem, set, lp) );
562 
563  --cutpool->ncuts;
564  cutpool->firstunprocessed = MIN(cutpool->firstunprocessed, cutpool->ncuts);
565  cutpool->firstunprocessedsol = MIN(cutpool->firstunprocessedsol, cutpool->ncuts);
566 
567  /* move the last cut of the pool to the free position */
568  if( pos < cutpool->ncuts )
569  {
570  cutpool->cuts[pos] = cutpool->cuts[cutpool->ncuts];
571  cutpool->cuts[pos]->pos = pos;
572  assert(cutpool->cuts[pos]->processedlp <= stat->lpcount);
573  assert(cutpool->cuts[pos]->processedlpsol <= stat->lpcount);
574  if( cutpool->cuts[pos]->processedlp < stat->lpcount )
575  cutpool->firstunprocessed = MIN(cutpool->firstunprocessed, pos);
576  if( cutpool->cuts[pos]->processedlpsol < stat->lpcount )
577  cutpool->firstunprocessedsol = MIN(cutpool->firstunprocessedsol, pos);
578  }
579 
580  return SCIP_OKAY;
581 }
582 
583 /** checks if cut is already existing */
585  SCIP_CUTPOOL* cutpool, /**< cut pool */
586  SCIP_SET* set, /**< global SCIP settings */
587  SCIP_ROW* row /**< cutting plane to add */
588  )
589 {
590  SCIP_CUT* othercut;
591  assert(cutpool != NULL);
592  assert(row != NULL);
593 
594  if( row->len == 0 )
595  {
596  /* trivial cut is only new if it proves infeasibility */
597  return SCIPsetIsFeasLT(set, row->constant, row->lhs) || SCIPsetIsFeasGT(set, row->constant, row->rhs);
598  }
599 
600  othercut = (SCIP_CUT*)SCIPhashtableRetrieve(cutpool->hashtable, (void*)row);
601  /* check in hash table, if cut already exists in the pool */
602  if( othercut == NULL )
603  {
604  return TRUE;
605  }
606  else if( othercut->row != row )
607  {
608  SCIP_ROW* otherrow = othercut->row;
609  SCIP_Real otherrhs;
610  SCIP_Real rhs;
611  SCIP_Real scale;
612  SCIP_Real otherscale;
613 
614  /* since we are comparing the improvement with an absolute value, we apply a
615  * scale to both rows such that the max absolute value is 1.0.
616  * Then bring the cut into the form ax <= b
617  */
618  scale = 1.0 / SCIProwGetMaxval(row, set);
619  otherscale = 1.0 / SCIProwGetMaxval(otherrow, set);
620 
621  if( SCIPsetIsInfinity(set, otherrow->rhs) )
622  {
623  otherrhs = otherscale * (otherrow->constant - otherrow->lhs);
624  }
625  else
626  {
627  otherrhs = otherscale * (otherrow->rhs - otherrow->constant);
628  }
629 
630  if( SCIPsetIsInfinity(set, row->rhs) )
631  {
632  rhs = scale * (row->constant - row->lhs);
633  }
634  else
635  {
636  rhs = scale * (row->rhs - row->constant);
637  }
638 
639  if( SCIPsetIsFeasLT(set, rhs, otherrhs) )
640  return TRUE;
641  }
642 
643  return FALSE;
644 }
645 
646 /** if not already existing, adds row to cut pool and captures it */
648  SCIP_CUTPOOL* cutpool, /**< cut pool */
649  BMS_BLKMEM* blkmem, /**< block memory */
650  SCIP_SET* set, /**< global SCIP settings */
651  SCIP_STAT* stat, /**< problem statistics data */
652  SCIP_LP* lp, /**< current LP data */
653  SCIP_ROW* row /**< cutting plane to add */
654  )
655 {
656  SCIP_CUT* othercut;
657  assert(cutpool != NULL);
658  assert(row != NULL);
659 
660  if( row->len == 0 )
661  return SCIP_OKAY;
662 
663  othercut = (SCIP_CUT*)SCIPhashtableRetrieve(cutpool->hashtable, (void*)row);
664  /* check in hash table, if cut already exists in the pool */
665  if( othercut == NULL )
666  {
667  SCIP_CALL( SCIPcutpoolAddNewRow(cutpool, blkmem, set, stat, lp, row) );
668  }
669  else
670  {
671  SCIP_ROW* otherrow = othercut->row;
672  SCIP_Real otherrhs;
673  SCIP_Real rhs;
674  SCIP_Real scale;
675  SCIP_Real otherscale;
676 
677  /* since we are comparing the improvement with an absolute value, we apply a
678  * scale to both rows such that the max absolute value is 1.0.
679  * Then bring the cut into the form ax <= b
680  */
681  scale = 1.0 / SCIProwGetMaxval(row, set);
682  otherscale = 1.0 / SCIProwGetMaxval(otherrow, set);
683 
684  if( SCIPsetIsInfinity(set, otherrow->rhs) )
685  {
686  otherrhs = otherscale * (otherrow->constant - otherrow->lhs);
687  }
688  else
689  {
690  otherrhs = otherscale * (otherrow->rhs - otherrow->constant);
691  }
692 
693  if( SCIPsetIsInfinity(set, row->rhs) )
694  {
695  rhs = scale * (row->constant - row->lhs);
696  }
697  else
698  {
699  rhs = scale * (row->rhs - row->constant);
700  }
701 
702  if( SCIPsetIsFeasLT(set, rhs, otherrhs) )
703  {
704  SCIP_CALL( cutpoolDelCut(cutpool, blkmem, set, stat, lp, othercut) );
705 
706  /* use recursion, since in rare cases new cut might compare equal to multiple other cuts
707  * that do not compare equal themselve due to non-transitivity of epsilon comparisons
708  */
709  SCIP_CALL( SCIPcutpoolAddRow(cutpool, blkmem, set, stat, lp, row) );
710  }
711  }
712 
713  return SCIP_OKAY;
714 }
715 
716 /** adds row to cut pool and captures it; doesn't check for multiple cuts */
718  SCIP_CUTPOOL* cutpool, /**< cut pool */
719  BMS_BLKMEM* blkmem, /**< block memory */
720  SCIP_SET* set, /**< global SCIP settings */
721  SCIP_STAT* stat, /**< problem statistics data */
722  SCIP_LP* lp, /**< current LP data */
723  SCIP_ROW* row /**< cutting plane to add */
724  )
725 {
726  SCIP_Real thisefficacy;
727  SCIP_CUT* cut;
728 
729  assert(cutpool != NULL);
730  assert(row != NULL);
731 
732  /* check, if row is modifiable or local */
733  if( SCIProwIsModifiable(row) )
734  {
735  SCIPerrorMessage("cannot store modifiable row <%s> in a cut pool\n", SCIProwGetName(row));
736  return SCIP_INVALIDDATA;
737  }
738  if( SCIProwIsLocal(row) )
739  {
740  SCIPerrorMessage("cannot store locally valid row <%s> in a cut pool\n", SCIProwGetName(row));
741  return SCIP_INVALIDDATA;
742  }
743 
744  assert(! row->inglobalcutpool);
745 
746  /* only called to ensure that minidx and maxidx are up-to-date */
747  (void) SCIProwGetMaxidx(row, set);
748  assert(row->validminmaxidx);
749 
750  /* create the cut */
751  SCIP_CALL( cutCreate(&cut, blkmem, row) );
752  cut->pos = cutpool->ncuts;
753 
754  /* add cut to the pool */
755  SCIP_CALL( cutpoolEnsureCutsMem(cutpool, set, cutpool->ncuts+1) );
756  cutpool->cuts[cutpool->ncuts] = cut;
757  cutpool->ncuts++;
758  cutpool->ncutsfound++;
759  cutpool->maxncuts = MAX(cutpool->maxncuts, cutpool->ncuts);
760  if( SCIProwIsRemovable(row) )
761  cutpool->nremovablecuts++;
762 
763  assert(!SCIPhashtableExists(cutpool->hashtable, (void*)cut));
764 
765  /* insert cut in the hash table */
766  SCIP_CALL( SCIPhashtableInsert(cutpool->hashtable, (void*)cut) );
767 
768  assert(SCIPhashtableExists(cutpool->hashtable, (void*)cut));
769 
771  {
772  thisefficacy = SCIProwGetLPEfficacy(row, set, stat, lp);
773  stat->bestefficacy = MAX(thisefficacy, stat->bestefficacy);
774  }
775 
776  /* if this is the global cut pool of SCIP, mark the row to be member of the pool */
777  if( cutpool->globalcutpool )
778  row->inglobalcutpool = TRUE;
779 
780  /* lock the row */
781  SCIProwLock(row);
782 
783  return SCIP_OKAY;
784 }
785 
786 /** removes the LP row from the cut pool */
788  SCIP_CUTPOOL* cutpool, /**< cut pool */
789  BMS_BLKMEM* blkmem, /**< block memory */
790  SCIP_SET* set, /**< global SCIP settings */
791  SCIP_STAT* stat, /**< problem statistics data */
792  SCIP_LP* lp, /**< current LP data */
793  SCIP_ROW* row /**< row to remove */
794  )
795 {
796  SCIP_CUT* cut;
797 
798  assert(cutpool != NULL);
799  assert(row != NULL);
800 
801  /* find the cut in hash table */
802  cut = (SCIP_CUT*)SCIPhashtableRetrieve(cutpool->hashtable, (void*)row);
803  if( cut == NULL )
804  {
805  SCIPerrorMessage("row <%s> is not existing in cutpool %p\n", SCIProwGetName(row), (void*)cutpool);
806  return SCIP_INVALIDDATA;
807  }
808 
809  SCIP_CALL( cutpoolDelCut(cutpool, blkmem, set, stat, lp, cut) );
810 
811  return SCIP_OKAY;
812 }
813 
814 
815 /** separates cuts of the cut pool */
817  SCIP_CUTPOOL* cutpool, /**< cut pool */
818  BMS_BLKMEM* blkmem, /**< block memory */
819  SCIP_SET* set, /**< global SCIP settings */
820  SCIP_STAT* stat, /**< problem statistics data */
821  SCIP_EVENTQUEUE* eventqueue, /**< event queue */
822  SCIP_EVENTFILTER* eventfilter, /**< event filter for global events */
823  SCIP_LP* lp, /**< current LP data */
824  SCIP_SEPASTORE* sepastore, /**< separation storage */
825  SCIP_SOL* sol, /**< solution to be separated (or NULL for LP-solution) */
826  SCIP_Bool cutpoolisdelayed, /**< is the cutpool delayed (count cuts found)? */
827  SCIP_Bool root, /**< are we at the root node? */
828  SCIP_RESULT* result /**< pointer to store the result of the separation call */
829  )
830 {
831  SCIP_CUT* cut;
832  SCIP_Bool found;
833  SCIP_Bool cutoff;
834  SCIP_Real minefficacy;
835  SCIP_Bool retest;
836  int firstunproc;
837  int oldncutsadded;
838  int oldncutsfound;
839  int nefficaciouscuts;
840  int c;
841 
842  assert(cutpool != NULL);
843  assert(stat != NULL);
844  assert(cutpool->processedlp <= stat->lpcount);
845  assert(cutpool->processedlpsol <= stat->lpcount);
846  assert(cutpool->firstunprocessed <= cutpool->ncuts);
847  assert(cutpool->firstunprocessedsol <= cutpool->ncuts);
848  assert(result != NULL);
849 
850  *result = SCIP_DIDNOTRUN;
851 
852  /* don't separate cut pool in the root node, if there are no removable cuts */
853  if( root && cutpool->nremovablecuts == 0 )
854  return SCIP_OKAY;
855 
856  if ( sol == NULL )
857  {
858  if( cutpool->processedlp < stat->lpcount )
859  cutpool->firstunprocessed = 0;
860  if( cutpool->firstunprocessed == cutpool->ncuts )
861  return SCIP_OKAY;
862  firstunproc = cutpool->firstunprocessed;
863  }
864  else
865  {
866  if( cutpool->processedlpsol < stat->lpcount )
867  cutpool->firstunprocessedsol = 0;
868  if( cutpool->firstunprocessedsol == cutpool->ncuts )
869  return SCIP_OKAY;
870  firstunproc = cutpool->firstunprocessedsol;
871  }
872 
873  *result = SCIP_DIDNOTFIND;
874  cutpool->ncalls++;
875  if( root )
876  cutpool->nrootcalls++;
877  found = FALSE;
878  if( set->sepa_filtercutpoolrel )
879  minefficacy = stat->bestefficacy * stat->minefficacyfac;
880  else
881  minefficacy = root ? set->sepa_minefficacyroot : set->sepa_minefficacy;
882 
883  if( sol == NULL )
884  {
885  retest = cutpool->processedlpefficacy > minefficacy;
886  cutpool->processedlpefficacy = minefficacy;
887  }
888  else
889  {
890  retest = cutpool->processedlpsolefficacy > minefficacy;
891  cutpool->processedlpsolefficacy = minefficacy;
892  }
893 
894  SCIPsetDebugMsg(set, "separating%s cut pool %p with %d cuts, beginning with cut %d\n", ( sol == NULL ) ? "" : " solution from", (void*)cutpool, cutpool->ncuts, firstunproc);
895 
896  /* start timing */
897  SCIPclockStart(cutpool->poolclock, set);
898 
899  /* remember the current total number of found cuts */
900  oldncutsfound = SCIPsepastoreGetNCuts(sepastore);
901  oldncutsadded = SCIPsepastoreGetNCutsAdded(sepastore);
902  nefficaciouscuts = 0;
903 
904  /* process all unprocessed cuts in the pool */
905  cutoff = FALSE;
906  for( c = firstunproc; c < cutpool->ncuts; ++c )
907  {
908  SCIP_Longint proclp;
909 
910  cut = cutpool->cuts[c];
911  assert(cut != NULL);
912  assert(cut->processedlp <= stat->lpcount);
913  assert(cut->processedlpsol <= stat->lpcount);
914  assert(cut->pos == c);
915 
916  proclp = ( sol == NULL ) ? cut->processedlp : cut->processedlpsol;
917 
918  if( retest || proclp < stat->lpcount )
919  {
920  SCIP_ROW* row;
921 
922  if ( sol == NULL )
923  cut->processedlp = stat->lpcount;
924  else
925  cut->processedlpsol = stat->lpcount;
926 
927  row = cut->row;
928  if( !SCIProwIsInLP(row) )
929  {
930  SCIP_Real efficacy;
931 
932  /* if the cut is a bound change (i.e. a row with only one variable), add it as bound change instead of LP
933  * row; hence, we want to remove the bound change cut from the SCIP cut pool
934  */
935  if( !SCIProwIsModifiable(row) && SCIProwGetNNonz(row) == 1 )
936  {
937  /* insert bound change cut into separation store which will force that cut;
938  * fromcutpool is set for consistency.
939  */
940  row->fromcutpool = TRUE;
941  SCIP_CALL( SCIPsepastoreAddCut(sepastore, blkmem, set, stat, eventqueue, eventfilter, lp, row, FALSE, root, &cutoff) );
942  SCIP_CALL( cutpoolDelCut(cutpool, blkmem, set, stat, lp, cut) );
943 
944  if ( cutoff )
945  break;
946 
947  continue;
948  }
949 
950  efficacy = sol == NULL ? SCIProwGetLPEfficacy(row, set, stat, lp) : SCIProwGetSolEfficacy(row, set, stat, sol);
951  if( SCIPsetIsFeasPositive(set, efficacy) )
952  ++nefficaciouscuts;
953 
954  if( efficacy >= minefficacy )
955  {
956  /* insert cut in separation storage */
957  row->fromcutpool = TRUE;
958  SCIPsetDebugMsg(set, " -> separated cut <%s> from the cut pool (feasibility: %g)\n",
959  SCIProwGetName(row), ( sol == NULL ) ? SCIProwGetLPFeasibility(row, set, stat, lp) : SCIProwGetSolFeasibility(row, set, stat, sol) );
960  SCIP_CALL( SCIPsepastoreAddCut(sepastore, blkmem, set, stat, eventqueue, eventfilter, lp, row, FALSE, root, &cutoff) );
961 
962  /* count cuts */
963  if ( cutpoolisdelayed )
964  {
965  if ( SCIProwGetOriginSepa(row) != NULL )
966  {
967  SCIP_SEPA* sepa;
968 
969  sepa = SCIProwGetOriginSepa(row);
972  }
973  else if ( SCIProwGetOriginConshdlr(row) != NULL )
974  {
975  SCIP_CONSHDLR* conshdlr;
976 
977  conshdlr = SCIProwGetOriginConshdlr(row);
978  SCIPconshdlrIncNCutsFound(conshdlr);
979  }
980  }
981 
982  found = TRUE;
983  cut->age = 0;
984 
985  if ( cutoff )
986  break;
987  }
988  else
989  {
990  cut->age++;
991  if( cutIsAged(cut, cutpool->agelimit) )
992  {
993  SCIP_CALL( cutpoolDelCut(cutpool, blkmem, set, stat, lp, cut) );
994  }
995  }
996  }
997  }
998  }
999 
1000  if ( sol == NULL )
1001  {
1002  cutpool->processedlp = stat->lpcount;
1003  cutpool->firstunprocessed = cutpool->ncuts;
1004  }
1005  else
1006  {
1007  cutpool->processedlpsol = stat->lpcount;
1008  cutpool->firstunprocessedsol = cutpool->ncuts;
1009  }
1010  /* update the number of found and added cuts */
1011  cutpool->ncutsadded += SCIPsepastoreGetNCutsAdded(sepastore) - oldncutsadded; /*lint !e776*/
1012 
1013  /* check whether efficacy threshold should be tightened or relaxed */
1014  if( set->sepa_filtercutpoolrel && nefficaciouscuts > 0 )
1015  {
1016  int maxncuts = SCIPsetGetSepaMaxcuts(set, root);
1017  int ncuts = SCIPsepastoreGetNCuts(sepastore) - oldncutsfound;
1018 
1019  maxncuts = MIN(maxncuts, nefficaciouscuts);
1020 
1021  if( ncuts > (0.5 * maxncuts) )
1022  {
1023  stat->ncutpoolfails = MIN(stat->ncutpoolfails - 1, -1);
1024  }
1025  else if( ncuts == 0 || (ncuts < (0.05 * maxncuts)) )
1026  {
1027  stat->ncutpoolfails = MAX(stat->ncutpoolfails + 1, 1);
1028  }
1029 
1030  if( stat->ncutpoolfails == (root ? 2 : 10) )
1031  {
1032  cutpool->firstunprocessed = 0;
1033  cutpool->firstunprocessedsol = 0;
1034  stat->minefficacyfac *= 0.5;
1035  stat->ncutpoolfails = 0;
1036  }
1037  else if( stat->ncutpoolfails == -2 )
1038  {
1039  stat->minefficacyfac *= 1.2;
1040  stat->ncutpoolfails = 0;
1041  }
1042  }
1043 
1044  /* stop timing */
1045  SCIPclockStop(cutpool->poolclock, set);
1046 
1047  if ( cutoff )
1048  *result = SCIP_CUTOFF;
1049  else if( found )
1050  *result = SCIP_SEPARATED;
1051 
1052  return SCIP_OKAY;
1053 }
1054 
1055 /** gets array of cuts in the cut pool */
1057  SCIP_CUTPOOL* cutpool /**< cut pool */
1058  )
1059 {
1060  assert(cutpool != NULL);
1061 
1062  return cutpool->cuts;
1063 }
1064 
1065 /** gets number of cuts in the cut pool */
1067  SCIP_CUTPOOL* cutpool /**< cut pool */
1068  )
1069 {
1070  assert(cutpool != NULL);
1071 
1072  return cutpool->ncuts;
1073 }
1074 
1075 /** gets maximum number of cuts that were stored in the cut pool at the same time */
1077  SCIP_CUTPOOL* cutpool /**< cut pool */
1078  )
1079 {
1080  assert(cutpool != NULL);
1081 
1082  return cutpool->maxncuts;
1083 }
1084 
1085 /** gets time in seconds used for separating cuts from the pool */
1087  SCIP_CUTPOOL* cutpool /**< cut pool */
1088  )
1089 {
1090  assert(cutpool != NULL);
1091 
1092  return SCIPclockGetTime(cutpool->poolclock);
1093 }
1094 
1095 /** get number of times the cut pool was separated */
1097  SCIP_CUTPOOL* cutpool /**< cut pool */
1098  )
1099 {
1100  assert(cutpool != NULL);
1101 
1102  return cutpool->ncalls;
1103 }
1104 
1105 /** get number of times the cut pool was separated at the root */
1107  SCIP_CUTPOOL* cutpool /**< cut pool */
1108  )
1109 {
1110  assert(cutpool != NULL);
1111 
1112  return cutpool->nrootcalls;
1113 }
1114 
1115 /** get total number of cuts that were added to the cut pool */
1117  SCIP_CUTPOOL* cutpool /**< cut pool */
1118  )
1119 {
1120  assert(cutpool != NULL);
1121 
1122  return cutpool->ncutsfound;
1123 }
1124 
1125 /** get total number of cuts that were added from the cut pool to sepastore */
1127  SCIP_CUTPOOL* cutpool /**< cut pool */
1128  )
1129 {
1130  assert(cutpool != NULL);
1131 
1132  return cutpool->ncutsadded;
1133 }
1134 
1135 /** adds the maximum number of cuts that were stored in the pool;
1136  * this is primarily used to keep statistics when SCIP performs a restart */
1138  SCIP_CUTPOOL* cutpool, /**< cut pool */
1139  SCIP_Longint ncuts /**< number of cuts to add */
1140  )
1141 {
1142  assert(cutpool != NULL);
1143 
1144  cutpool->maxncuts += ncuts;
1145 }
1146 
1147 /** sets time in seconds used for separating cuts from the pool;
1148  * this is primarily used to keep statistics when SCIP performs a restart */
1150  SCIP_CUTPOOL* cutpool, /**< cut pool */
1151  SCIP_Real time /**< poolclock time */
1152  )
1153 {
1154  assert(cutpool != NULL);
1155 
1156  SCIPclockSetTime(cutpool->poolclock, time);
1157 }
1158 
1159 /** adds the number of times the cut pool was separated;
1160  * this is primarily used to keep statistics when SCIP performs a restart */
1162  SCIP_CUTPOOL* cutpool, /**< cut pool */
1163  SCIP_Longint ncalls /**< ncalls */
1164  )
1165 {
1166  assert(cutpool != NULL);
1167 
1168  cutpool->ncalls += ncalls;
1169 }
1170 
1171 /** adds the number of times the cut pool was separated at the root;
1172  * this is primarily used to keep statistics when SCIP performs a restart */
1174  SCIP_CUTPOOL* cutpool, /**< cut pool */
1175  SCIP_Longint nrootcalls /**< nrootcalls */
1176  )
1177 {
1178  assert(cutpool != NULL);
1179 
1180  cutpool->nrootcalls += nrootcalls;
1181 }
1182 
1183 /** adds the total number of cuts that were added to the pool;
1184  * this is primarily used to keep statistics when SCIP performs a restart */
1186  SCIP_CUTPOOL* cutpool, /**< cut pool */
1187  SCIP_Longint ncutsfound /**< total number of cuts added to cut pool */
1188  )
1189 {
1190  assert(cutpool != NULL);
1191 
1192  cutpool->ncutsfound += ncutsfound;
1193 }
1194 
1195 /** adds the total number of cuts that were separated from the pool;
1196  * this is primarily used to keep statistics when SCIP performs a restart */
1198  SCIP_CUTPOOL* cutpool, /**< cut pool */
1199  SCIP_Longint ncutsadded /**< total number of cuts added from cut pool to sepastore */
1200 )
1201 {
1202  assert(cutpool != NULL);
1203 
1204  cutpool->ncutsadded += ncutsadded;
1205 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
internal methods for separators
SCIP_Bool SCIProwIsRemovable(SCIP_ROW *row)
Definition: lp.c:17387
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:6503
void SCIPcutpoolAddNCalls(SCIP_CUTPOOL *cutpool, SCIP_Longint ncalls)
Definition: cutpool.c:1161
SCIP_Bool SCIPsetIsInfinity(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6206
int SCIProwGetMaxidx(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6698
SCIP_HASHTABLE * hashtable
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:141
#define SCIP_HASHSIZE_CUTPOOLS
Definition: def.h:304
SCIP_SEPA * SCIProwGetOriginSepa(SCIP_ROW *row)
Definition: lp.c:17442
SCIP_Longint processedlp
SCIP_Real SCIProwGetMinval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6682
SCIP_Longint nrootcalls
int * cols_index
Definition: struct_lp.h:219
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2487
SCIP_Bool SCIPsetIsFeasEQ(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6604
SCIP_CUT ** cuts
SCIP_Longint SCIPcutpoolGetNCutsFound(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1116
internal methods for clocks and timing issues
int SCIProwGetNNonz(SCIP_ROW *row)
Definition: lp.c:17179
void SCIProwCapture(SCIP_ROW *row)
Definition: lp.c:5334
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:17317
SCIP_Longint SCIProwGetActiveLPCount(SCIP_ROW *row)
Definition: lp.c:17511
void SCIPclockStop(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:351
#define FALSE
Definition: def.h:87
SCIP_Longint processedlpsol
void SCIPclockStart(SCIP_CLOCK *clck, SCIP_SET *set)
Definition: clock.c:281
#define TRUE
Definition: def.h:86
SCIP_Real SCIPcutGetLPActivityQuot(SCIP_CUT *cut)
Definition: cutpool.c:397
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_Longint SCIPcutpoolGetNCalls(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1096
SCIP_Real SCIProwGetLPEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp)
Definition: lp.c:6803
SCIP_RETCODE SCIPcutpoolAddNewRow(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_ROW *row)
Definition: cutpool.c:717
int SCIPsetCalcMemGrowSize(SCIP_SET *set, int num)
Definition: set.c:5785
SCIP_Longint ncutsadded
SCIP_Longint SCIPcutpoolGetNCutsAdded(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1126
void SCIPsepaIncNCutsFoundAtNode(SCIP_SEPA *sepa)
Definition: sepa.c:1040
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:514
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:138
SCIP_Longint processedlp
SCIP_RETCODE SCIPcutpoolFree(SCIP_CUTPOOL **cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: cutpool.c:459
int nlpcols
Definition: struct_lp.h:227
SCIP_LPSOLSTAT SCIPlpGetSolstat(SCIP_LP *lp)
Definition: lp.c:13083
internal methods for LP management
Definition: heur_padm.c:123
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:2236
int SCIPsetGetSepaMaxcuts(SCIP_SET *set, SCIP_Bool root)
Definition: set.c:5924
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17489
void SCIPclockSetTime(SCIP_CLOCK *clck, SCIP_Real sec)
Definition: clock.c:523
int ncutpoolfails
Definition: struct_stat.h:211
SCIP_Real * vals
Definition: struct_lp.h:220
unsigned int fromcutpool
Definition: struct_lp.h:240
SCIP_Longint SCIPcutpoolGetNRootCalls(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1106
SCIP_RETCODE SCIPcutpoolDelRow(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_ROW *row)
Definition: cutpool.c:787
void SCIProwSort(SCIP_ROW *row)
Definition: lp.c:6011
#define SCIPerrorMessage
Definition: pub_message.h:55
SCIP_Longint lpcount
Definition: struct_stat.h:181
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_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:17367
static INLINE uint32_t SCIPrealHashCode(double x)
Definition: pub_misc.h:535
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:1140
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_ROW * SCIPcutGetRow(SCIP_CUT *cut)
Definition: cutpool.c:373
internal methods for global SCIP settings
#define SCIP_CALL(x)
Definition: def.h:384
#define SCIPhashTwo(a, b)
Definition: pub_misc.h:510
void SCIPcutpoolAddNCutsAdded(SCIP_CUTPOOL *cutpool, SCIP_Longint ncutsadded)
Definition: cutpool.c:1197
SCIP_Real processedlpsolefficacy
void SCIPhashtableRemoveAll(SCIP_HASHTABLE *hashtable)
Definition: misc.c:2695
SCIP_RETCODE SCIPcutpoolClear(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: cutpool.c:485
SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2617
SCIP_CUT ** SCIPcutpoolGetCuts(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1056
Definition: graph_load.c:93
int SCIPcutpoolGetNCuts(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1066
internal methods for storing separated cuts
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:17377
SCIP_RETCODE SCIProwRelease(SCIP_ROW **row, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_LP *lp)
Definition: lp.c:5347
SCIP_RETCODE SCIPclockCreate(SCIP_CLOCK **clck, SCIP_CLOCKTYPE clocktype)
Definition: clock.c:161
void SCIPconshdlrIncNCutsFound(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4884
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:458
void SCIPsepaIncNCutsAdded(SCIP_SEPA *sepa, SCIP_Bool fromcutpool)
Definition: sepa.c:984
SCIP_Real bestefficacy
Definition: struct_stat.h:148
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:84
SCIP_Real minefficacyfac
Definition: struct_stat.h:149
SCIP_Bool SCIPcutpoolIsCutNew(SCIP_CUTPOOL *cutpool, SCIP_SET *set, SCIP_ROW *row)
Definition: cutpool.c:584
void SCIPclockFree(SCIP_CLOCK **clck)
Definition: clock.c:176
#define MAX(x, y)
Definition: tclique_def.h:83
#define SCIP_HASHSIZE_CUTPOOLS_SMALL
Definition: def.h:307
#define SCIPsetDebugMsg
Definition: set.h:1761
void SCIPcutpoolAddNRootCalls(SCIP_CUTPOOL *cutpool, SCIP_Longint nrootcalls)
Definition: cutpool.c:1173
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 SCIPsepastoreGetNCutsAdded(SCIP_SEPASTORE *sepastore)
Definition: sepastore.c:1151
unsigned int lpcolssorted
Definition: struct_lp.h:242
internal methods for storing cuts in a cut pool
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
Definition: misc.c:2548
SCIP_Real SCIProwGetSolEfficacy(SCIP_ROW *row, SCIP_SET *set, SCIP_STAT *stat, SCIP_SOL *sol)
Definition: lp.c:6860
int firstunprocessedsol
SCIP_CLOCK * poolclock
SCIP_Bool SCIPsetIsFeasLT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6626
SCIP_CONSHDLR * SCIProwGetOriginConshdlr(SCIP_ROW *row)
Definition: lp.c:17422
SCIP_Longint maxncuts
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2286
void SCIProwLock(SCIP_ROW *row)
Definition: lp.c:5373
SCIP_Real rhs
Definition: struct_lp.h:196
SCIP_Real constant
Definition: struct_lp.h:194
SCIP_Longint ncalls
void SCIPcutpoolAddNCutsFound(SCIP_CUTPOOL *cutpool, SCIP_Longint ncutsfound)
Definition: cutpool.c:1185
void SCIPcutpoolSetTime(SCIP_CUTPOOL *cutpool, SCIP_Real time)
Definition: cutpool.c:1149
unsigned int inglobalcutpool
Definition: struct_lp.h:253
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:6249
#define SCIP_Real
Definition: def.h:177
internal methods for problem statistics
SCIP_Bool SCIPsetIsFeasPositive(SCIP_SET *set, SCIP_Real val)
Definition: set.c:6725
#define BMSallocMemory(ptr)
Definition: memory.h:111
#define SCIP_INVALID
Definition: def.h:197
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:120
internal methods for constraints and constraint handlers
SCIP_RETCODE SCIPcutpoolAddRow(SCIP_CUTPOOL *cutpool, BMS_BLKMEM *blkmem, SCIP_SET *set, SCIP_STAT *stat, SCIP_LP *lp, SCIP_ROW *row)
Definition: cutpool.c:647
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:816
#define SCIP_Longint
Definition: def.h:162
SCIP_Bool SCIPsetIsFeasGT(SCIP_SET *set, SCIP_Real val1, SCIP_Real val2)
Definition: set.c:6670
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2599
SCIP_Real SCIProwGetMaxval(SCIP_ROW *row, SCIP_SET *set)
Definition: lp.c:6666
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:444
SCIP_Real SCIPcutpoolGetTime(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1086
SCIP_Bool globalcutpool
int SCIPcutGetAge(SCIP_CUT *cut)
Definition: cutpool.c:383
SCIP_Longint SCIPcutpoolGetMaxNCuts(SCIP_CUTPOOL *cutpool)
Definition: cutpool.c:1076
common defines and data types used in all packages of SCIP
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:430
unsigned int validminmaxidx
Definition: struct_lp.h:245
#define SCIP_ALLOC(x)
Definition: def.h:395
unsigned int nonlpcolssorted
Definition: struct_lp.h:243
SCIP_Longint SCIProwGetNLPsAfterCreation(SCIP_ROW *row)
Definition: lp.c:17521
static SCIP_Bool cutIsAged(SCIP_CUT *cut, int agelimit)
Definition: cutpool.c:361
static SCIP_DECL_HASHGETKEY(hashGetKeyCut)
Definition: cutpool.c:52
void SCIPcutpoolAddMaxNCuts(SCIP_CUTPOOL *cutpool, SCIP_Longint ncuts)
Definition: cutpool.c:1137
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:419
int len
Definition: struct_lp.h:226
int age
Definition: struct_lp.h:238
void SCIProwUnlock(SCIP_ROW *row)
Definition: lp.c:5388