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