SCIP Doxygen Documentation
Loading...
Searching...
No Matches
branch_gomory.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-2026 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 branch_gomory.c
26 * @ingroup DEFPLUGINS_BRANCH
27 * @brief Gomory cut branching rule
28 * @author Mark Turner
29 *
30 * The approach is based on the following papers.
31 *
32 * M. Turner, T. Berthold, M. Besancon, T. Koch@n
33 * Branching via Cutting Plane Selection: Improving Hybrid Branching,@n
34 * arXiv preprint arXiv:2306.06050
35 *
36 * The Gomory cut branching rule selects a candidate integer variable $j$ with a fractional solution value.
37 * Each candidate variable must be a basic variable in the LP Tableau (if not then it would have to be at its bound
38 * that is integer-valued)
39 * This branching rule calculates the GMI cut for the aggregated row of the LP tableau associated with the
40 * candidate variable.
41 * The generated cut is then scored using a weighted sum rule.
42 * The branching candidate whose cut is highest scoring is then selected.
43 * For more details on the method, see:
44 *
45 * @par
46 * Mark Turner, Timo Berthold, Mathieu Besançon, Thorsten Koch@n
47 * Branching via Cutting Plane Selection: Improving Hybrid Branching@n
48 * 2023@n
49 */
50
51/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
52
53#include "scip/branch_gomory.h"
54#include "scip/pub_branch.h"
55#include "scip/pub_var.h"
56#include "scip/pub_lp.h"
57#include "scip/pub_tree.h"
58#include "scip/pub_message.h"
59#include "scip/scip_branch.h"
60#include "scip/scip_cut.h"
61#include "scip/scip_mem.h"
62#include "scip/scip_message.h"
63#include "scip/scip_numerics.h"
64#include "scip/scip_lp.h"
65#include "scip/scip_tree.h"
66#include "scip/scip_param.h"
68
69
70#define BRANCHRULE_NAME "gomory"
71#define BRANCHRULE_DESC "Gomory cut score branching"
72#define BRANCHRULE_PRIORITY -1000
73#define BRANCHRULE_MAXDEPTH -1
74#define BRANCHRULE_MAXBOUNDDIST 1.0
75
76#define DEFAULT_MAXNCANDS -1 /**< maximum number of branching candidates to produce a cut for */
77#define DEFAULT_EFFICACYWEIGHT 1.0 /**< the weight of efficacy in weighted sum cut scoring rule */
78#define DEFAULT_OBJPARALLELWEIGHT 0.0 /**< the weight of objective parallelism in weighted sum scoring rule */
79#define DEFAULT_INTSUPPORTWEIGHT 0.0 /**< the weight of integer support in weighted sum cut scoring rule */
80#define DEFAULT_PERFORMRELPSCOST FALSE /**< if relpscost branching should be called without actual branching */
81#define DEFAULT_USEWEAKERCUTS TRUE /**< use weaker cuts derived from the exact branching split */
82
83
84/*
85 * Data structures
86 */
87
88/** branching rule data */
89struct SCIP_BranchruleData
90{
91 int maxncands; /**< maximum number of variable candidates to produce cut for */
92 SCIP_Real efficacyweight; /**< the weight of efficacy in weighted sum cut scoring rule */
93 SCIP_Real objparallelweight; /**< the weight of objective parallelism in weighted sum scoring rule */
94 SCIP_Real intsupportweight; /**< the weight of integer support in weighted sum cut scoring rule */
95 SCIP_Bool performrelpscost; /**< if relpscost branching should be called without actual branching */
96 SCIP_Bool useweakercuts; /**< use weaker cuts derived from the exact branching split */
97};
98
99
100/*
101 * Local methods
102 */
103
104/** Generate GMI cut: The GMI is given by
105 * sum(f_j x_j , j in J_I s.t. f_j <= f_0) +
106 * sum((1-f_j)*f_0/(1 - f_0) x_j, j in J_I s.t. f_j > f_0) +
107 * sum(a_j x_j, , j in J_C s.t. a_j >= 0) -
108 * sum(a_j*f_0/(1-f_0) x_j , j in J_C s.t. a_j < 0) >= f_0.
109 * where J_I are the integer non-basic variables and J_C are the continuous.
110 * f_0 is the fractional part of lpval
111 * a_j is the j-th coefficient of the tableau row and f_j its fractional part
112 * Note: we create -% <= -f_0 !!
113 * Note: this formula is valid for a problem of the form Ax = b, x>= 0. Since we do not have
114 * such problem structure in general, we have to (implicitly) transform whatever we are given
115 * to that form. Specifically, non-basic variables at their lower bound are shifted so that the lower
116 * bound is 0 and non-basic at their upper bound are complemented. */
117static
119 SCIP* scip, /**< SCIP data structure */
120 int ncols, /**< Number of columns (original variables) in the LP */
121 int nrows, /**< Number of rows (slack variables) in the LP */
122 SCIP_COL** cols, /**< Column data of the LP */
123 SCIP_ROW** rows, /**< Row data of the LP */
124 const SCIP_Real* binvrow, /**< row of B^-1 for current basic variable */
125 const SCIP_Real* binvarow, /**< row of B^-1A for current basic variable */
126 const SCIP_Real* lpval, /**< value of variable at current LP solution */
127 SCIP_Real* cutcoefs, /**< array to store cut coefficients */
128 SCIP_Real* cutrhs, /**< pointer to store rhs of cut */
129 SCIP_Bool useweakerscuts /**< use weakener cuts derived from the exact branching split */
130 )
131{
132 SCIP_COL** rowcols;
133 SCIP_COL* col;
134 SCIP_ROW* row;
135 SCIP_Real* rowvals;
136 SCIP_BASESTAT basestat;
137 SCIP_Real rowelem;
138 SCIP_Real cutelem;
139 SCIP_Real f0;
140 SCIP_Real f0complementratio;
141 SCIP_Real rowrhs;
142 SCIP_Real rowlhs;
143 SCIP_Real rowact;
144 SCIP_Real rowrhsslack;
145 int i;
146 int c;
147
148 /* Clear the memory array of cut coefficients. It may store that of the last computed cut */
149 BMSclearMemoryArray(cutcoefs, ncols);
150
151 /* compute fractionality f0 and f0/(1-f0) */
152 f0 = SCIPfeasFrac(scip, *lpval);
153 f0complementratio = f0 / (1.0 - f0);
154
155 /* The rhs of the cut is the fractional part of the LP solution of the basic variable */
156 *cutrhs = -f0;
157
158 /* Generate cut coefficient for the original variables */
159 for ( c = 0; c < ncols; c++ )
160 {
161 col = cols[c];
162 assert( col != NULL );
163
164 basestat = SCIPcolGetBasisStatus(col);
165 /* Get simplex tableau coefficient */
166 if ( basestat == SCIP_BASESTAT_LOWER )
167 {
168 /* Take coefficient if nonbasic at lower bound */
169 rowelem = binvarow[c];
170 }
171 else if ( basestat == SCIP_BASESTAT_UPPER )
172 {
173 /* Flip coefficient if nonbasic at upper bound: x --> u - x */
174 rowelem = -binvarow[c];
175 }
176 else
177 {
178 /* Nonbasic free variable at zero or basic variable. Just skip it. */
179 continue;
180 }
181
182 /* Integer variables */
183 if ( SCIPcolIsIntegral(col) && !useweakerscuts )
184 {
185 /* Warning: Because of numerics we can have cutelem < 0
186 * In such a case it is very close to 0, so isZero will catch and we can ignore the coefficient */
187 cutelem = SCIPfrac(scip, rowelem);
188 if ( cutelem > f0 )
189 {
190 /* sum((1 - f_j) * f_0/(1 - f_0) x_j, j in J_I s.t. f_j > f_0 */
191 cutelem = -((1.0 - cutelem) * f0complementratio);
192 }
193 else
194 {
195 /* sum(f_j * x_j, j in J_I s.t. f_j <= 0 */
196 cutelem = -cutelem;
197 }
198 }
199 /* Then continuous variables */
200 else
201 {
202 if ( rowelem < 0 )
203 {
204 /* sum(a_j* f_0/(1 - f_0) x_j, j in J_C s.t. a_j < 0 */
205 cutelem = rowelem * f0complementratio;
206 }
207 else
208 {
209 /* sum(a_j * x_j, j in J_C s.t. a_j >= 0 */
210 cutelem = -rowelem;
211 }
212 }
213
214 /* Cut is defined when variables are in [0, infinity). Translate to general bounds. */
215 if ( !SCIPisZero(scip, cutelem) )
216 {
217 if ( basestat == SCIP_BASESTAT_UPPER )
218 {
219 cutelem = -cutelem;
220 *cutrhs += cutelem * SCIPcolGetUb(col);
221 }
222 else
223 {
224 *cutrhs += cutelem * SCIPcolGetLb(col);
225 }
226 /* Add coefficient to cut */
227 cutcoefs[SCIPcolGetLPPos(col)] = cutelem;
228 }
229 }
230
231 /* generate cut coefficient for the slack variables. Skip the basic ones */
232 for ( c = 0; c < nrows; c++ )
233 {
234 row = rows[c];
235 assert( row != NULL );
236 basestat = SCIProwGetBasisStatus(row);
237
238 /* Get the simplex tableau coefficient */
239 if ( basestat == SCIP_BASESTAT_LOWER )
240 {
241 /* Take coefficient if nonbasic at lower bound */
242 rowelem = binvrow[SCIProwGetLPPos(row)];
243 /* If there is a >= constraint or ranged constraint at the lower bound, we have to flip the row element */
244 if ( !SCIPisInfinity(scip, -SCIProwGetLhs(row)) )
245 rowelem = -rowelem;
246 }
247 else if ( basestat == SCIP_BASESTAT_UPPER )
248 {
249 /* Take element if nonbasic at upper bound. Only non-positive slack variables can be nonbasic at upper,
250 * therefore they should be flipped twice, meaning we can take the element directly */
251 rowelem = binvrow[SCIProwGetLPPos(row)];
252 }
253 else
254 {
255 /* Nonbasic free variable at zero or basic variable. Free variable should not happen here. Just skip if free */
256 assert( basestat == SCIP_BASESTAT_BASIC );
257 continue;
258 }
259
260 /* Integer rows */
261 if ( SCIProwIsIntegral(row) && !SCIProwIsModifiable(row) && !useweakerscuts )
262 {
263 /* Warning: Because of numerics we can have cutelem < 0
264 * In such a case it is very close to 0, so isZero will catch and we can ignore the coefficient */
265 cutelem = SCIPfrac(scip, rowelem);
266 if ( cutelem > f0 )
267 {
268 /* sum((1 - f_j) * f_0/(1 - f_0) x_j, j in J_I s.t. f_j > f_0 */
269 cutelem = -((1.0 - cutelem) * f0complementratio);
270 }
271 else
272 {
273 /* sum(f_j * x_j, j in J_I s.t. f_j <= 0 */
274 cutelem = -cutelem;
275 }
276 }
277 /* Then continuous variables */
278 else
279 {
280 if ( rowelem < 0 )
281 {
282 /* sum(a_j* f_0/(1 - f_0) x_j, j in J_C s.t. a_j < 0 */
283 cutelem = rowelem * f0complementratio;
284 }
285 else
286 {
287 /* sum(a_j * x_j, j in J_C s.t. a_j >= 0 */
288 cutelem = -rowelem;
289 }
290 }
291
292 /* Cut is defined in original variables, so we replace slack variables by their original definition */
293 if ( !SCIPisZero(scip, cutelem) )
294 {
295 /* Coefficient is large enough so we keep it */
296 rowlhs = SCIProwGetLhs(row);
297 rowrhs = SCIProwGetRhs(row);
298 assert( SCIPisLE(scip, rowlhs, rowrhs) );
299 assert( !SCIPisInfinity(scip, rowlhs) || !SCIPisInfinity(scip, rowrhs) );
300
301 /* If the slack variable is fixed we can ignore this cut coefficient */
302 if ( SCIPisFeasZero(scip, rowrhs - rowlhs) )
303 continue;
304
305 /* Un-flip sack variable and adjust rhs if necessary.
306 * Row at lower basis means the slack variable is at its upper bound.
307 * Since SCIP adds +1 slacks, this can only happen when constraints have finite lhs */
309 {
310 assert( !SCIPisInfinity(scip, -rowlhs) );
311 cutelem = -cutelem;
312 }
313
314 rowcols = SCIProwGetCols(row);
315 rowvals = SCIProwGetVals(row);
316
317 /* Eliminate slack variables. rowcols is sorted [columns in LP, columns not in LP] */
318 for ( i = 0; i < SCIProwGetNLPNonz(row); i++ )
319 cutcoefs[SCIPcolGetLPPos(rowcols[i])] -= cutelem * rowvals[i];
320
321 /* Modify the rhs */
322 rowact = SCIPgetRowActivity(scip, row);
323 rowrhsslack = rowrhs - rowact;
324
325 if ( SCIPisFeasZero(scip, rowrhsslack) )
326 *cutrhs -= cutelem * (rowrhs - SCIProwGetConstant(row));
327 else
328 {
329 assert( SCIPisFeasZero(scip, rowact - rowlhs) );
330 *cutrhs -= cutelem * (rowlhs - SCIProwGetConstant(row));
331 }
332 }
333 }
334}
335
336
337/*
338 * Callback methods of branching rule
339 */
340
341
342/** copy method for branchrule plugins (called when SCIP copies plugins) */
343static
344SCIP_DECL_BRANCHCOPY(branchCopyGomory)
345{ /*lint --e{715}*/
346 assert(scip != NULL);
347 assert(branchrule != NULL);
348
350
351 /* call inclusion method of branchrule */
353
354 return SCIP_OKAY;
355}
356
357
358/** destructor of branching rule to free user data (called when SCIP is exiting) */
359static
360SCIP_DECL_BRANCHFREE(branchFreeGomory)
361{ /*lint --e{715}*/
362 SCIP_BRANCHRULEDATA* branchruledata;
363
364 /* free branching rule data */
365 branchruledata = SCIPbranchruleGetData(branchrule);
366 assert(branchruledata != NULL);
367
368 SCIPfreeBlockMemoryNull(scip, &branchruledata);
369
370 return SCIP_OKAY;
371}
372
373
374/** branching execution method for fractional LP solutions */
375static
376SCIP_DECL_BRANCHEXECLP(branchExeclpGomory)
377{ /*lint --e{715}*/
378 SCIP_BRANCHRULEDATA* branchruledata;
380 SCIP_COL** cols;
381 SCIP_ROW** rows;
384 SCIP_Real* binvrow;
385 SCIP_Real* binvarow;
386 SCIP_Real* cutcoefs;
387 SCIP_ROW* cut;
388 SCIP_COL* col;
389 int* basisind;
390 int* basicvarpos2tableaurow;
391 int* inds;
392 const char* name;
393 SCIP_Real cutrhs;
394 SCIP_Real score;
395 SCIP_Real bestscore;
396 int nlpcands;
397 int maxncands;
398 int ncols;
399 int nrows;
400 int lppos;
401 int ninds;
402 int bestcand;
403 int i;
404 int j;
405
406 name = (char *) "test";
407
408 assert(branchrule != NULL);
409 assert(scip != NULL);
410 assert(result != NULL);
411
413
414 SCIPdebugMsg(scip, "Execlp method of Gomory branching in node %" SCIP_LONGINT_FORMAT "\n", SCIPnodeGetNumber(SCIPgetCurrentNode(scip)));
415
417 {
419 SCIPdebugMsg(scip, "Could not apply Gomory branching, as the current LP was not solved to optimality.\n");
420
421 return SCIP_OKAY;
422 }
423
424 /* Get branching candidates */
426 assert(nlpcands > 0);
427
429
430 /* Get branching rule data */
431 branchruledata = SCIPbranchruleGetData(branchrule);
432 assert(branchruledata != NULL);
433
434 /* Compute the reliability pseudo-cost branching scores for the candidates */
435 if ( branchruledata->performrelpscost )
436 {
437 /* We do not branch using this rule, but if enabled do take all the bound and conflict inferences made */
440 }
441
442 /* Return SCIP_OKAY if relpscost has shown that this node can be cutoff or some variable domains have changed */
444 {
445 return SCIP_OKAY;
446 }
447
448 /* Get the maximum number of LP branching candidates that we generate cuts for and score */
449 if( branchruledata->maxncands >= 0 )
450 {
451 maxncands = MIN(nlpcands, branchruledata->maxncands);
452 }
453 else
454 {
455 maxncands = nlpcands;
456 }
457
458 /* Get the Column and Row data */
459 SCIP_CALL( SCIPgetLPColsData(scip, &cols, &ncols) );
460 SCIP_CALL( SCIPgetLPRowsData(scip, &rows, &nrows) );
461
462 /* Allocate temporary memory */
463 SCIP_CALL( SCIPallocBufferArray(scip, &cutcoefs, ncols) );
464 SCIP_CALL( SCIPallocBufferArray(scip, &basisind, nrows) );
465 SCIP_CALL( SCIPallocBufferArray(scip, &basicvarpos2tableaurow, ncols) );
466 SCIP_CALL( SCIPallocBufferArray(scip, &binvrow, nrows) );
467 SCIP_CALL( SCIPallocBufferArray(scip, &binvarow, ncols) );
468 SCIP_CALL( SCIPallocBufferArray(scip, &inds, nrows) );
469
470 /* Create basis indices mapping (from the column position to LP tableau rox index) */
471 for( i = 0; i < ncols; ++i )
472 {
473 basicvarpos2tableaurow[i] = -1;
474 }
475 SCIP_CALL( SCIPgetLPBasisInd(scip, basisind) );
476 for( i = 0; i < nrows; ++i )
477 {
478 if( basisind[i] >= 0 )
479 basicvarpos2tableaurow[basisind[i]] = i;
480 }
481
482 /* Initialise the best candidate */
483 bestcand = 0;
484 bestscore = -SCIPinfinity(scip);
485 ninds = -1;
486
487 /* Iterate over candidates and get best cut score */
488 for( i = 0; i < maxncands; i++ )
489 {
490 /* Initialise the score of the cut */
491 score = 0;
492
493 /* Get the LP position of the branching candidate */
494 col = SCIPvarGetCol(lpcands[i]);
495 lppos = SCIPcolGetLPPos(col);
496 assert(lppos != -1);
497
498 /* get the row of B^-1 for this basic integer variable with fractional solution value */
499 SCIP_CALL( SCIPgetLPBInvRow(scip, basicvarpos2tableaurow[lppos], binvrow, inds, &ninds) );
500
501 /* Get the Tableau row for this basic integer variable with fractional solution value */
502 SCIP_CALL( SCIPgetLPBInvARow(scip, basicvarpos2tableaurow[lppos], binvrow, binvarow, inds, &ninds) );
503
504 /* Compute the GMI cut */
505 getGMIFromRow(scip, ncols, nrows, cols, rows, binvrow, binvarow, &lpcandssol[i], cutcoefs,
506 &cutrhs, branchruledata->useweakercuts);
507
508 /* Calculate the weighted sum score of measures */
509 cut = NULL;
511 for( j = 0; j < ncols; ++j )
512 {
513 if( !SCIPisZero(scip, cutcoefs[j]) )
514 {
515 SCIP_CALL( SCIPaddVarToRow(scip, cut, SCIPcolGetVar(cols[j]), cutcoefs[SCIPcolGetLPPos(cols[j])]) );
516 }
517 }
519 if ( branchruledata-> efficacyweight != 0 )
520 score += branchruledata->efficacyweight * SCIPgetCutEfficacy(scip, NULL, cut);
521 if ( branchruledata->objparallelweight != 0 )
522 score += branchruledata->objparallelweight * SCIPgetRowObjParallelism(scip, cut);
523 if ( branchruledata->intsupportweight != 0 )
524 score += branchruledata->intsupportweight * SCIPgetRowNumIntCols(scip, cut) / (SCIP_Real) SCIProwGetNNonz(cut);
525 SCIP_CALL( SCIPreleaseRow(scip, &cut) );
526
527 /* Replace the best cut if score is higher */
528 if (score > bestscore)
529 {
530 bestscore = score;
531 bestcand = i;
532 }
533 }
534
535 /* Free temporary memory */
537 SCIPfreeBufferArray(scip, &binvrow);
538 SCIPfreeBufferArray(scip, &binvarow);
539 SCIPfreeBufferArray(scip, &basicvarpos2tableaurow);
540 SCIPfreeBufferArray(scip, &basisind);
541 SCIPfreeBufferArray(scip, &cutcoefs);
542
543 SCIPdebugMsg(scip, " -> %d candidates, selected candidate %d: variable <%s> (frac=%g, factor=%g, score=%g)\n",
546
547 /* Perform the branching */
550
551 return SCIP_OKAY;
552}
553
554
555/*
556 * branching rule specific interface methods
557 */
558
559/** creates the Gomory cut branching rule and includes it in SCIP */
561 SCIP* scip /**< SCIP data structure */
562 )
563{
564 SCIP_BRANCHRULEDATA* branchruledata;
565 SCIP_BRANCHRULE* branchrule;
566
567 /* create branching rule data */
568 SCIP_CALL( SCIPallocBlockMemory(scip, &branchruledata) );
569
570 /* include branching rule */
573
574 assert(branchrule != NULL);
575
576 /* set non-fundamental callbacks via specific setter functions*/
577 SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyGomory) );
578 SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreeGomory) );
579 SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpGomory) );
580
581 /* Gomory cut branching rule parameters */
582 SCIP_CALL( SCIPaddIntParam(scip,"branching/gomory/maxncands",
583 "maximum amount of branching candidates to generate Gomory cuts for (-1: all candidates)",
584 &branchruledata->maxncands, FALSE, DEFAULT_MAXNCANDS, -1, INT_MAX, NULL, NULL) );
585 SCIP_CALL( SCIPaddRealParam(scip,"branching/gomory/efficacyweight",
586 "weight of efficacy in the weighted sum cut scoring rule",
587 &branchruledata->efficacyweight, FALSE, DEFAULT_EFFICACYWEIGHT, -1.0, 1.0, NULL, NULL) );
588 SCIP_CALL( SCIPaddRealParam(scip,"branching/gomory/objparallelweight",
589 "weight of objective parallelism in the weighted sum cut scoring rule",
590 &branchruledata->objparallelweight, FALSE, DEFAULT_OBJPARALLELWEIGHT, -1.0, 1.0, NULL, NULL) );
591 SCIP_CALL( SCIPaddRealParam(scip,"branching/gomory/intsupportweight",
592 "weight of integer support in the weighted sum cut scoring rule",
593 &branchruledata->intsupportweight, FALSE, DEFAULT_INTSUPPORTWEIGHT, -1.0, 1.0, NULL, NULL) );
594 SCIP_CALL( SCIPaddBoolParam(scip,"branching/gomory/performrelpscost",
595 "whether relpscost branching should be called without branching (used for bound inferences and conflicts)",
596 &branchruledata->performrelpscost, FALSE, DEFAULT_PERFORMRELPSCOST, NULL, NULL) );
597 SCIP_CALL( SCIPaddBoolParam(scip,"branching/gomory/useweakercuts",
598 "use weaker cuts that are exactly derived from the branching split disjunction",
599 &branchruledata->useweakercuts, FALSE, DEFAULT_USEWEAKERCUTS, NULL, NULL) );
600
601 return SCIP_OKAY;
602}
#define BRANCHRULE_DESC
#define BRANCHRULE_PRIORITY
#define BRANCHRULE_NAME
#define BRANCHRULE_MAXDEPTH
#define BRANCHRULE_MAXBOUNDDIST
#define DEFAULT_EFFICACYWEIGHT
static void getGMIFromRow(SCIP *scip, int ncols, int nrows, SCIP_COL **cols, SCIP_ROW **rows, const SCIP_Real *binvrow, const SCIP_Real *binvarow, const SCIP_Real *lpval, SCIP_Real *cutcoefs, SCIP_Real *cutrhs, SCIP_Bool useweakerscuts)
#define DEFAULT_OBJPARALLELWEIGHT
#define DEFAULT_PERFORMRELPSCOST
#define DEFAULT_USEWEAKERCUTS
#define DEFAULT_INTSUPPORTWEIGHT
#define DEFAULT_MAXNCANDS
Gomory cut branching rule.
reliable pseudo costs branching rule
#define NULL
Definition def.h:257
#define SCIP_Bool
Definition def.h:100
#define MIN(x, y)
Definition def.h:233
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define SCIP_LONGINT_FORMAT
Definition def.h:157
#define SCIP_CALL(x)
Definition def.h:364
SCIP_RETCODE SCIPexecRelpscostBranching(SCIP *scip, SCIP_VAR **branchcands, SCIP_Real *branchcandssol, SCIP_Real *branchcandsfrac, int nbranchcands, SCIP_Bool executebranching, SCIP_RESULT *result)
SCIP_RETCODE SCIPincludeBranchruleGomory(SCIP *scip)
#define SCIPdebugMsg
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_param.c:83
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_param.c:139
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_param.c:57
SCIP_RETCODE SCIPincludeBranchruleBasic(SCIP *scip, SCIP_BRANCHRULE **branchruleptr, const char *name, const char *desc, int priority, int maxdepth, SCIP_Real maxbounddist, SCIP_BRANCHRULEDATA *branchruledata)
const char * SCIPbranchruleGetName(SCIP_BRANCHRULE *branchrule)
Definition branch.c:2018
SCIP_BRANCHRULEDATA * SCIPbranchruleGetData(SCIP_BRANCHRULE *branchrule)
Definition branch.c:1886
SCIP_RETCODE SCIPsetBranchruleCopy(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPsetBranchruleExecLp(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPsetBranchruleFree(SCIP *scip, SCIP_BRANCHRULE *branchrule,)
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
SCIP_RETCODE SCIPbranchVar(SCIP *scip, SCIP_VAR *var, SCIP_NODE **downchild, SCIP_NODE **eqchild, SCIP_NODE **upchild)
int SCIPcolGetLPPos(SCIP_COL *col)
Definition lp.c:17487
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition lp.c:17425
SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
Definition lp.c:17455
SCIP_Real SCIPcolGetLb(SCIP_COL *col)
Definition lp.c:17346
SCIP_Real SCIPcolGetUb(SCIP_COL *col)
Definition lp.c:17356
SCIP_BASESTAT SCIPcolGetBasisStatus(SCIP_COL *col)
Definition lp.c:17414
SCIP_Real SCIPgetCutEfficacy(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
Definition scip_cut.c:94
SCIP_RETCODE SCIPgetLPBasisInd(SCIP *scip, int *basisind)
Definition scip_lp.c:692
SCIP_RETCODE SCIPgetLPColsData(SCIP *scip, SCIP_COL ***cols, int *ncols)
Definition scip_lp.c:477
SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
Definition scip_lp.c:576
SCIP_RETCODE SCIPgetLPBInvARow(SCIP *scip, int r, SCIP_Real *binvrow, SCIP_Real *coefs, int *inds, int *ninds)
Definition scip_lp.c:791
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition scip_lp.c:174
SCIP_RETCODE SCIPgetLPBInvRow(SCIP *scip, int r, SCIP_Real *coefs, int *inds, int *ninds)
Definition scip_lp.c:720
#define SCIPallocBufferArray(scip, ptr, num)
Definition scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition scip_mem.h:136
#define SCIPfreeBlockMemoryNull(scip, ptr)
Definition scip_mem.h:109
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
Definition tree.c:8513
SCIP_Bool SCIProwIsIntegral(SCIP_ROW *row)
Definition lp.c:17785
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition lp.c:17686
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition lp.c:17805
int SCIProwGetNNonz(SCIP_ROW *row)
Definition lp.c:17607
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition lp.c:17632
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition lp.c:17696
int SCIProwGetNLPNonz(SCIP_ROW *row)
Definition lp.c:17621
int SCIProwGetLPPos(SCIP_ROW *row)
Definition lp.c:17895
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition scip_lp.c:1646
SCIP_Real SCIPgetRowActivity(SCIP *scip, SCIP_ROW *row)
Definition scip_lp.c:2068
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition scip_lp.c:1508
SCIP_RETCODE SCIPcreateEmptyRowUnspec(SCIP *scip, SCIP_ROW **row, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
Definition scip_lp.c:1458
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition lp.c:17652
SCIP_Real SCIPgetRowObjParallelism(SCIP *scip, SCIP_ROW *row)
Definition scip_lp.c:2154
int SCIPgetRowNumIntCols(SCIP *scip, SCIP_ROW *row)
Definition scip_lp.c:1832
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition lp.c:17642
SCIP_BASESTAT SCIProwGetBasisStatus(SCIP_ROW *row)
Definition lp.c:17734
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Real SCIPfeasFrac(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeastol(SCIP *scip)
SCIP_Real SCIPfrac(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition scip_tree.c:91
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition var.c:23715
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23299
SCIP_Real SCIPvarGetBranchFactor(SCIP_VAR *var)
Definition var.c:24482
return SCIP_OKAY
int c
SCIP_Real * lpcandssol
int nlpcands
SCIP_VAR ** lpcands
assert(minobj< SCIPgetCutoffbound(scip))
int bestcand
SCIP_Real * lpcandsfrac
#define BMSclearMemoryArray(ptr, num)
Definition memory.h:130
public methods for branching rules
public methods for LP management
public methods for message output
public methods for branch and bound tree
public methods for problem variables
public methods for branching rule plugins and branching
public methods for cuts and aggregation rows
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for the branch-and-bound tree
#define SCIP_DECL_BRANCHEXECLP(x)
#define SCIP_DECL_BRANCHCOPY(x)
Definition type_branch.h:67
#define SCIP_DECL_BRANCHFREE(x)
Definition type_branch.h:75
struct SCIP_Branchrule SCIP_BRANCHRULE
Definition type_branch.h:56
struct SCIP_BranchruleData SCIP_BRANCHRULEDATA
Definition type_branch.h:57
struct SCIP_Row SCIP_ROW
Definition type_lp.h:105
struct SCIP_Col SCIP_COL
Definition type_lp.h:99
@ SCIP_LPSOLSTAT_OPTIMAL
Definition type_lp.h:44
@ SCIP_BASESTAT_BASIC
Definition type_lpi.h:92
@ SCIP_BASESTAT_UPPER
Definition type_lpi.h:93
@ SCIP_BASESTAT_LOWER
Definition type_lpi.h:91
enum SCIP_BaseStat SCIP_BASESTAT
Definition type_lpi.h:96
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_CUTOFF
Definition type_result.h:48
@ SCIP_REDUCEDDOM
Definition type_result.h:51
@ SCIP_BRANCHED
Definition type_result.h:54
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Var SCIP_VAR
Definition type_var.h:166