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#include <string.h>
69#include <assert.h>
70
71
72
73#define BRANCHRULE_NAME "gomory"
74#define BRANCHRULE_DESC "Gomory cut score branching"
75#define BRANCHRULE_PRIORITY -1000
76#define BRANCHRULE_MAXDEPTH -1
77#define BRANCHRULE_MAXBOUNDDIST 1.0
78
79#define DEFAULT_MAXNCANDS -1 /**< maximum number of branching candidates to produce a cut for */
80#define DEFAULT_EFFICACYWEIGHT 1.0 /**< the weight of efficacy in weighted sum cut scoring rule */
81#define DEFAULT_OBJPARALLELWEIGHT 0.0 /**< the weight of objective parallelism in weighted sum scoring rule */
82#define DEFAULT_INTSUPPORTWEIGHT 0.0 /**< the weight of integer support in weighted sum cut scoring rule */
83#define DEFAULT_PERFORMRELPSCOST FALSE /**< if relpscost branching should be called without actual branching */
84#define DEFAULT_USEWEAKERCUTS TRUE /**< use weaker cuts derived from the exact branching split */
85
86
87/*
88 * Data structures
89 */
90
91/** branching rule data */
92struct SCIP_BranchruleData
93{
94 int maxncands; /**< maximum number of variable candidates to produce cut for */
95 SCIP_Real efficacyweight; /**< the weight of efficacy in weighted sum cut scoring rule */
96 SCIP_Real objparallelweight; /**< the weight of objective parallelism in weighted sum scoring rule */
97 SCIP_Real intsupportweight; /**< the weight of integer support in weighted sum cut scoring rule */
98 SCIP_Bool performrelpscost; /**< if relpscost branching should be called without actual branching */
99 SCIP_Bool useweakercuts; /**< use weaker cuts derived from the exact branching split */
100};
101
102
103/*
104 * Local methods
105 */
106
107/** Generate GMI cut: The GMI is given by
108 * sum(f_j x_j , j in J_I s.t. f_j <= f_0) +
109 * sum((1-f_j)*f_0/(1 - f_0) x_j, j in J_I s.t. f_j > f_0) +
110 * sum(a_j x_j, , j in J_C s.t. a_j >= 0) -
111 * sum(a_j*f_0/(1-f_0) x_j , j in J_C s.t. a_j < 0) >= f_0.
112 * where J_I are the integer non-basic variables and J_C are the continuous.
113 * f_0 is the fractional part of lpval
114 * a_j is the j-th coefficient of the tableau row and f_j its fractional part
115 * Note: we create -% <= -f_0 !!
116 * Note: this formula is valid for a problem of the form Ax = b, x>= 0. Since we do not have
117 * such problem structure in general, we have to (implicitly) transform whatever we are given
118 * to that form. Specifically, non-basic variables at their lower bound are shifted so that the lower
119 * bound is 0 and non-basic at their upper bound are complemented. */
120static
122 SCIP* scip, /**< SCIP data structure */
123 int ncols, /**< Number of columns (original variables) in the LP */
124 int nrows, /**< Number of rows (slack variables) in the LP */
125 SCIP_COL** cols, /**< Column data of the LP */
126 SCIP_ROW** rows, /**< Row data of the LP */
127 const SCIP_Real* binvrow, /**< row of B^-1 for current basic variable */
128 const SCIP_Real* binvarow, /**< row of B^-1A for current basic variable */
129 const SCIP_Real* lpval, /**< value of variable at current LP solution */
130 SCIP_Real* cutcoefs, /**< array to store cut coefficients */
131 SCIP_Real* cutrhs, /**< pointer to store rhs of cut */
132 SCIP_Bool useweakerscuts /**< use weakener cuts derived from the exact branching split */
133 )
134{
135 SCIP_COL** rowcols;
136 SCIP_COL* col;
137 SCIP_ROW* row;
138 SCIP_Real* rowvals;
139 SCIP_BASESTAT basestat;
140 SCIP_Real rowelem;
141 SCIP_Real cutelem;
142 SCIP_Real f0;
143 SCIP_Real f0complementratio;
144 SCIP_Real rowrhs;
145 SCIP_Real rowlhs;
146 SCIP_Real rowact;
147 SCIP_Real rowrhsslack;
148 int i;
149 int c;
150
151 /* Clear the memory array of cut coefficients. It may store that of the last computed cut */
152 BMSclearMemoryArray(cutcoefs, ncols);
153
154 /* compute fractionality f0 and f0/(1-f0) */
155 f0 = SCIPfeasFrac(scip, *lpval);
156 f0complementratio = f0 / (1.0 - f0);
157
158 /* The rhs of the cut is the fractional part of the LP solution of the basic variable */
159 *cutrhs = -f0;
160
161 /* Generate cut coefficient for the original variables */
162 for ( c = 0; c < ncols; c++ )
163 {
164 col = cols[c];
165 assert( col != NULL );
166
167 basestat = SCIPcolGetBasisStatus(col);
168 /* Get simplex tableau coefficient */
169 if ( basestat == SCIP_BASESTAT_LOWER )
170 {
171 /* Take coefficient if nonbasic at lower bound */
172 rowelem = binvarow[c];
173 }
174 else if ( basestat == SCIP_BASESTAT_UPPER )
175 {
176 /* Flip coefficient if nonbasic at upper bound: x --> u - x */
177 rowelem = -binvarow[c];
178 }
179 else
180 {
181 /* Nonbasic free variable at zero or basic variable. Just skip it. */
182 continue;
183 }
184
185 /* Integer variables */
186 if ( SCIPcolIsIntegral(col) && !useweakerscuts )
187 {
188 /* Warning: Because of numerics we can have cutelem < 0
189 * In such a case it is very close to 0, so isZero will catch and we can ignore the coefficient */
190 cutelem = SCIPfrac(scip, rowelem);
191 if ( cutelem > f0 )
192 {
193 /* sum((1 - f_j) * f_0/(1 - f_0) x_j, j in J_I s.t. f_j > f_0 */
194 cutelem = -((1.0 - cutelem) * f0complementratio);
195 }
196 else
197 {
198 /* sum(f_j * x_j, j in J_I s.t. f_j <= 0 */
199 cutelem = -cutelem;
200 }
201 }
202 /* Then continuous variables */
203 else
204 {
205 if ( rowelem < 0 )
206 {
207 /* sum(a_j* f_0/(1 - f_0) x_j, j in J_C s.t. a_j < 0 */
208 cutelem = rowelem * f0complementratio;
209 }
210 else
211 {
212 /* sum(a_j * x_j, j in J_C s.t. a_j >= 0 */
213 cutelem = -rowelem;
214 }
215 }
216
217 /* Cut is defined when variables are in [0, infinity). Translate to general bounds. */
218 if ( !SCIPisZero(scip, cutelem) )
219 {
220 if ( basestat == SCIP_BASESTAT_UPPER )
221 {
222 cutelem = -cutelem;
223 *cutrhs += cutelem * SCIPcolGetUb(col);
224 }
225 else
226 {
227 *cutrhs += cutelem * SCIPcolGetLb(col);
228 }
229 /* Add coefficient to cut */
230 cutcoefs[SCIPcolGetLPPos(col)] = cutelem;
231 }
232 }
233
234 /* generate cut coefficient for the slack variables. Skip the basic ones */
235 for ( c = 0; c < nrows; c++ )
236 {
237 row = rows[c];
238 assert( row != NULL );
239 basestat = SCIProwGetBasisStatus(row);
240
241 /* Get the simplex tableau coefficient */
242 if ( basestat == SCIP_BASESTAT_LOWER )
243 {
244 /* Take coefficient if nonbasic at lower bound */
245 rowelem = binvrow[SCIProwGetLPPos(row)];
246 /* If there is a >= constraint or ranged constraint at the lower bound, we have to flip the row element */
247 if ( !SCIPisInfinity(scip, -SCIProwGetLhs(row)) )
248 rowelem = -rowelem;
249 }
250 else if ( basestat == SCIP_BASESTAT_UPPER )
251 {
252 /* Take element if nonbasic at upper bound. Only non-positive slack variables can be nonbasic at upper,
253 * therefore they should be flipped twice, meaning we can take the element directly */
254 rowelem = binvrow[SCIProwGetLPPos(row)];
255 }
256 else
257 {
258 /* Nonbasic free variable at zero or basic variable. Free variable should not happen here. Just skip if free */
259 assert( basestat == SCIP_BASESTAT_BASIC );
260 continue;
261 }
262
263 /* Integer rows */
264 if ( SCIProwIsIntegral(row) && !SCIProwIsModifiable(row) && !useweakerscuts )
265 {
266 /* Warning: Because of numerics we can have cutelem < 0
267 * In such a case it is very close to 0, so isZero will catch and we can ignore the coefficient */
268 cutelem = SCIPfrac(scip, rowelem);
269 if ( cutelem > f0 )
270 {
271 /* sum((1 - f_j) * f_0/(1 - f_0) x_j, j in J_I s.t. f_j > f_0 */
272 cutelem = -((1.0 - cutelem) * f0complementratio);
273 }
274 else
275 {
276 /* sum(f_j * x_j, j in J_I s.t. f_j <= 0 */
277 cutelem = -cutelem;
278 }
279 }
280 /* Then continuous variables */
281 else
282 {
283 if ( rowelem < 0 )
284 {
285 /* sum(a_j* f_0/(1 - f_0) x_j, j in J_C s.t. a_j < 0 */
286 cutelem = rowelem * f0complementratio;
287 }
288 else
289 {
290 /* sum(a_j * x_j, j in J_C s.t. a_j >= 0 */
291 cutelem = -rowelem;
292 }
293 }
294
295 /* Cut is defined in original variables, so we replace slack variables by their original definition */
296 if ( !SCIPisZero(scip, cutelem) )
297 {
298 /* Coefficient is large enough so we keep it */
299 rowlhs = SCIProwGetLhs(row);
300 rowrhs = SCIProwGetRhs(row);
301 assert( SCIPisLE(scip, rowlhs, rowrhs) );
302 assert( !SCIPisInfinity(scip, rowlhs) || !SCIPisInfinity(scip, rowrhs) );
303
304 /* If the slack variable is fixed we can ignore this cut coefficient */
305 if ( SCIPisFeasZero(scip, rowrhs - rowlhs) )
306 continue;
307
308 /* Un-flip sack variable and adjust rhs if necessary.
309 * Row at lower basis means the slack variable is at its upper bound.
310 * Since SCIP adds +1 slacks, this can only happen when constraints have finite lhs */
312 {
313 assert( !SCIPisInfinity(scip, -rowlhs) );
314 cutelem = -cutelem;
315 }
316
317 rowcols = SCIProwGetCols(row);
318 rowvals = SCIProwGetVals(row);
319
320 /* Eliminate slack variables. rowcols is sorted [columns in LP, columns not in LP] */
321 for ( i = 0; i < SCIProwGetNLPNonz(row); i++ )
322 cutcoefs[SCIPcolGetLPPos(rowcols[i])] -= cutelem * rowvals[i];
323
324 /* Modify the rhs */
325 rowact = SCIPgetRowActivity(scip, row);
326 rowrhsslack = rowrhs - rowact;
327
328 if ( SCIPisFeasZero(scip, rowrhsslack) )
329 *cutrhs -= cutelem * (rowrhs - SCIProwGetConstant(row));
330 else
331 {
332 assert( SCIPisFeasZero(scip, rowact - rowlhs) );
333 *cutrhs -= cutelem * (rowlhs - SCIProwGetConstant(row));
334 }
335 }
336 }
337}
338
339
340/*
341 * Callback methods of branching rule
342 */
343
344
345/** copy method for branchrule plugins (called when SCIP copies plugins) */
346static
347SCIP_DECL_BRANCHCOPY(branchCopyGomory)
348{ /*lint --e{715}*/
349 assert(scip != NULL);
350 assert(branchrule != NULL);
351 assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
352
353 /* call inclusion method of branchrule */
355
356 return SCIP_OKAY;
357}
358
359
360/** destructor of branching rule to free user data (called when SCIP is exiting) */
361static
362SCIP_DECL_BRANCHFREE(branchFreeGomory)
363{ /*lint --e{715}*/
364 SCIP_BRANCHRULEDATA* branchruledata;
365
366 /* free branching rule data */
367 branchruledata = SCIPbranchruleGetData(branchrule);
368 assert(branchruledata != NULL);
369
370 SCIPfreeBlockMemoryNull(scip, &branchruledata);
371
372 return SCIP_OKAY;
373}
374
375
376/** branching execution method for fractional LP solutions */
377static
378SCIP_DECL_BRANCHEXECLP(branchExeclpGomory)
379{ /*lint --e{715}*/
380 SCIP_BRANCHRULEDATA* branchruledata;
382 SCIP_COL** cols;
383 SCIP_ROW** rows;
386 SCIP_Real* binvrow;
387 SCIP_Real* binvarow;
388 SCIP_Real* cutcoefs;
389 SCIP_ROW* cut;
390 SCIP_COL* col;
391 int* basisind;
392 int* basicvarpos2tableaurow;
393 int* inds;
394 const char* name;
395 SCIP_Real cutrhs;
396 SCIP_Real score;
397 SCIP_Real bestscore;
398 int nlpcands;
399 int maxncands;
400 int ncols;
401 int nrows;
402 int lppos;
403 int ninds;
404 int bestcand;
405 int i;
406 int j;
407
408 name = (char *) "test";
409
410 assert(branchrule != NULL);
411 assert(strcmp(SCIPbranchruleGetName(branchrule), BRANCHRULE_NAME) == 0);
412 assert(scip != NULL);
413 assert(result != NULL);
414
415 SCIPdebugMsg(scip, "Execlp method of Gomory branching in node %" SCIP_LONGINT_FORMAT "\n", SCIPnodeGetNumber(SCIPgetCurrentNode(scip)));
416
418 {
420 SCIPdebugMsg(scip, "Could not apply Gomory branching, as the current LP was not solved to optimality.\n");
421
422 return SCIP_OKAY;
423 }
424
425 /* Get branching candidates */
427 assert(nlpcands > 0);
428
430
431 /* Get branching rule data */
432 branchruledata = SCIPbranchruleGetData(branchrule);
433 assert(branchruledata != NULL);
434
435 /* Compute the reliability pseudo-cost branching scores for the candidates */
436 if ( branchruledata->performrelpscost )
437 {
438 /* We do not branch using this rule, but if enabled do take all the bound and conflict inferences made */
441 }
442
443 /* Return SCIP_OKAY if relpscost has shown that this node can be cutoff or some variable domains have changed */
445 {
446 return SCIP_OKAY;
447 }
448
449 /* Get the maximum number of LP branching candidates that we generate cuts for and score */
450 if( branchruledata->maxncands >= 0 )
451 {
452 maxncands = MIN(nlpcands, branchruledata->maxncands);
453 }
454 else
455 {
456 maxncands = nlpcands;
457 }
458
459 /* Get the Column and Row data */
460 SCIP_CALL( SCIPgetLPColsData(scip, &cols, &ncols) );
461 SCIP_CALL( SCIPgetLPRowsData(scip, &rows, &nrows) );
462
463 /* Allocate temporary memory */
464 SCIP_CALL( SCIPallocBufferArray(scip, &cutcoefs, ncols) );
465 SCIP_CALL( SCIPallocBufferArray(scip, &basisind, nrows) );
466 SCIP_CALL( SCIPallocBufferArray(scip, &basicvarpos2tableaurow, ncols) );
467 SCIP_CALL( SCIPallocBufferArray(scip, &binvrow, nrows) );
468 SCIP_CALL( SCIPallocBufferArray(scip, &binvarow, ncols) );
469 SCIP_CALL( SCIPallocBufferArray(scip, &inds, nrows) );
470
471 /* Create basis indices mapping (from the column position to LP tableau rox index) */
472 for( i = 0; i < ncols; ++i )
473 {
474 basicvarpos2tableaurow[i] = -1;
475 }
476 SCIP_CALL( SCIPgetLPBasisInd(scip, basisind) );
477 for( i = 0; i < nrows; ++i )
478 {
479 if( basisind[i] >= 0 )
480 basicvarpos2tableaurow[basisind[i]] = i;
481 }
482
483 /* Initialise the best candidate */
484 bestcand = 0;
485 bestscore = -SCIPinfinity(scip);
486 ninds = -1;
487
488 /* Iterate over candidates and get best cut score */
489 for( i = 0; i < maxncands; i++ )
490 {
491 /* Initialise the score of the cut */
492 score = 0;
493
494 /* Get the LP position of the branching candidate */
495 col = SCIPvarGetCol(lpcands[i]);
496 lppos = SCIPcolGetLPPos(col);
497 assert(lppos != -1);
498
499 /* get the row of B^-1 for this basic integer variable with fractional solution value */
500 SCIP_CALL( SCIPgetLPBInvRow(scip, basicvarpos2tableaurow[lppos], binvrow, inds, &ninds) );
501
502 /* Get the Tableau row for this basic integer variable with fractional solution value */
503 SCIP_CALL( SCIPgetLPBInvARow(scip, basicvarpos2tableaurow[lppos], binvrow, binvarow, inds, &ninds) );
504
505 /* Compute the GMI cut */
506 getGMIFromRow(scip, ncols, nrows, cols, rows, binvrow, binvarow, &lpcandssol[i], cutcoefs,
507 &cutrhs, branchruledata->useweakercuts);
508
509 /* Calculate the weighted sum score of measures */
510 cut = NULL;
512 for( j = 0; j < ncols; ++j )
513 {
514 if( !SCIPisZero(scip, cutcoefs[j]) )
515 {
516 SCIP_CALL( SCIPaddVarToRow(scip, cut, SCIPcolGetVar(cols[j]), cutcoefs[SCIPcolGetLPPos(cols[j])]) );
517 }
518 }
520 if ( branchruledata-> efficacyweight != 0 )
521 score += branchruledata->efficacyweight * SCIPgetCutEfficacy(scip, NULL, cut);
522 if ( branchruledata->objparallelweight != 0 )
523 score += branchruledata->objparallelweight * SCIPgetRowObjParallelism(scip, cut);
524 if ( branchruledata->intsupportweight != 0 )
525 score += branchruledata->intsupportweight * SCIPgetRowNumIntCols(scip, cut) / (SCIP_Real) SCIProwGetNNonz(cut);
526 SCIP_CALL( SCIPreleaseRow(scip, &cut) );
527
528 /* Replace the best cut if score is higher */
529 if (score > bestscore)
530 {
531 bestscore = score;
532 bestcand = i;
533 }
534 }
535
536 /* Free temporary memory */
538 SCIPfreeBufferArray(scip, &binvrow);
539 SCIPfreeBufferArray(scip, &binvarow);
540 SCIPfreeBufferArray(scip, &basicvarpos2tableaurow);
541 SCIPfreeBufferArray(scip, &basisind);
542 SCIPfreeBufferArray(scip, &cutcoefs);
543
544 SCIPdebugMsg(scip, " -> %d candidates, selected candidate %d: variable <%s> (frac=%g, factor=%g, score=%g)\n",
547
548 /* Perform the branching */
551
552 return SCIP_OKAY;
553}
554
555
556/*
557 * branching rule specific interface methods
558 */
559
560/** creates the Gomory cut branching rule and includes it in SCIP */
562 SCIP* scip /**< SCIP data structure */
563 )
564{
565 SCIP_BRANCHRULEDATA* branchruledata;
566 SCIP_BRANCHRULE* branchrule;
567
568 /* create branching rule data */
569 SCIP_CALL( SCIPallocBlockMemory(scip, &branchruledata) );
570
571 /* include branching rule */
574
575 assert(branchrule != NULL);
576
577 /* set non-fundamental callbacks via specific setter functions*/
578 SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyGomory) );
579 SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreeGomory) );
580 SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpGomory) );
581
582 /* Gomory cut branching rule parameters */
583 SCIP_CALL( SCIPaddIntParam(scip,"branching/gomory/maxncands",
584 "maximum amount of branching candidates to generate Gomory cuts for (-1: all candidates)",
585 &branchruledata->maxncands, FALSE, DEFAULT_MAXNCANDS, -1, INT_MAX, NULL, NULL) );
586 SCIP_CALL( SCIPaddRealParam(scip,"branching/gomory/efficacyweight",
587 "weight of efficacy in the weighted sum cut scoring rule",
588 &branchruledata->efficacyweight, FALSE, DEFAULT_EFFICACYWEIGHT, -1.0, 1.0, NULL, NULL) );
589 SCIP_CALL( SCIPaddRealParam(scip,"branching/gomory/objparallelweight",
590 "weight of objective parallelism in the weighted sum cut scoring rule",
591 &branchruledata->objparallelweight, FALSE, DEFAULT_OBJPARALLELWEIGHT, -1.0, 1.0, NULL, NULL) );
592 SCIP_CALL( SCIPaddRealParam(scip,"branching/gomory/intsupportweight",
593 "weight of integer support in the weighted sum cut scoring rule",
594 &branchruledata->intsupportweight, FALSE, DEFAULT_INTSUPPORTWEIGHT, -1.0, 1.0, NULL, NULL) );
595 SCIP_CALL( SCIPaddBoolParam(scip,"branching/gomory/performrelpscost",
596 "whether relpscost branching should be called without branching (used for bound inferences and conflicts)",
597 &branchruledata->performrelpscost, FALSE, DEFAULT_PERFORMRELPSCOST, NULL, NULL) );
598 SCIP_CALL( SCIPaddBoolParam(scip,"branching/gomory/useweakercuts",
599 "use weaker cuts that are exactly derived from the branching split disjunction",
600 &branchruledata->useweakercuts, FALSE, DEFAULT_USEWEAKERCUTS, NULL, NULL) );
601
602 return SCIP_OKAY;
603}
#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:255
#define SCIP_Bool
Definition def.h:98
#define MIN(x, y)
Definition def.h:231
#define SCIP_Real
Definition def.h:163
#define TRUE
Definition def.h:100
#define FALSE
Definition def.h:101
#define SCIP_LONGINT_FORMAT
Definition def.h:155
#define SCIP_CALL(x)
Definition def.h:362
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:23683
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23267
SCIP_Real SCIPvarGetBranchFactor(SCIP_VAR *var)
Definition var.c:24450
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
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Var SCIP_VAR
Definition type_var.h:166