Scippy

SCIP

Solving Constraint Integer Programs

sepa_edge.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-2023 Zuse Institute Berlin (ZIB) */
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 sepa_edge.c
26  * @brief edge-separator. Separates triangle-inequalities in cycle clustering problem
27  * @author Leon Eifler
28  */
29 
30 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
31 #include <assert.h>
32 #include <string.h>
33 
34 #include "sepa_edge.h"
35 
36 #include "probdata_cyc.h"
37 #include "scip/cutsel_hybrid.h"
38 
39 #define SEPA_NAME "edge"
40 #define SEPA_DESC "separator to separate triangle-inequalities in cycle-clustering application"
41 #define SEPA_PRIORITY 5000
42 #define SEPA_FREQ 5
43 #define SEPA_MAXBOUNDDIST 0.0
44 #define SEPA_USESSUBSCIP FALSE /**< does the separator use a secondary SCIP instance? */
45 #define SEPA_DELAY FALSE /**< should separation method be delayed, if other separators found cuts? */
46 #define MAXCUTS 2000 /**< maximal number of cuts that can be added to cut pool */
47 #define MAXCUTSCREATED 10000 /**< maximal number of cuts to select from */
48 #define MAXROUNDS 20
49 
50 /** copy method for separator plugins (called when SCIP copies plugins) */
51 static
52 SCIP_DECL_SEPACOPY(sepaCopyEdge)
53 { /*lint --e{715}*/
54  assert(scip != NULL);
55  assert(sepa != NULL);
56  assert(strcmp(SCIPsepaGetName(sepa), SEPA_NAME) == 0);
57 
58  /* call inclusion method of constraint handler */
60 
61  return SCIP_OKAY;
62 }
63 
64 /** LP solution separation method of separator */
65 static
66 SCIP_DECL_SEPAEXECLP(sepaExeclpEdge)
67 { /*lint --e{715}*/
68  SCIP_VAR**** edgevars; /* edgevars from probdata */
69  SCIP_DIGRAPH* edgegraph; /* edgegraph from probdata */
70  char cutname[SCIP_MAXSTRLEN]; /* name of the cut */
71  SCIP_Real** sign; /* matrix of sign-permuations */
72  SCIP_Real* violation; /* array of violations */
73  SCIP_ROW** cuts; /* array of generated cuts */
74  SCIP_Real goodscorefac; /* parameters for cut-selection */
75  SCIP_Real badscorefac;
76  SCIP_Real goodmaxparall;
77  SCIP_Real maxparall;
78  SCIP_Real dircutoffdist;
79  SCIP_Real efficacyweight;
80  SCIP_Real objparalweight;
81  SCIP_Real intsuppweight;
82  int* succs1; /* successors of first state */
83  int* succs2; /* successors of second state */
84  int nstates; /* number of states */
85  int ncutscreated; /* number of generated cuts */
86  int ncutsapplied; /* number of cuts that were added to the pool */
87  int size; /* size of the cuts-array */
88  int rounds; /* number of separation rounds */
89  int states[3]; /* states in a triangle */
90  int nsuccs1; /* number of successors */
91  int nsuccs2;
92  int j; /* running indices */
93  int k;
94  int l;
95  SCIP_Bool usecutselection; /* should cut selection be uses */
96 
97  rounds = SCIPsepaGetNCallsAtNode(sepa);
98  if( rounds >= MAXROUNDS )
99  {
100  *result = SCIP_DIDNOTRUN;
101  return SCIP_OKAY;
102  }
103 
104  edgegraph = SCIPcycGetEdgeGraph(scip);
105  edgevars = SCIPcycGetEdgevars(scip);
106  nstates = SCIPcycGetNBins(scip);
107 
108  assert(nstates > 0);
109  assert(NULL != edgevars);
110  assert(NULL != edgegraph);
111 
112  ncutscreated = 0;
113  ncutsapplied = 0;
114  size = MAXCUTS;
115  *result = SCIP_DIDNOTFIND;
116 
117  SCIP_CALL( SCIPgetBoolParam(scip, "cycleclustering/usecutselection", &usecutselection) );
118 
119  SCIP_CALL( SCIPallocClearBufferArray(scip, &violation, size) );
120  SCIP_CALL( SCIPallocBufferArray(scip, &cuts, size) );
122 
123  /* for some inequalities, you can swap the minus sign to any variable of the triangle */
124  for( j = 0; j < 3; ++j )
125  {
126  SCIP_CALL( SCIPallocMemoryArray(scip, &sign[j], 3) ); /*lint !e866*/
127 
128  for( k = 0; k < 3; ++k )
129  {
130  sign[j][k] = 1.0;
131  }
132  sign[j][j] = -1.0;
133  }
134 
135  if( SCIPcycGetNCluster(scip) > 3 )
136  {
137  /* separate edges by the valid inequality z_ij1 + z_ik1 - y_jk0 <= 1 and z_ji + z_ki - y_jk1 <= 1
138  * (minus sign can be anywhere)
139  */
140  for( states[0] = 0; states[0] < nstates && ncutscreated < MAXCUTSCREATED; ++states[0] )
141  {
142  succs1 = SCIPdigraphGetSuccessors(edgegraph, states[0]);
143  nsuccs1 = SCIPdigraphGetNSuccessors(edgegraph, states[0]);
144 
145  for( j = 0; j < nsuccs1 && ncutscreated < MAXCUTSCREATED; ++j )
146  {
147  states[1] = succs1[j];
148  succs2 = SCIPdigraphGetSuccessors(edgegraph, states[1]);
149  nsuccs2 = SCIPdigraphGetNSuccessors(edgegraph, states[1]);
150 
151  for( k = 0; k < nsuccs2 && ncutscreated < MAXCUTSCREATED; ++k )
152  {
153  states[2] = succs2[k];
154 
155  if( !edgesExist(edgevars, states, 3) )
156  continue;
157 
158  if( (states[0] != states[1] && states[0] != states[2] && states[1] > states[2]) )
159  {
160  /* permute the minus sign */
161  for( l = 0; l < 3 ; ++l )
162  {
163  violation[ncutscreated] = sign[l][0]
164  * SCIPvarGetLPSol(getEdgevar(edgevars, states[0], states[1], 1));
165  violation[ncutscreated] += sign[l][1]
166  * SCIPvarGetLPSol(getEdgevar(edgevars, states[0], states[2], 1));
167  violation[ncutscreated] += sign[l][2]
168  * SCIPvarGetLPSol(getEdgevar(edgevars, states[1], states[2], 0)) - 1;
169 
170  if( violation[ncutscreated] > 0 )
171  {
172  (void)SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "trianglefw_%d_%d_%d_%d", states[0], states[1], states[2], l );
173  SCIP_CALL( SCIPcreateEmptyRowSepa(scip, &(cuts[ncutscreated]), sepa, cutname,
174  -SCIPinfinity(scip), 1.0, FALSE, FALSE, TRUE) );
175 
176  SCIP_CALL( SCIPcacheRowExtensions(scip, cuts[ncutscreated]) );
177 
178  SCIP_CALL( SCIPaddVarToRow(scip, cuts[ncutscreated],
179  getEdgevar(edgevars, states[1], states[2], 0), sign[l][2]) );
180  SCIP_CALL( SCIPaddVarToRow(scip, cuts[ncutscreated],
181  getEdgevar(edgevars, states[0], states[1], 1), sign[l][0]) );
182  SCIP_CALL( SCIPaddVarToRow(scip, cuts[ncutscreated],
183  getEdgevar(edgevars, states[0], states[2], 1), sign[l][1]) );
184 
185  SCIP_CALL( SCIPflushRowExtensions(scip, cuts[ncutscreated]) );
186 
187  if( ncutscreated >= size - 1 )
188  {
189  SCIP_CALL( SCIPreallocBufferArray(scip, &violation, (int) (size + MAXCUTS)) );
190  SCIP_CALL( SCIPreallocBufferArray(scip, &cuts, (int) (size + MAXCUTS)) );
191  size += MAXCUTS;
192  }
193 
194  ncutscreated++;
195  }
196 
197  violation[ncutscreated] = sign[l][0]
198  * SCIPvarGetLPSol(getEdgevar(edgevars, states[1], states[0], 1));
199  violation[ncutscreated] += sign[l][1]
200  * SCIPvarGetLPSol(getEdgevar(edgevars, states[2], states[0], 1));
201  violation[ncutscreated] += sign[l][2]
202  * SCIPvarGetLPSol(getEdgevar(edgevars, states[1], states[2], 0)) - 1;
203 
204  if( violation[ncutscreated] > 0)
205  {
206  (void)SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "trianglebw_%d_%d_%d_%d", states[0], states[1], states[2], l );
207  SCIP_CALL( SCIPcreateEmptyRowSepa(scip, &(cuts[ncutscreated]), sepa, cutname,
208  -SCIPinfinity(scip), 1.0, FALSE, FALSE, TRUE) );
209 
210  SCIP_CALL( SCIPcacheRowExtensions(scip, cuts[ncutscreated]) );
211 
212  SCIP_CALL( SCIPaddVarToRow(scip, cuts[ncutscreated],
213  getEdgevar(edgevars, states[1], states[2], 0), sign[l][2]) );
214  SCIP_CALL( SCIPaddVarToRow(scip, cuts[ncutscreated],
215  getEdgevar(edgevars, states[1], states[0], 1), sign[l][0]) );
216  SCIP_CALL( SCIPaddVarToRow(scip, cuts[ncutscreated],
217  getEdgevar(edgevars, states[2], states[0], 1), sign[l][1]) );
218 
219  SCIP_CALL( SCIPflushRowExtensions(scip, cuts[ncutscreated]) );
220 
221  if( ncutscreated >= size - 1 )
222  {
223  SCIP_CALL( SCIPreallocBufferArray(scip, &violation, (int) (size + MAXCUTS)) );
224  SCIP_CALL( SCIPreallocBufferArray(scip, &cuts, (int) (size + MAXCUTS)) );
225  size += MAXCUTS;
226  }
227 
228  ncutscreated++;
229  }
230  }
231  }
232 
233  if( states[0] > states[1] && states[1] > states[2] )
234  {
235  for( l = 0; l < 3; ++l )
236  {
237  violation[ncutscreated] = sign[l][0]
238  * SCIPvarGetLPSol(getEdgevar(edgevars, states[0], states[1], 0));
239  violation[ncutscreated] += sign[l][1]
240  * SCIPvarGetLPSol(getEdgevar(edgevars, states[0], states[2], 0));
241  violation[ncutscreated] += sign[l][2]
242  * SCIPvarGetLPSol(getEdgevar(edgevars, states[1], states[2], 0)) - 1;
243 
244  if( violation[ncutscreated] > 0 )
245  {
246  (void)SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "edgecut_%d_%d_%d", states[0], states[1], states[2]);
247  SCIP_CALL( SCIPcreateEmptyRowSepa(scip, &(cuts[ncutscreated]), sepa, cutname,
248  -SCIPinfinity(scip), 1.0, FALSE, FALSE, TRUE) );
249  SCIP_CALL( SCIPaddVarToRow(scip, cuts[ncutscreated],
250  getEdgevar(edgevars, states[0], states[1], 0), sign[l][0]) );
251  SCIP_CALL( SCIPaddVarToRow(scip, cuts[ncutscreated],
252  getEdgevar(edgevars, states[0], states[2], 0), sign[l][1]) );
253  SCIP_CALL( SCIPaddVarToRow(scip, cuts[ncutscreated],
254  getEdgevar(edgevars, states[1], states[2], 0), sign[l][2]) );
255 
256  if( ncutscreated >= size - 1 )
257  {
258  SCIP_CALL( SCIPreallocBufferArray(scip, &violation, (int) (size + MAXCUTS)) );
259  SCIP_CALL( SCIPreallocBufferArray(scip, &cuts, (int) (size + MAXCUTS)) );
260  size += MAXCUTS;
261  }
262 
263  ncutscreated++;
264  }
265  }
266  }
267  }
268  }
269  }
270  }
271 
272  if( SCIPcycGetNCluster(scip) == 3 )
273  {
274  for( states[0] = 0; states[0] < nstates; ++states[0] )
275  {
276  succs1 = SCIPdigraphGetSuccessors(edgegraph, states[0]);
277  nsuccs1 = SCIPdigraphGetNSuccessors(edgegraph, states[0]);
278 
279  for( j = 0; j < nsuccs1 && ncutscreated < MAXCUTSCREATED; ++j )
280  {
281  states[1] = succs1[j];
282  succs2 = SCIPdigraphGetSuccessors(edgegraph, states[1]);
283  nsuccs2 = SCIPdigraphGetNSuccessors(edgegraph, states[1]);
284 
285  for( k = 0; k < nsuccs2 && ncutscreated < MAXCUTSCREATED; ++k )
286  {
287  states[2] = succs2[k];
288 
289  if( !edgesExist(edgevars, states, 3) )
290  continue;
291 
292  violation[ncutscreated] = SCIPvarGetLPSol(getEdgevar(edgevars, states[0], states[1], 1));
293  violation[ncutscreated] += SCIPvarGetLPSol(getEdgevar(edgevars, states[1], states[2], 1));
294  violation[ncutscreated] -= SCIPvarGetLPSol(getEdgevar(edgevars, states[2], states[0], 1)) - 1;
295 
296  if( violation[ncutscreated] > 0 )
297  {
298  (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "edgecut_%d_%d_%d", states[0], states[1], states[2]);
299  SCIP_CALL( SCIPcreateEmptyRowSepa(scip, &(cuts[ncutscreated]), sepa, cutname,
300  -SCIPinfinity(scip), 1.0, FALSE, FALSE, TRUE) );
301 
302  SCIP_CALL( SCIPcacheRowExtensions(scip, cuts[ncutscreated]) );
303 
304  SCIP_CALL( SCIPaddVarToRow(scip, cuts[ncutscreated],
305  getEdgevar(edgevars, states[0], states[1], 1), 1.0) );
306  SCIP_CALL( SCIPaddVarToRow(scip, cuts[ncutscreated],
307  getEdgevar(edgevars, states[1], states[2], 1), 1.0) );
308  SCIP_CALL( SCIPaddVarToRow(scip, cuts[ncutscreated],
309  getEdgevar(edgevars, states[2], states[0], 1), -1.0) );
310 
311  SCIP_CALL( SCIPflushRowExtensions(scip, cuts[ncutscreated]) );
312 
313  if( ncutscreated >= size - 1 )
314  {
315  SCIP_CALL( SCIPreallocBufferArray(scip, &violation, (int) (size + MAXCUTS)) );
316  SCIP_CALL( SCIPreallocBufferArray(scip, &cuts, (int) (size + MAXCUTS)) );
317  size += MAXCUTS;
318  }
319 
320  ncutscreated++;
321  }
322  }
323  }
324  }
325  }
326 
327  if( ncutscreated > 0 )
328  {
329  /* apply the cuts with the highest violation or use cut-selection */
330  if( usecutselection )
331  {
332  SCIP_CALL( SCIPgetRealParam(scip, "cycleclustering/goodscorefac", &goodscorefac) );
333  SCIP_CALL( SCIPgetRealParam(scip, "cycleclustering/badscorefac", &badscorefac) );
334  SCIP_CALL( SCIPgetRealParam(scip, "cycleclustering/goodmaxparall", &goodmaxparall) );
335  SCIP_CALL( SCIPgetRealParam(scip, "cycleclustering/maxparall", &maxparall) );
336  SCIP_CALL( SCIPgetRealParam(scip, "cycleclustering/dircutoffdist", &dircutoffdist) );
337  SCIP_CALL( SCIPgetRealParam(scip, "cycleclustering/efficacyweight", &efficacyweight) );
338  SCIP_CALL( SCIPgetRealParam(scip, "cycleclustering/objparalweight", &objparalweight) );
339  SCIP_CALL( SCIPgetRealParam(scip, "cycleclustering/intsuppweight", &intsuppweight) );
340 
341  SCIP_CALL( SCIPselectCutsHybrid(scip, cuts, NULL, NULL, goodscorefac, badscorefac,
342  goodmaxparall, maxparall, dircutoffdist, efficacyweight, objparalweight, intsuppweight,
343  ncutscreated, 0, MAXCUTS, &ncutsapplied) );
344  }
345  else
346  {
347  SCIPsortDownRealPtr(violation, ((void **) cuts), ncutscreated);
348  ncutsapplied = MIN(ncutscreated, MAXCUTS);
349  }
350 
351  for( j = 0; j < ncutsapplied; ++j )
352  {
353  SCIP_CALL( SCIPaddPoolCut(scip, cuts[j]) );
354  *result = SCIP_SEPARATED;
355  }
356  }
357 
358  /* free memory */
359  for( j = 0; j < ncutscreated; ++j )
360  {
361  SCIP_CALL( SCIPreleaseRow(scip, &(cuts[j])) );
362  }
363  SCIPfreeBufferArray(scip, &cuts);
364  SCIPfreeBufferArray(scip, &violation);
365  for( j = 0; j < 3; ++j )
366  {
367  SCIPfreeMemoryArray(scip, &sign[j]);
368  }
369  SCIPfreeMemoryArray(scip, &sign);
370 
371  return SCIP_OKAY;
372 }
373 
374 /** creates the Edge separator and includes it in SCIP */
376  SCIP* scip /**< SCIP data structure */
377  )
378 {
379  SCIP_SEPA* sepa;
380 
381  /* include separator */
384  sepaExeclpEdge, NULL,
385  NULL) );
386 
387  assert(sepa != NULL);
388 
389  /* set non fundamental callbacks via setter functions */
390  SCIP_CALL( SCIPsetSepaCopy(scip, sepa, sepaCopyEdge) );
391 
392  return SCIP_OKAY;
393 }
SCIP_RETCODE SCIPcacheRowExtensions(SCIP *scip, SCIP_ROW *row)
Definition: scip_lp.c:1635
#define SEPA_DESC
Definition: sepa_edge.c:40
SCIP_RETCODE SCIPflushRowExtensions(SCIP *scip, SCIP_ROW *row)
Definition: scip_lp.c:1658
#define SCIPallocClearBufferArray(scip, ptr, num)
Definition: scip_mem.h:126
#define SEPA_USESSUBSCIP
Definition: sepa_edge.c:44
#define SCIPfreeMemoryArray(scip, ptr)
Definition: scip_mem.h:80
SCIP_VAR * getEdgevar(SCIP_VAR ****edgevars, int state1, int state2, int direction)
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition: scip_param.c:307
#define SCIP_MAXSTRLEN
Definition: def.h:302
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition: scip_lp.c:1698
hybrid cut selector
SCIP_RETCODE SCIPincludeSepaEdge(SCIP *scip)
Definition: sepa_edge.c:375
int * SCIPdigraphGetSuccessors(SCIP_DIGRAPH *digraph, int node)
Definition: misc.c:7731
#define SCIPallocMemoryArray(scip, ptr, num)
Definition: scip_mem.h:64
void SCIPsortDownRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
#define SEPA_NAME
Definition: sepa_edge.c:39
SCIP_VAR **** SCIPcycGetEdgevars(SCIP *scip)
#define FALSE
Definition: def.h:96
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10788
#define TRUE
Definition: def.h:95
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
Definition: sepa.c:743
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
static SCIP_DECL_SEPAEXECLP(sepaExeclpEdge)
Definition: sepa_edge.c:66
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
SCIP_RETCODE SCIPsetSepaCopy(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPACOPY((*sepacopy)))
Definition: scip_sepa.c:151
#define SCIPallocClearMemoryArray(scip, ptr, num)
Definition: scip_mem.h:66
#define SEPA_FREQ
Definition: sepa_edge.c:42
edge-separator. Separates triangle-inequalities in cycle clustering problem
#define MAXCUTSCREATED
Definition: sepa_edge.c:47
int SCIPsepaGetNCallsAtNode(SCIP_SEPA *sepa)
Definition: sepa.c:880
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:250
#define NULL
Definition: lpi_spx1.cpp:164
SCIP_Bool edgesExist(SCIP_VAR ****edgevars, int *states, int nstates)
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:18297
static SCIP_DECL_SEPACOPY(sepaCopyEdge)
Definition: sepa_edge.c:52
#define SCIP_CALL(x)
Definition: def.h:394
int SCIPcycGetNBins(SCIP *scip)
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_sepa.c:109
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
int SCIPdigraphGetNSuccessors(SCIP_DIGRAPH *digraph, int node)
Definition: misc.c:7716
#define SCIP_Bool
Definition: def.h:93
#define MAXROUNDS
Definition: sepa_edge.c:48
SCIP_RETCODE SCIPselectCutsHybrid(SCIP *scip, SCIP_ROW **cuts, SCIP_ROW **forcedcuts, SCIP_RANDNUMGEN *randnumgen, SCIP_Real goodscorefac, SCIP_Real badscorefac, SCIP_Real goodmaxparall, SCIP_Real maxparall, SCIP_Real dircutoffdistweight, SCIP_Real efficacyweight, SCIP_Real objparalweight, SCIP_Real intsupportweight, int ncuts, int nforcedcuts, int maxselectedcuts, int *nselectedcuts)
SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
Definition: scip_cut.c:361
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_lp.c:1453
problem data for cycle clustering problem
#define MAXCUTS
Definition: sepa_edge.c:46
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip_lp.c:1562
int SCIPcycGetNCluster(SCIP *scip)
SCIP_DIGRAPH * SCIPcycGetEdgeGraph(SCIP *scip)
#define SCIP_Real
Definition: def.h:186
#define SEPA_DELAY
Definition: sepa_edge.c:45
#define SEPA_MAXBOUNDDIST
Definition: sepa_edge.c:43
#define SEPA_PRIORITY
Definition: sepa_edge.c:41
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:128