Scippy

SCIP

Solving Constraint Integer Programs

sepa_strongcg.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-2014 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file sepa_strongcg.c
17  * @brief Strong CG Cuts (Letchford & Lodi)
18  * @author Kati Wolter
19  * @author Tobias Achterberg
20  */
21 
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
23 
24 #include <assert.h>
25 #include <string.h>
26 
27 #include "scip/sepa_strongcg.h"
28 #include "scip/pub_misc.h"
29 
30 
31 #define SEPA_NAME "strongcg"
32 #define SEPA_DESC "Strong CG cuts separator (Letchford and Lodi)"
33 #define SEPA_PRIORITY -2000
34 #define SEPA_FREQ 0
35 #define SEPA_MAXBOUNDDIST 0.0
36 #define SEPA_USESSUBSCIP FALSE /**< does the separator use a secondary SCIP instance? */
37 #define SEPA_DELAY FALSE /**< should separation method be delayed, if other separators found cuts? */
38 
39 #define DEFAULT_MAXROUNDS 5 /**< maximal number of strong CG separation rounds per node (-1: unlimited) */
40 #define DEFAULT_MAXROUNDSROOT 20 /**< maximal number of strong CG separation rounds in the root node (-1: unlimited) */
41 #define DEFAULT_MAXSEPACUTS 50 /**< maximal number of strong CG cuts separated per separation round */
42 #define DEFAULT_MAXSEPACUTSROOT 500 /**< maximal number of strong CG cuts separated per separation round in root node */
43 #define DEFAULT_DYNAMICCUTS TRUE /**< should generated cuts be removed from the LP if they are no longer tight? */
44 #define DEFAULT_MAXWEIGHTRANGE 1e+04 /**< maximal valid range max(|weights|)/min(|weights|) of row weights */
45 
46 #define MAKECUTINTEGRAL /* try to scale all cuts to integral coefficients */
47 /*#define MAKEINTCUTINTEGRAL*/ /* try to scale cuts without continuous variables to integral coefficients */
48 #define FORCECUTINTEGRAL /* discard cut if conversion to integral coefficients failed */
49 #define SEPARATEROWS /* separate rows with integral slack */
50 
51 #define BOUNDSWITCH 0.9999
52 #define USEVBDS TRUE
53 #define ALLOWLOCAL TRUE
54 #define MAKECONTINTEGRAL FALSE
55 #define MINFRAC 0.05
56 #define MAXFRAC 0.95
57 
58 #define MAXAGGRLEN(nvars) (0.1*(nvars)+1000) /**< maximal length of base inequality */
59 
60 
61 /** separator data */
62 struct SCIP_SepaData
63 {
64  SCIP_Real maxweightrange; /**< maximal valid range max(|weights|)/min(|weights|) of row weights */
65  int maxrounds; /**< maximal number of strong CG separation rounds per node (-1: unlimited) */
66  int maxroundsroot; /**< maximal number of strong CG separation rounds in the root node (-1: unlimited) */
67  int maxsepacuts; /**< maximal number of strong CG cuts separated per separation round */
68  int maxsepacutsroot; /**< maximal number of strong CG cuts separated per separation round in root node */
69  int lastncutsfound; /**< total number of cuts found after last call of separator */
70  SCIP_Bool dynamiccuts; /**< should generated cuts be removed from the LP if they are no longer tight? */
71 };
72 
73 
74 /*
75  * local methods
76  */
77 
78 /** stores nonzero elements of dense coefficient vector as sparse vector, and calculates activity and norm */
79 static
81  SCIP* scip, /**< SCIP data structure */
82  int nvars, /**< number of problem variables */
83  SCIP_VAR** vars, /**< problem variables */
84  SCIP_Real* cutcoefs, /**< dense coefficient vector */
85  SCIP_Real* varsolvals, /**< dense variable LP solution vector */
86  char normtype, /**< type of norm to use for efficacy norm calculation */
87  SCIP_VAR** cutvars, /**< array to store variables of sparse cut vector */
88  SCIP_Real* cutvals, /**< array to store coefficients of sparse cut vector */
89  int* cutlen, /**< pointer to store number of nonzero entries in cut */
90  SCIP_Real* cutact, /**< pointer to store activity of cut */
91  SCIP_Real* cutnorm /**< pointer to store norm of cut vector */
92  )
93 {
94  SCIP_Real val;
95  SCIP_Real absval;
96  SCIP_Real cutsqrnorm;
97  SCIP_Real act;
98  SCIP_Real norm;
99  int len;
100  int v;
101 
102  assert(nvars == 0 || cutcoefs != NULL);
103  assert(nvars == 0 || varsolvals != NULL);
104  assert(cutvars != NULL);
105  assert(cutvals != NULL);
106  assert(cutlen != NULL);
107  assert(cutact != NULL);
108  assert(cutnorm != NULL);
109 
110  len = 0;
111  act = 0.0;
112  norm = 0.0;
113  switch( normtype )
114  {
115  case 'e':
116  cutsqrnorm = 0.0;
117  for( v = 0; v < nvars; ++v )
118  {
119  val = cutcoefs[v];
120  if( !SCIPisZero(scip, val) )
121  {
122  act += val * varsolvals[v];
123  cutsqrnorm += SQR(val);
124  cutvars[len] = vars[v];
125  cutvals[len] = val;
126  len++;
127  }
128  }
129  norm = SQRT(cutsqrnorm);
130  break;
131  case 'm':
132  for( v = 0; v < nvars; ++v )
133  {
134  val = cutcoefs[v];
135  if( !SCIPisZero(scip, val) )
136  {
137  act += val * varsolvals[v];
138  absval = ABS(val);
139  norm = MAX(norm, absval);
140  cutvars[len] = vars[v];
141  cutvals[len] = val;
142  len++;
143  }
144  }
145  break;
146  case 's':
147  for( v = 0; v < nvars; ++v )
148  {
149  val = cutcoefs[v];
150  if( !SCIPisZero(scip, val) )
151  {
152  act += val * varsolvals[v];
153  norm += ABS(val);
154  cutvars[len] = vars[v];
155  cutvals[len] = val;
156  len++;
157  }
158  }
159  break;
160  case 'd':
161  for( v = 0; v < nvars; ++v )
162  {
163  val = cutcoefs[v];
164  if( !SCIPisZero(scip, val) )
165  {
166  act += val * varsolvals[v];
167  norm = 1.0;
168  cutvars[len] = vars[v];
169  cutvals[len] = val;
170  len++;
171  }
172  }
173  break;
174  default:
175  SCIPerrorMessage("invalid efficacy norm parameter '%c'\n", normtype);
176  return SCIP_INVALIDDATA;
177  }
178 
179  *cutlen = len;
180  *cutact = act;
181  *cutnorm = norm;
182 
183  return SCIP_OKAY;
184 }
185 
186 
187 /*
188  * Callback methods
189  */
190 
191 /** copy method for separator plugins (called when SCIP copies plugins) */
192 static
193 SCIP_DECL_SEPACOPY(sepaCopyStrongcg)
194 { /*lint --e{715}*/
195  assert(scip != NULL);
196  assert(sepa != NULL);
197  assert(strcmp(SCIPsepaGetName(sepa), SEPA_NAME) == 0);
198 
199  /* call inclusion method of constraint handler */
201 
202  return SCIP_OKAY;
203 }
204 
205 /** destructor of separator to free user data (called when SCIP is exiting) */
206 static
207 SCIP_DECL_SEPAFREE(sepaFreeStrongcg)
208 { /*lint --e{715}*/
209  SCIP_SEPADATA* sepadata;
210 
211  assert(strcmp(SCIPsepaGetName(sepa), SEPA_NAME) == 0);
212 
213  /* free separator data */
214  sepadata = SCIPsepaGetData(sepa);
215  assert(sepadata != NULL);
216 
217  SCIPfreeMemory(scip, &sepadata);
218 
219  SCIPsepaSetData(sepa, NULL);
220 
221  return SCIP_OKAY;
222 }
223 
224 
225 /** LP solution separation method of separator */
226 static
227 SCIP_DECL_SEPAEXECLP(sepaExeclpStrongcg)
228 { /*lint --e{715}*/
229  SCIP_SEPADATA* sepadata;
230  SCIP_VAR** vars;
231  SCIP_COL** cols;
232  SCIP_ROW** rows;
233  SCIP_Real* varsolvals;
234  SCIP_Real* binvrow;
235  SCIP_Real* cutcoefs;
236  SCIP_Real cutrhs;
237  SCIP_Real cutact;
238  SCIP_Real maxscale;
239  SCIP_Longint maxdnom;
240  int* basisind;
241  int nvars;
242  int ncols;
243  int nrows;
244  int ncalls;
245  int depth;
246  int maxdepth;
247  int maxsepacuts;
248  int ncuts;
249  int c;
250  int i;
251  int cutrank;
252  SCIP_Bool success;
253  SCIP_Bool cutislocal;
254  char normtype;
255 
256  assert(sepa != NULL);
257  assert(strcmp(SCIPsepaGetName(sepa), SEPA_NAME) == 0);
258  assert(scip != NULL);
259  assert(result != NULL);
260 
261  *result = SCIP_DIDNOTRUN;
262 
263  sepadata = SCIPsepaGetData(sepa);
264  assert(sepadata != NULL);
265 
266  depth = SCIPgetDepth(scip);
267  ncalls = SCIPsepaGetNCallsAtNode(sepa);
268 
269  /* only call separator, if we are not close to terminating */
270  if( SCIPisStopped(scip) )
271  return SCIP_OKAY;
272 
273  /* only call the strong CG cut separator a given number of times at each node */
274  if( (depth == 0 && sepadata->maxroundsroot >= 0 && ncalls >= sepadata->maxroundsroot)
275  || (depth > 0 && sepadata->maxrounds >= 0 && ncalls >= sepadata->maxrounds) )
276  return SCIP_OKAY;
277 
278  /* only call separator, if an optimal LP solution is at hand */
280  return SCIP_OKAY;
281 
282  /* only call separator, if the LP solution is basic */
283  if( !SCIPisLPSolBasic(scip) )
284  return SCIP_OKAY;
285 
286  /* only call separator, if there are fractional variables */
287  if( SCIPgetNLPBranchCands(scip) == 0 )
288  return SCIP_OKAY;
289 
290  /* get variables data */
291  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
292 
293  /* get LP data */
294  SCIP_CALL( SCIPgetLPColsData(scip, &cols, &ncols) );
295  SCIP_CALL( SCIPgetLPRowsData(scip, &rows, &nrows) );
296  if( ncols == 0 || nrows == 0 )
297  return SCIP_OKAY;
298 
299 #if 0 /* if too many columns, separator is usually very slow: delay it until no other cuts have been found */
300  if( ncols >= 50*nrows )
301  return SCIP_OKAY;
302  if( ncols >= 5*nrows )
303  {
304  int ncutsfound;
305 
306  ncutsfound = SCIPgetNCutsFound(scip);
307  if( ncutsfound > sepadata->lastncutsfound || !SCIPsepaWasLPDelayed(sepa) )
308  {
309  sepadata->lastncutsfound = ncutsfound;
310  *result = SCIP_DELAYED;
311  return SCIP_OKAY;
312  }
313  }
314 #endif
315 
316  /* get the type of norm to use for efficacy calculations */
317  SCIP_CALL( SCIPgetCharParam(scip, "separating/efficacynorm", &normtype) );
318 
319  /* set the maximal denominator in rational representation of strong CG cut and the maximal scale factor to
320  * scale resulting cut to integral values to avoid numerical instabilities
321  */
322  /**@todo find better but still stable strong CG cut settings: look at dcmulti, gesa3, khb0525, misc06, p2756 */
323  maxdepth = SCIPgetMaxDepth(scip);
324  if( depth == 0 )
325  {
326  maxdnom = 1000;
327  maxscale = 1000.0;
328  }
329  else if( depth <= maxdepth/4 )
330  {
331  maxdnom = 1000;
332  maxscale = 1000.0;
333  }
334  else if( depth <= maxdepth/2 )
335  {
336  maxdnom = 100;
337  maxscale = 100.0;
338  }
339  else
340  {
341  maxdnom = 10;
342  maxscale = 10.0;
343  }
344 
345  *result = SCIP_DIDNOTFIND;
346 
347  /* allocate temporary memory */
348  SCIP_CALL( SCIPallocBufferArray(scip, &cutcoefs, nvars) );
349  SCIP_CALL( SCIPallocBufferArray(scip, &basisind, nrows) );
350  SCIP_CALL( SCIPallocBufferArray(scip, &binvrow, nrows) );
351  varsolvals = NULL; /* allocate this later, if needed */
352 
353  /* get basis indices */
354  SCIP_CALL( SCIPgetLPBasisInd(scip, basisind) );
355 
356  /* get the maximal number of cuts allowed in a separation round */
357  if( depth == 0 )
358  maxsepacuts = sepadata->maxsepacutsroot;
359  else
360  maxsepacuts = sepadata->maxsepacuts;
361 
362  SCIPdebugMessage("searching strong CG cuts: %d cols, %d rows, maxdnom=%"SCIP_LONGINT_FORMAT", maxscale=%g, maxcuts=%d\n",
363  ncols, nrows, maxdnom, maxscale, maxsepacuts);
364 
365  /* for all basic columns belonging to integer variables, try to generate a strong CG cut */
366  ncuts = 0;
367  for( i = 0; i < nrows && ncuts < maxsepacuts && !SCIPisStopped(scip) && *result != SCIP_CUTOFF; ++i )
368  {
369  SCIP_Bool tryrow;
370 
371  tryrow = FALSE;
372  c = basisind[i];
373  if( c >= 0 )
374  {
375  SCIP_VAR* var;
376 
377  assert(c < ncols);
378  var = SCIPcolGetVar(cols[c]);
380  {
381  SCIP_Real primsol;
382 
383  primsol = SCIPcolGetPrimsol(cols[c]);
384  assert(SCIPgetVarSol(scip, var) == primsol); /*lint !e777*/
385 
386  if( SCIPfeasFrac(scip, primsol) >= MINFRAC )
387  {
388  SCIPdebugMessage("trying strong CG cut for col <%s> [%g]\n", SCIPvarGetName(var), primsol);
389  tryrow = TRUE;
390  }
391  }
392  }
393 #ifdef SEPARATEROWS
394  else
395  {
396  SCIP_ROW* row;
397 
398  assert(0 <= -c-1 && -c-1 < nrows);
399  row = rows[-c-1];
400  if( SCIProwIsIntegral(row) && !SCIProwIsModifiable(row) )
401  {
402  SCIP_Real primsol;
403 
404  primsol = SCIPgetRowActivity(scip, row);
405  if( SCIPfeasFrac(scip, primsol) >= MINFRAC )
406  {
407  SCIPdebugMessage("trying strong CG cut for row <%s> [%g]\n", SCIProwGetName(row), primsol);
408  tryrow = TRUE;
409  }
410  }
411  }
412 #endif
413 
414  if( tryrow )
415  {
416  /* get the row of B^-1 for this basic integer variable with fractional solution value */
417  SCIP_CALL( SCIPgetLPBInvRow(scip, i, binvrow) );
418 
419 #ifdef SCIP_DEBUG
420  /* initialize variables, that might not have been initialized in SCIPcalcMIR if success == FALSE */
421  cutact = 0.0;
422  cutrhs = SCIPinfinity(scip);
423 #endif
424  /* create a strong CG cut out of the weighted LP rows using the B^-1 row as weights */
425  SCIP_CALL( SCIPcalcStrongCG(scip, BOUNDSWITCH, USEVBDS, ALLOWLOCAL, (int) MAXAGGRLEN(nvars), sepadata->maxweightrange, MINFRAC, MAXFRAC,
426  binvrow, 1.0, cutcoefs, &cutrhs, &cutact, &success, &cutislocal, &cutrank) );
427  assert(ALLOWLOCAL || !cutislocal);
428  SCIPdebugMessage(" -> success=%u: %g <= %g\n", success, cutact, cutrhs);
429 
430  /* if successful, convert dense cut into sparse row, and add the row as a cut */
431  if( success && SCIPisFeasGT(scip, cutact, cutrhs) )
432  {
433  SCIP_VAR** cutvars;
434  SCIP_Real* cutvals;
435  SCIP_Real cutnorm;
436  int cutlen;
437 
438  /* if this is the first successful cut, get the LP solution for all COLUMN variables */
439  if( varsolvals == NULL )
440  {
441  int v;
442 
443  SCIP_CALL( SCIPallocBufferArray(scip, &varsolvals, nvars) );
444  for( v = 0; v < nvars; ++v )
445  {
446  if( SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_COLUMN )
447  varsolvals[v] = SCIPvarGetLPSol(vars[v]);
448  }
449  }
450  assert(varsolvals != NULL);
451 
452  /* get temporary memory for storing the cut as sparse row */
453  SCIP_CALL( SCIPallocBufferArray(scip, &cutvars, nvars) );
454  SCIP_CALL( SCIPallocBufferArray(scip, &cutvals, nvars) );
455 
456  /* store the cut as sparse row, calculate activity and norm of cut */
457  SCIP_CALL( storeCutInArrays(scip, nvars, vars, cutcoefs, varsolvals, normtype,
458  cutvars, cutvals, &cutlen, &cutact, &cutnorm) );
459 
460  SCIPdebugMessage(" -> strong CG cut for <%s>: act=%f, rhs=%f, norm=%f, eff=%f, rank=%d\n",
461  c >= 0 ? SCIPvarGetName(SCIPcolGetVar(cols[c])) : SCIProwGetName(rows[-c-1]),
462  cutact, cutrhs, cutnorm, (cutact - cutrhs)/cutnorm, cutrank);
463 
464  if( SCIPisPositive(scip, cutnorm) && SCIPisEfficacious(scip, (cutact - cutrhs)/cutnorm) )
465  {
466  SCIP_ROW* cut;
467  char cutname[SCIP_MAXSTRLEN];
468 
469  /* create the cut */
470  if( c >= 0 )
471  (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "scg%d_x%d", SCIPgetNLPs(scip), c);
472  else
473  (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "scg%d_s%d", SCIPgetNLPs(scip), -c-1);
474  SCIP_CALL( SCIPcreateEmptyRowSepa(scip, &cut, sepa, cutname, -SCIPinfinity(scip), cutrhs, cutislocal, FALSE, sepadata->dynamiccuts) );
475  SCIP_CALL( SCIPaddVarsToRow(scip, cut, cutlen, cutvars, cutvals) );
476  /*SCIPdebug( SCIP_CALL(SCIPprintRow(scip, cut, NULL)) );*/
477  SCIProwChgRank(cut, cutrank);
478 
479  assert(success);
480 #ifdef MAKECUTINTEGRAL
481  /* try to scale the cut to integral values */
482  SCIP_CALL( SCIPmakeRowIntegral(scip, cut, -SCIPepsilon(scip), SCIPsumepsilon(scip),
483  maxdnom, maxscale, MAKECONTINTEGRAL, &success) );
484 #else
485 #ifdef MAKEINTCUTINTEGRAL
486  /* try to scale the cut to integral values if there are no continuous variables
487  * -> leads to an integral slack variable that can later be used for other cuts
488  */
489  {
490  int k = 0;
491  while ( k < cutlen && SCIPvarIsIntegral(cutvars[k]) )
492  ++k;
493  if( k == cutlen )
494  {
495  SCIP_CALL( SCIPmakeRowIntegral(scip, cut, -SCIPepsilon(scip), SCIPsumepsilon(scip),
496  maxdnom, maxscale, MAKECONTINTEGRAL, &success) );
497  }
498  }
499 #endif
500 #endif
501 
502 #ifndef FORCECUTINTEGRAL
503  success = TRUE;
504 #endif
505 
506  if( success )
507  {
508  if( !SCIPisCutEfficacious(scip, NULL, cut) )
509  {
510  SCIPdebugMessage(" -> strong CG cut <%s> no longer efficacious: act=%f, rhs=%f, norm=%f, eff=%f\n",
511  cutname, SCIPgetRowLPActivity(scip, cut), SCIProwGetRhs(cut), SCIProwGetNorm(cut),
512  SCIPgetCutEfficacy(scip, NULL, cut));
513  /*SCIPdebug( SCIP_CALL(SCIPprintRow(scip, cut, NULL)) );*/
514  success = FALSE;
515  }
516  else
517  {
518  SCIP_Bool infeasible;
519 
520  SCIPdebugMessage(" -> found strong CG cut <%s>: act=%f, rhs=%f, norm=%f, eff=%f, min=%f, max=%f (range=%f)\n",
521  cutname, SCIPgetRowLPActivity(scip, cut), SCIProwGetRhs(cut), SCIProwGetNorm(cut),
522  SCIPgetCutEfficacy(scip, NULL, cut),
523  SCIPgetRowMinCoef(scip, cut), SCIPgetRowMaxCoef(scip, cut),
524  SCIPgetRowMaxCoef(scip, cut)/SCIPgetRowMinCoef(scip, cut));
525  /*SCIPdebug( SCIP_CALL(SCIPprintRow(scip, cut, NULL)) );*/
526  SCIP_CALL( SCIPaddCut(scip, NULL, cut, FALSE, &infeasible) );
527  if ( infeasible )
528  *result = SCIP_CUTOFF;
529  else
530  {
531  if( !cutislocal )
532  {
533  SCIP_CALL( SCIPaddPoolCut(scip, cut) );
534  }
535  *result = SCIP_SEPARATED;
536  }
537  ncuts++;
538  }
539  }
540  else
541  {
542  SCIPdebugMessage(" -> strong CG cut <%s> couldn't be scaled to integral coefficients: act=%f, rhs=%f, norm=%f, eff=%f\n",
543  cutname, cutact, cutrhs, cutnorm, SCIPgetCutEfficacy(scip, NULL, cut));
544  }
545 
546  /* release the row */
547  SCIP_CALL( SCIPreleaseRow(scip, &cut) );
548  }
549 
550  /* free temporary memory */
551  SCIPfreeBufferArray(scip, &cutvals);
552  SCIPfreeBufferArray(scip, &cutvars);
553  }
554  }
555  }
556 
557  /* free temporary memory */
558  SCIPfreeBufferArrayNull(scip, &varsolvals);
559  SCIPfreeBufferArray(scip, &binvrow);
560  SCIPfreeBufferArray(scip, &basisind);
561  SCIPfreeBufferArray(scip, &cutcoefs);
562 
563  SCIPdebugMessage("end searching strong CG cuts: found %d cuts\n", ncuts);
564 
565  sepadata->lastncutsfound = SCIPgetNCutsFound(scip);
566 
567  return SCIP_OKAY;
568 }
569 
570 
571 /*
572  * separator specific interface methods
573  */
574 
575 /** creates the Strong CG cut separator and includes it in SCIP */
577  SCIP* scip /**< SCIP data structure */
578  )
579 {
580  SCIP_SEPADATA* sepadata;
581  SCIP_SEPA* sepa;
582 
583  /* create separator data */
584  SCIP_CALL( SCIPallocMemory(scip, &sepadata) );
585  sepadata->lastncutsfound = 0;
586 
587  /* include separator */
590  sepaExeclpStrongcg, NULL,
591  sepadata) );
592 
593  assert(sepa != NULL);
594 
595  /* set non-NULL pointers to callback methods */
596  SCIP_CALL( SCIPsetSepaCopy(scip, sepa, sepaCopyStrongcg) );
597  SCIP_CALL( SCIPsetSepaFree(scip, sepa, sepaFreeStrongcg) );
598 
599  /* add separator parameters */
601  "separating/strongcg/maxrounds",
602  "maximal number of strong CG separation rounds per node (-1: unlimited)",
603  &sepadata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
605  "separating/strongcg/maxroundsroot",
606  "maximal number of strong CG separation rounds in the root node (-1: unlimited)",
607  &sepadata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
609  "separating/strongcg/maxsepacuts",
610  "maximal number of strong CG cuts separated per separation round",
611  &sepadata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) );
613  "separating/strongcg/maxsepacutsroot",
614  "maximal number of strong CG cuts separated per separation round in the root node",
615  &sepadata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) );
617  "separating/strongcg/maxweightrange",
618  "maximal valid range max(|weights|)/min(|weights|) of row weights",
619  &sepadata->maxweightrange, TRUE, DEFAULT_MAXWEIGHTRANGE, 1.0, SCIP_REAL_MAX, NULL, NULL) );
621  "separating/strongcg/dynamiccuts",
622  "should generated cuts be removed from the LP if they are no longer tight?",
623  &sepadata->dynamiccuts, FALSE, DEFAULT_DYNAMICCUTS, NULL, NULL) );
624 
625  return SCIP_OKAY;
626 }
627 
int SCIPgetNLPBranchCands(SCIP *scip)
Definition: scip.c:30035
static SCIP_DECL_SEPAFREE(sepaFreeStrongcg)
#define DEFAULT_MAXROUNDS
Definition: sepa_strongcg.c:39
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:38397
#define USEVBDS
Definition: sepa_strongcg.c:52
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:15788
static SCIP_DECL_SEPACOPY(sepaCopyStrongcg)
SCIP_Real SCIPgetRowMinCoef(SCIP *scip, SCIP_ROW *row)
Definition: scip.c:25721
#define SEPA_DESC
Definition: sepa_strongcg.c:32
#define BOUNDSWITCH
Definition: sepa_strongcg.c:51
#define SEPA_PRIORITY
Definition: sepa_strongcg.c:33
#define SCIP_MAXSTRLEN
Definition: def.h:196
SCIP_Bool SCIPisEfficacious(SCIP *scip, SCIP_Real efficacy)
Definition: scip.c:28166
#define NULL
Definition: lpi_spx.cpp:129
#define DEFAULT_MAXROUNDSROOT
Definition: sepa_strongcg.c:40
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1111
SCIP_Bool SCIPisCutEfficacious(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
Definition: scip.c:28148
static SCIP_DECL_SEPAEXECLP(sepaExeclpStrongcg)
#define FALSE
Definition: def.h:52
#define DEFAULT_MAXSEPACUTSROOT
Definition: sepa_strongcg.c:42
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:7579
#define TRUE
Definition: def.h:51
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_RETCODE SCIPaddVarsToRow(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip.c:25564
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip.c:24136
#define SCIPdebugMessage
Definition: pub_message.h:77
#define SEPA_NAME
Definition: sepa_strongcg.c:31
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:19214
#define ALLOWLOCAL
Definition: sepa_strongcg.c:53
SCIP_RETCODE SCIPaddCut(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition: scip.c:28256
SCIP_RETCODE SCIPsetSepaFree(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAFREE((*sepafree)))
Definition: scip.c:6440
SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
Definition: sepa.c:544
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
Definition: sepa.c:633
SCIP_RETCODE SCIPgetLPBInvRow(SCIP *scip, int r, SCIP_Real *coef)
Definition: scip.c:24591
SCIP_Real SCIPgetRowMaxCoef(SCIP *scip, SCIP_ROW *row)
Definition: scip.c:25739
SCIP_RETCODE SCIPgetLPColsData(SCIP *scip, SCIP_COL ***cols, int *ncols)
Definition: scip.c:24369
#define MINFRAC
Definition: sepa_strongcg.c:55
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:3388
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:15907
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:3414
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:15979
#define MAXFRAC
Definition: sepa_strongcg.c:56
#define SEPA_USESSUBSCIP
Definition: sepa_strongcg.c:36
int SCIPgetNCutsFound(SCIP *scip)
Definition: scip.c:34690
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:18756
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:19159
#define SCIPerrorMessage
Definition: pub_message.h:45
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:19221
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:18647
#define SEPA_FREQ
Definition: sepa_strongcg.c:34
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
Definition: lp.c:18361
SCIP_Real SCIPepsilon(SCIP *scip)
Definition: scip.c:37705
int SCIPgetMaxDepth(SCIP *scip)
Definition: scip.c:34883
SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
Definition: scip.c:28351
SCIP_RETCODE SCIPgetCharParam(SCIP *scip, const char *name, char *value)
Definition: scip.c:3657
SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
Definition: scip.c:24447
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:38349
#define SCIP_CALL(x)
Definition: def.h:258
SCIP_RETCODE SCIPmakeRowIntegral(SCIP *scip, SCIP_ROW *row, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Real maxscale, SCIP_Bool usecontvars, SCIP_Bool *success)
Definition: scip.c:25679
SCIP_Longint SCIPgetNLPs(SCIP *scip)
Definition: scip.c:34128
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:18696
SCIP_RETCODE SCIPcreateEmptyRowSepa(SCIP *scip, SCIP_ROW **row, SCIP_SEPA *sepa, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
Definition: scip.c:25305
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38705
#define SEPA_DELAY
Definition: sepa_strongcg.c:37
public data structures and miscellaneous methods
void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
Definition: sepa.c:554
void SCIProwChgRank(SCIP_ROW *row, int rank)
Definition: lp.c:18859
#define SCIP_Bool
Definition: def.h:49
#define SEPA_MAXBOUNDDIST
Definition: sepa_strongcg.c:35
SCIP_Real SCIProwGetNorm(SCIP_ROW *row)
Definition: lp.c:18613
SCIP_RETCODE SCIPincludeSepaStrongcg(SCIP *scip)
SCIP_Bool SCIPsepaWasLPDelayed(SCIP_SEPA *sepa)
Definition: sepa.c:870
SCIP_RETCODE SCIPsetSepaCopy(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPACOPY((*sepacopy)))
Definition: scip.c:6424
#define DEFAULT_MAXSEPACUTS
Definition: sepa_strongcg.c:41
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip.h:19222
#define MAX(x, y)
Definition: tclique_def.h:75
int SCIPgetDepth(SCIP *scip)
Definition: scip.c:34833
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:16760
#define SCIP_REAL_MAX
Definition: def.h:124
SCIP_RETCODE SCIPgetLPBasisInd(SCIP *scip, int *basisind)
Definition: scip.c:24563
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:15953
#define DEFAULT_MAXWEIGHTRANGE
Definition: sepa_strongcg.c:44
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:19176
#define DEFAULT_DYNAMICCUTS
Definition: sepa_strongcg.c:43
#define MAKECONTINTEGRAL
Definition: sepa_strongcg.c:54
SCIP_Bool SCIProwIsIntegral(SCIP_ROW *row)
Definition: lp.c:18736
#define SCIP_Real
Definition: def.h:123
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip.c:25414
static SCIP_RETCODE storeCutInArrays(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_Real *cutcoefs, SCIP_Real *varsolvals, char normtype, SCIP_VAR **cutvars, SCIP_Real *cutvals, int *cutlen, SCIP_Real *cutact, SCIP_Real *cutnorm)
Definition: sepa_strongcg.c:80
#define SCIP_Longint
Definition: def.h:107
int SCIPsepaGetNCallsAtNode(SCIP_SEPA *sepa)
Definition: sepa.c:760
Strong CG Cuts (Letchford & Lodi)
SCIP_Real SCIPgetVarSol(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:15863
SCIP_Real SCIPgetRowLPActivity(SCIP *scip, SCIP_ROW *row)
Definition: scip.c:25810
SCIP_RETCODE SCIPcalcStrongCG(SCIP *scip, SCIP_Real boundswitch, SCIP_Bool usevbds, SCIP_Bool allowlocal, int maxmksetcoefs, SCIP_Real maxweightrange, SCIP_Real minfrac, SCIP_Real maxfrac, SCIP_Real *weights, SCIP_Real scale, SCIP_Real *mircoef, SCIP_Real *mirrhs, SCIP_Real *cutactivity, SCIP_Bool *success, SCIP_Bool *cutislocal, int *cutrank)
Definition: scip.c:24793
SCIP_Real SCIPfeasFrac(SCIP *scip, SCIP_Real val)
Definition: scip.c:38839
SCIP_Real SCIPgetRowActivity(SCIP *scip, SCIP_ROW *row)
Definition: scip.c:25921
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip.c:9945
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
Definition: scip.c:24544
SCIP_RETCODE SCIPincludeSepaBasic(SCIP *scip, SCIP_SEPA **sepa, const char *name, const char *desc, int priority, int freq, SCIP_Real maxbounddist, SCIP_Bool usessubscip, SCIP_Bool delay, SCIP_DECL_SEPAEXECLP((*sepaexeclp)), SCIP_DECL_SEPAEXECSOL((*sepaexecsol)), SCIP_SEPADATA *sepadata)
Definition: scip.c:6382
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition: lp.c:18407
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
Definition: scip.c:38409
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:3470
SCIP_Real SCIPsumepsilon(SCIP *scip)
Definition: scip.c:37719
SCIP_Real SCIPgetCutEfficacy(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
Definition: scip.c:28125
#define MAXAGGRLEN(nvars)
Definition: sepa_strongcg.c:58
struct SCIP_SepaData SCIP_SEPADATA
Definition: type_sepa.h:38