Scippy

SCIP

Solving Constraint Integer Programs

sepa_impliedbounds.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-2018 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_impliedbounds.c
17  * @brief implied bounds separator
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 
28 #include "scip/pub_misc.h"
29 
30 
31 #define SEPA_NAME "impliedbounds"
32 #define SEPA_DESC "implied bounds separator"
33 #define SEPA_PRIORITY -50
34 #define SEPA_FREQ 10
35 #define SEPA_MAXBOUNDDIST 1.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 RELCUTCOEFMAXRANGE 1.0 /**< maximal allowed range of cut coefficients, relative to 1/feastol */
40 #define DEFAULT_USETWOSIZECLIQUES TRUE /**< should violated inequalities for cliques with 2 variables be separated? */
41 
42 /** separator-specific data for the implied bounds separator */
43 struct SCIP_SepaData
44 {
45  SCIP_Bool usetwosizecliques; /**< should violated inequalities for cliques with 2 variables be separated? */
46 };
47 
48 /*
49  * Local methods
50  */
51 
52 /** adds given cut with two variables, if it is violated */
53 static
55  SCIP* scip, /**< SCIP data structure */
56  SCIP_SEPA* sepa, /**< separator */
57  SCIP_Real val1, /**< given coefficient of first variable */
58  SCIP_VAR* var1, /**< given first variable */
59  SCIP_Real solval1, /**< current LP solution value of first variable */
60  SCIP_Real val2, /**< given coefficient of second variable */
61  SCIP_VAR* var2, /**< given second variable */
62  SCIP_Real solval2, /**< current LP solution value of second variable */
63  SCIP_Real rhs, /**< given right hand side of the cut to add */
64  SCIP_Bool* cutoff, /**< whether a cutoff has been detected */
65  int* ncuts /**< pointer to update number of cuts added */
66  )
67 {
68  SCIP_Real activity;
69 
70  assert(ncuts != NULL);
71  assert(cutoff != NULL);
72  *cutoff = FALSE;
73 
74  /* calculate activity of cut */
75  activity = val1 * solval1 + val2 * solval2;
76  /*SCIPdebugMsg(scip, " -> %g<%s>[%g] + %g<%s>[%g] <= %g (act: %g)\n",
77  val1, SCIPvarGetName(var1), solval1, val2, SCIPvarGetName(var2), solval2, rhs, activity);*/
78 
79  /* check, if cut is violated */
80  if( SCIPisEfficacious(scip, activity - rhs) )
81  {
82  SCIP_ROW* cut;
83  char cutname[SCIP_MAXSTRLEN];
84 
85  /* create cut */
86  (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "implbd%d_%d", SCIPgetNLPs(scip), *ncuts);
87  SCIP_CALL( SCIPcreateEmptyRowSepa(scip, &cut, sepa, cutname, -SCIPinfinity(scip), rhs, FALSE, FALSE, TRUE) );
88  SCIP_CALL( SCIPcacheRowExtensions(scip, cut) );
89  SCIP_CALL( SCIPaddVarToRow(scip, cut, var1, val1) );
90  SCIP_CALL( SCIPaddVarToRow(scip, cut, var2, val2) );
91  SCIP_CALL( SCIPflushRowExtensions(scip, cut) );
92  /* set cut rank: for implied bounds we always set to 1 */
93  SCIProwChgRank(cut, 1);
94 
95 #ifdef SCIP_DEBUG
96  SCIPdebugMsg(scip, " -> found cut (activity = %g): ", activity);
97  SCIP_CALL( SCIPprintRow(scip, cut, NULL) );
98 #endif
99 
100  SCIP_CALL( SCIPaddPoolCut(scip, cut) );
101  (*ncuts)++;
102 
103  /* release cut */
104  SCIP_CALL( SCIPreleaseRow(scip, &cut) );
105  }
106 
107  return SCIP_OKAY;
108 }
109 
110 /** searches and adds implied bound cuts that are violated by the given solution value array */
111 static
113  SCIP* scip, /**< SCIP data structure */
114  SCIP_SEPA* sepa, /**< separator */
115  SCIP_SOL* sol, /**< the solution that should be separated, or NULL for LP solution */
116  SCIP_Real* solvals, /**< array with solution values of all problem variables */
117  SCIP_VAR** fracvars, /**< array of fractional variables */
118  SCIP_Real* fracvals, /**< solution values of fractional variables */
119  int nfracs, /**< number of fractional variables */
120  SCIP_Bool* cutoff, /**< whether a cutoff has been detected */
121  int* ncuts /**< pointer to store the number of generated cuts */
122  )
123 {
124  SCIP_CLIQUE** cliques;
125  SCIP_SEPADATA* sepadata;
126  int ncliques;
127  int i;
128 
129  assert(solvals != NULL);
130  assert(fracvars != NULL || nfracs == 0);
131  assert(fracvals != NULL || nfracs == 0);
132  assert(cutoff != NULL);
133  assert(ncuts != NULL);
134 
135  *cutoff = FALSE;
136  *ncuts = 0;
137  sepadata = SCIPsepaGetData(sepa);
138  assert(sepadata != NULL);
139 
140  SCIPdebugMsg(scip, "searching for implied bound cuts\n");
141 
142  /* search binary variables for violated implications */
143  for( i = 0; i < nfracs; i++ )
144  {
145  SCIP_BOUNDTYPE* impltypes;
146  SCIP_Real* implbounds;
147  SCIP_VAR** implvars;
148  int nimpl;
149  int j;
150 
151  assert(fracvars != NULL);
152  assert(fracvals != NULL);
153 
154  /* only process binary variables */
155  if( SCIPvarGetType(fracvars[i]) != SCIP_VARTYPE_BINARY )
156  continue;
157 
158  /* get implications of x == 1 */
159  nimpl = SCIPvarGetNImpls(fracvars[i], TRUE);
160  implvars = SCIPvarGetImplVars(fracvars[i], TRUE);
161  impltypes = SCIPvarGetImplTypes(fracvars[i], TRUE);
162  implbounds = SCIPvarGetImplBounds(fracvars[i], TRUE);
163 
164  /*SCIPdebugMsg(scip, "%d implications for <%s>[%g] == 1\n", nimpl, SCIPvarGetName(fracvars[i]), fracvals[i]);*/
165 
166  /* try to add cuts for implications of x == 1
167  * x == 1 -> y <= p: y <= ub + x * (p - ub) <==> y + (ub - p) * x <= ub
168  * x == 1 -> y >= p: y >= lb + x * (p - lb) <==> -y + (p - lb) * x <= -lb
169  * with lb (ub) global lower (upper) bound of y
170  */
171  for( j = 0; j < nimpl; j++ )
172  {
173  SCIP_Real solval;
174 
175  assert(implvars != NULL);
176  assert(impltypes != NULL);
177  assert(implbounds != NULL);
178 
179  /* consider only implications with active implvar */
180  if( SCIPvarGetProbindex(implvars[j]) < 0 )
181  continue;
182 
183  solval = solvals[SCIPvarGetProbindex(implvars[j])];
184  if( impltypes[j] == SCIP_BOUNDTYPE_UPPER )
185  {
186  SCIP_Real ub;
187 
188  /* implication x == 1 -> y <= p */
189  ub = SCIPvarGetUbGlobal(implvars[j]);
190 
191  /* consider only nonredundant and numerical harmless implications */
192  if( SCIPisLE(scip, implbounds[j], ub) && (ub - implbounds[j]) * SCIPfeastol(scip) <= RELCUTCOEFMAXRANGE )
193  {
194  /* add cut if violated */
195  SCIP_CALL( addCut(scip, sepa, 1.0, implvars[j], solval, (ub - implbounds[j]), fracvars[i], fracvals[i],
196  ub, cutoff, ncuts) );
197  if ( *cutoff )
198  return SCIP_OKAY;
199  }
200  }
201  else
202  {
203  SCIP_Real lb;
204 
205  /* implication x == 1 -> y >= p */
206  lb = SCIPvarGetLbGlobal(implvars[j]);
207  assert(impltypes[j] == SCIP_BOUNDTYPE_LOWER);
208 
209  /* consider only nonredundant and numerical harmless implications */
210  if( SCIPisGE(scip, implbounds[j], lb) && (implbounds[j] - lb) * SCIPfeastol(scip) <= RELCUTCOEFMAXRANGE )
211  {
212  /* add cut if violated */
213  SCIP_CALL( addCut(scip, sepa, -1.0, implvars[j], solval, (implbounds[j] - lb), fracvars[i], fracvals[i],
214  -lb, cutoff, ncuts) );
215  if ( *cutoff )
216  return SCIP_OKAY;
217  }
218  }
219  }
220 
221  /* get implications of x == 0 */
222  nimpl = SCIPvarGetNImpls(fracvars[i], FALSE);
223  implvars = SCIPvarGetImplVars(fracvars[i], FALSE);
224  impltypes = SCIPvarGetImplTypes(fracvars[i], FALSE);
225  implbounds = SCIPvarGetImplBounds(fracvars[i], FALSE);
226 
227  /*SCIPdebugMsg(scip, "%d implications for <%s>[%g] == 0\n", nimpl, SCIPvarGetName(fracvars[i]), fracvals[i]);*/
228 
229  /* try to add cuts for implications of x == 0
230  * x == 0 -> y <= p: y <= p + x * (ub - p) <==> y + (p - ub) * x <= p
231  * x == 0 -> y >= p: y >= p + x * (lb - p) <==> -y + (lb - p) * x <= -p
232  * with lb (ub) global lower (upper) bound of y
233  */
234  for( j = 0; j < nimpl; j++ )
235  {
236  SCIP_Real solval;
237 
238  /* consider only implications with active implvar */
239  if( SCIPvarGetProbindex(implvars[j]) < 0 )
240  continue;
241 
242  solval = solvals[SCIPvarGetProbindex(implvars[j])];
243  if( impltypes[j] == SCIP_BOUNDTYPE_UPPER )
244  {
245  SCIP_Real ub;
246 
247  /* implication x == 0 -> y <= p */
248  ub = SCIPvarGetUbGlobal(implvars[j]);
249 
250  /* consider only nonredundant and numerical harmless implications */
251  if( SCIPisLE(scip, implbounds[j], ub) && (ub - implbounds[j]) * SCIPfeastol(scip) < RELCUTCOEFMAXRANGE )
252  {
253  /* add cut if violated */
254  SCIP_CALL( addCut(scip, sepa, 1.0, implvars[j], solval, (implbounds[j] - ub), fracvars[i], fracvals[i],
255  implbounds[j], cutoff, ncuts) );
256  if ( *cutoff )
257  return SCIP_OKAY;
258  }
259  }
260  else
261  {
262  SCIP_Real lb;
263 
264  /* implication x == 0 -> y >= p */
265  lb = SCIPvarGetLbGlobal(implvars[j]);
266  assert(impltypes[j] == SCIP_BOUNDTYPE_LOWER);
267 
268  /* consider only nonredundant and numerical harmless implications */
269  if( SCIPisGE(scip, implbounds[j], lb) && (implbounds[j] - lb) * SCIPfeastol(scip) < RELCUTCOEFMAXRANGE )
270  {
271  /* add cut if violated */
272  SCIP_CALL( addCut(scip, sepa, -1.0, implvars[j], solval, (lb - implbounds[j]), fracvars[i], fracvals[i],
273  -implbounds[j], cutoff, ncuts) );
274  if ( *cutoff )
275  return SCIP_OKAY;
276  }
277  }
278  }
279  }
280 
281  /* stop separation here if cliques should not be separated */
282  if( ! sepadata->usetwosizecliques )
283  return SCIP_OKAY;
284 
285  /* prepare clean clique data */
286  SCIP_CALL( SCIPcleanupCliques(scip, cutoff) );
287 
288  if( *cutoff )
289  return SCIP_OKAY;
290 
291  cliques = SCIPgetCliques(scip);
292  ncliques = SCIPgetNCliques(scip);
293 
294  /* loop over cliques of size 2 which are essentially implications and add cuts if they are violated */
295  for( i = 0; i < ncliques; ++i )
296  {
297  SCIP_CLIQUE* clique;
298  SCIP_VAR** clqvars;
299  SCIP_Bool* clqvals;
300  SCIP_Real rhs;
301 
302  clique = cliques[i];
303  /* only consider inequality cliques of size 2 */
304  if( SCIPcliqueGetNVars(clique) != 2 || SCIPcliqueIsEquation(clique) )
305  continue;
306 
307  /* get variables and values of the clique */
308  clqvars = SCIPcliqueGetVars(clique);
309  clqvals = SCIPcliqueGetValues(clique);
310 
311  /* clique variables should never be equal after clean up */
312  assert(clqvars[0] != clqvars[1]);
313 
314  /* calculate right hand side of clique inequality, which is initially 1 and decreased by 1 for every occurence of
315  * a negated variable in the clique
316  */
317  rhs = 1.0;
318  if( ! clqvals[0] )
319  rhs -= 1.0;
320  if( ! clqvals[1] )
321  rhs -= 1.0;
322 
323  /* Basic clique inequality is
324  *
325  * cx * x + (1-cx) (1-x) + cy * y + (1-cy) * (1-y) <= 1,
326  *
327  * where x and y are the two binary variables in the clique and cx and cy are their clique values, where a
328  * clique value of 0 means that the negation of the variable should be part of the inequality.
329  * Hence, exactly one of the two possible terms for x and y has a nonzero coefficient
330  */
331  SCIP_CALL( addCut(scip, sepa,
332  clqvals[0] ? 1.0 : -1.0, clqvars[0], SCIPgetSolVal(scip, sol, clqvars[0]),
333  clqvals[1] ? 1.0 : -1.0, clqvars[1], SCIPgetSolVal(scip, sol, clqvars[1]),
334  rhs, cutoff, ncuts) );
335 
336  /* terminate if cutoff was found */
337  if( *cutoff )
338  return SCIP_OKAY;
339  }
340 
341  return SCIP_OKAY;
342 }
343 
344 
345 /*
346  * Callback methods of separator
347  */
348 
349 /** copy method for separator plugins (called when SCIP copies plugins) */
350 static
351 SCIP_DECL_SEPACOPY(sepaCopyImpliedbounds)
352 { /*lint --e{715}*/
353  assert(scip != NULL);
354  assert(sepa != NULL);
355  assert(strcmp(SCIPsepaGetName(sepa), SEPA_NAME) == 0);
356 
357  /* call inclusion method of constraint handler */
359 
360  return SCIP_OKAY;
361 }
362 
363 /** destructor of separator to free user data (called when SCIP is exiting) */
364 static
365 SCIP_DECL_SEPAFREE(sepaFreeImpliedbounds)
366 { /*lint --e{715}*/
367  SCIP_SEPADATA* sepadata;
368 
369  assert(scip != NULL);
370  assert(sepa != NULL);
371  assert(strcmp(SCIPsepaGetName(sepa), SEPA_NAME) == 0);
372 
373  /* get separation data and free it */
374  sepadata = SCIPsepaGetData(sepa);
375  assert(sepadata != NULL);
376  SCIPfreeBlockMemory(scip, &sepadata);
377 
378  /* reset data pointer to NULL */
379  SCIPsepaSetData(sepa, NULL);
380 
381  return SCIP_OKAY;
382 }
383 
384 
385 /** LP solution separation method of separator */
386 static
387 SCIP_DECL_SEPAEXECLP(sepaExeclpImpliedbounds)
388 { /*lint --e{715}*/
389  SCIP_VAR** vars;
390  SCIP_VAR** fracvars;
391  SCIP_Real* solvals;
392  SCIP_Real* fracvals;
393  SCIP_Bool cutoff;
394  int nvars;
395  int nbinvars;
396  int nfracs;
397  int ncuts;
398 
399  assert(sepa != NULL);
400  assert(scip != NULL);
401 
402  *result = SCIP_DIDNOTRUN;
403 
404  /* gets active problem variables */
405  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, NULL, NULL, NULL) );
406  if( nbinvars == 0 )
407  return SCIP_OKAY;
408 
409  /* get fractional problem variables */
410  /* todo try out also separating fractional implicit integer variables */
411  SCIP_CALL( SCIPgetLPBranchCands(scip, &fracvars, &fracvals, NULL, &nfracs, NULL, NULL) );
412  if( nfracs == 0 )
413  return SCIP_OKAY;
414 
415  /* get solution values for all variables */
416  SCIP_CALL( SCIPallocBufferArray(scip, &solvals, nvars) );
417  SCIP_CALL( SCIPgetVarSols(scip, nvars, vars, solvals) );
418 
419  /* call the cut separation */
420  SCIP_CALL( separateCuts(scip, sepa, NULL, solvals, fracvars, fracvals, nfracs, &cutoff, &ncuts) );
421 
422  /* adjust result code */
423  if ( cutoff )
424  *result = SCIP_CUTOFF;
425  else if ( ncuts > 0 )
426  *result = SCIP_SEPARATED;
427  else
428  *result = SCIP_DIDNOTFIND;
429 
430  /* free temporary memory */
431  SCIPfreeBufferArray(scip, &solvals);
432 
433  return SCIP_OKAY;
434 }
435 
436 
437 /** arbitrary primal solution separation method of separator */
438 static
439 SCIP_DECL_SEPAEXECSOL(sepaExecsolImpliedbounds)
440 { /*lint --e{715}*/
441  SCIP_VAR** vars;
442  SCIP_VAR** fracvars;
443  SCIP_Real* solvals;
444  SCIP_Real* fracvals;
445  SCIP_Bool cutoff;
446  int nvars;
447  int nbinvars;
448  int nfracs;
449  int ncuts;
450  int i;
451 
452  assert(sepa != NULL);
453  assert(scip != NULL);
454 
455  *result = SCIP_DIDNOTRUN;
456 
457  /* gets active problem variables */
458  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, NULL, NULL, NULL) );
459  if( nbinvars == 0 )
460  return SCIP_OKAY;
461 
462  /* get solution values for all variables */
463  SCIP_CALL( SCIPallocBufferArray(scip, &solvals, nvars) );
464  SCIP_CALL( SCIPgetSolVals(scip, sol, nvars, vars, solvals) );
465 
466  /* get binary problem variables that are fractional in given solution */
467  SCIP_CALL( SCIPallocBufferArray(scip, &fracvars, nbinvars) );
468  SCIP_CALL( SCIPallocBufferArray(scip, &fracvals, nbinvars) );
469  nfracs = 0;
470  for( i = 0; i < nbinvars; ++i )
471  {
472  if( !SCIPisFeasIntegral(scip, solvals[i]) )
473  {
474  fracvars[nfracs] = vars[i];
475  fracvals[nfracs] = solvals[i];
476  nfracs++;
477  }
478  }
479 
480  /* call the cut separation */
481  ncuts = 0;
482  cutoff = FALSE;
483 
484  if( nfracs > 0 )
485  {
486  SCIP_CALL( separateCuts(scip, sepa, sol, solvals, fracvars, fracvals, nfracs, &cutoff, &ncuts) );
487  }
488 
489  /* adjust result code */
490  if ( cutoff )
491  *result = SCIP_CUTOFF;
492  else if ( ncuts > 0 )
493  *result = SCIP_SEPARATED;
494  else
495  *result = SCIP_DIDNOTFIND;
496 
497  /* free temporary memory */
498  SCIPfreeBufferArray(scip, &fracvals);
499  SCIPfreeBufferArray(scip, &fracvars);
500  SCIPfreeBufferArray(scip, &solvals);
501 
502  return SCIP_OKAY;
503 }
504 
505 
506 /*
507  * separator specific interface methods
508  */
509 
510 /** creates the impliedbounds separator and includes it in SCIP */
512  SCIP* scip /**< SCIP data structure */
513  )
514 {
515  SCIP_SEPADATA* sepadata;
516  SCIP_SEPA* sepa;
517 
518  /* create impliedbounds separator data */
519  SCIP_CALL( SCIPallocBlockMemory(scip, &sepadata) );
520  assert(sepadata != NULL);
521 
522  /* include separator */
525  sepaExeclpImpliedbounds, sepaExecsolImpliedbounds,
526  sepadata) );
527  assert(sepa != NULL);
528 
529  /* set non-NULL pointers to callback methods */
530  SCIP_CALL( SCIPsetSepaCopy(scip, sepa, sepaCopyImpliedbounds) );
531  SCIP_CALL( SCIPsetSepaFree(scip, sepa, sepaFreeImpliedbounds) );
532 
533  /* add separator parameters */
534  SCIP_CALL( SCIPaddBoolParam(scip, "separating/impliedbounds/usetwosizecliques",
535  "should violated inequalities for cliques with 2 variables be separated?",
536  &sepadata->usetwosizecliques, TRUE, DEFAULT_USETWOSIZECLIQUES, NULL, NULL) );
537 
538  return SCIP_OKAY;
539 }
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
Definition: scip.c:37001
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
static SCIP_DECL_SEPAEXECLP(sepaExeclpImpliedbounds)
SCIP_Real SCIPfeastol(SCIP *scip)
Definition: scip.c:46443
SCIP_VAR ** SCIPcliqueGetVars(SCIP_CLIQUE *clique)
Definition: implics.c:3353
SCIP_RETCODE SCIPcacheRowExtensions(SCIP *scip, SCIP_ROW *row)
Definition: scip.c:30613
SCIP_RETCODE SCIPflushRowExtensions(SCIP *scip, SCIP_ROW *row)
Definition: scip.c:30636
static SCIP_DECL_SEPAFREE(sepaFreeImpliedbounds)
#define SEPA_MAXBOUNDDIST
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17276
#define SCIP_MAXSTRLEN
Definition: def.h:259
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition: scip.c:30668
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:47015
#define SEPA_PRIORITY
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip.c:11686
#define FALSE
Definition: def.h:64
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:47028
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10011
#define SEPA_DELAY
#define TRUE
Definition: def.h:63
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
Definition: sepa.c:646
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Bool SCIPcliqueIsEquation(SCIP_CLIQUE *clique)
Definition: implics.c:3409
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16969
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip.h:22602
static SCIP_RETCODE addCut(SCIP *scip, SCIP_SEPA *sepa, SCIP_Real val1, SCIP_VAR *var1, SCIP_Real solval1, SCIP_Real val2, SCIP_VAR *var2, SCIP_Real solval2, SCIP_Real rhs, SCIP_Bool *cutoff, int *ncuts)
#define SEPA_USESSUBSCIP
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:22632
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip.h:22585
SCIP_RETCODE SCIPsetSepaCopy(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPACOPY((*sepacopy)))
Definition: scip.c:7427
#define SCIPdebugMsg
Definition: scip.h:455
#define DEFAULT_USETWOSIZECLIQUES
SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
Definition: sepa.c:557
#define SEPA_FREQ
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17286
SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip.c:38948
SCIP_RETCODE SCIPincludeSepaImpliedbounds(SCIP *scip)
SCIP_Bool SCIPisEfficacious(SCIP *scip, SCIP_Real efficacy)
Definition: scip.c:34546
void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
Definition: sepa.c:567
#define SCIP_CALL(x)
Definition: def.h:350
#define RELCUTCOEFMAXRANGE
static SCIP_DECL_SEPAEXECSOL(sepaExecsolImpliedbounds)
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:7385
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:22620
public data structures and miscellaneous methods
SCIP_BOUNDTYPE * SCIPvarGetImplTypes(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:17586
#define SCIP_Bool
Definition: def.h:61
#define SEPA_DESC
int SCIPvarGetNImpls(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:17554
SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
Definition: scip.c:34772
SCIP_Bool * SCIPcliqueGetValues(SCIP_CLIQUE *clique)
Definition: implics.c:3365
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:30431
SCIP_Real * SCIPvarGetImplBounds(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:17600
SCIP_VAR ** SCIPvarGetImplVars(SCIP_VAR *var, SCIP_Bool varfixing)
Definition: var.c:17571
SCIP_CLIQUE ** SCIPgetCliques(SCIP *scip)
Definition: scip.c:24933
implied bounds separator
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip.c:30540
SCIP_RETCODE SCIPsetSepaFree(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAFREE((*sepafree)))
Definition: scip.c:7443
SCIP_RETCODE SCIPgetVarSols(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip.c:19852
void SCIProwChgRank(SCIP_ROW *row, int rank)
Definition: lp.c:16706
static SCIP_DECL_SEPACOPY(sepaCopyImpliedbounds)
int SCIPgetNCliques(SCIP *scip)
Definition: scip.c:24879
#define SCIP_Real
Definition: def.h:149
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
Definition: scip.c:31160
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:16827
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46989
int SCIPcliqueGetNVars(SCIP_CLIQUE *clique)
Definition: implics.c:3343
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:47399
#define SEPA_NAME
SCIP_RETCODE SCIPcleanupCliques(SCIP *scip, SCIP_Bool *infeasible)
Definition: scip.c:24836
SCIP_Longint SCIPgetNLPs(SCIP *scip)
Definition: scip.c:42314
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip.c:38911
struct SCIP_SepaData SCIP_SEPADATA
Definition: type_sepa.h:38
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:4239
static SCIP_RETCODE separateCuts(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_Real *solvals, SCIP_VAR **fracvars, SCIP_Real *fracvals, int nfracs, SCIP_Bool *cutoff, int *ncuts)