SCIP Doxygen Documentation
Loading...
Searching...
No Matches
sepa_disjunctive.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 sepa_disjunctive.c
26 * @ingroup DEFPLUGINS_SEPA
27 * @brief disjunctive cut separator
28 * @author Tobias Fischer
29 * @author Marc Pfetsch
30 *
31 * We separate disjunctive cuts for two term disjunctions of the form \f$x_1 = 0 \vee x_2 = 0\f$. They can be generated
32 * directly from the simplex tableau. For further information, we refer to@n
33 * "A complementarity-based partitioning and disjunctive cut algorithm for mathematical programming problems with
34 * equilibrium constraints"@n
35 * Júdice, J.J., Sherali, H.D., Ribeiro, I.M., Faustino, A.M., Journal of Global Optimization 36(1), 89–114 (2006)
36 *
37 * Cut coefficients belonging to integer variables can be strengthened by the 'monoidal cut strengthening' procedure, see@n
38 * "Strengthening cuts for mixed integer programs"@n
39 * Egon Balas, Robert G. Jeroslow, European Journal of Operational Research, Volume 4, Issue 4, 1980, Pages 224-234
40 */
41
42/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
43
45#include "scip/cons_sos1.h"
46#include "scip/pub_cons.h"
47#include "scip/pub_lp.h"
48#include "scip/pub_message.h"
49#include "scip/pub_misc.h"
50#include "scip/pub_misc_sort.h"
51#include "scip/pub_sepa.h"
52#include "scip/pub_var.h"
53#include "scip/scip_cons.h"
54#include "scip/scip_cut.h"
55#include "scip/scip_general.h"
56#include "scip/scip_lp.h"
57#include "scip/scip_mem.h"
58#include "scip/scip_message.h"
59#include "scip/scip_numerics.h"
60#include "scip/scip_param.h"
61#include "scip/scip_sepa.h"
62#include "scip/scip_sol.h"
64#include "scip/scip_tree.h"
66
67
68#define SEPA_NAME "disjunctive"
69#define SEPA_DESC "disjunctive cut separator"
70#define SEPA_PRIORITY 10 /**< priority for separation */
71#define SEPA_FREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
72#define SEPA_MAXBOUNDDIST 0.0 /**< maximal relative distance from the current node's dual bound to primal bound
73 * compared to best node's dual bound for applying separation.*/
74#define SEPA_USESSUBSCIP FALSE /**< does the separator use a secondary SCIP instance? */
75#define SEPA_DELAY TRUE /**< should separation method be delayed, if other separators found cuts? */
76
77#define DEFAULT_MAXRANK 20 /**< maximal rank of a cut that could not be scaled to integral coefficients (-1: unlimited) */
78#define DEFAULT_MAXRANKINTEGRAL -1 /**< maximal rank of a cut that could be scaled to integral coefficients (-1: unlimited) */
79#define DEFAULT_MAXWEIGHTRANGE 1e+03 /**< maximal valid range max(|weights|)/min(|weights|) of row weights */
80#define DEFAULT_STRENGTHEN TRUE /**< strengthen cut if integer variables are present */
81
82#define DEFAULT_MAXDEPTH -1 /**< node depth of separating cuts (-1: no limit) */
83#define DEFAULT_MAXROUNDS 25 /**< maximal number of separation rounds in a branching node (-1: no limit) */
84#define DEFAULT_MAXROUNDSROOT 100 /**< maximal number of separation rounds in the root node (-1: no limit) */
85#define DEFAULT_MAXINVCUTS 50 /**< maximal number of cuts investigated per iteration in a branching node */
86#define DEFAULT_MAXINVCUTSROOT 250 /**< maximal number of cuts investigated per iteration in the root node */
87#define DEFAULT_MAXCONFSDELAY 100000 /**< delay separation if number of conflict graph edges is larger than predefined value (-1: no limit) */
88
89#define MAKECONTINTEGRAL FALSE /**< convert continuous variable to integral variables in SCIPmakeRowIntegral() */
90
91
92/** separator data */
93struct SCIP_SepaData
94{
95 SCIP_Bool strengthen; /**< strengthen cut if integer variables are present */
96 SCIP_CONSHDLR* conshdlr; /**< SOS1 constraint handler */
97 SCIP_Real maxweightrange; /**< maximal valid range max(|weights|)/min(|weights|) of row weights */
98 int maxrank; /**< maximal rank of a cut that could not be scaled to integral coefficients (-1: unlimited) */
99 int maxrankintegral; /**< maximal rank of a cut that could be scaled to integral coefficients (-1: unlimited) */
100 int maxdepth; /**< node depth of separating cuts (-1: no limit) */
101 int maxrounds; /**< maximal number of separation rounds in a branching node (-1: no limit) */
102 int maxroundsroot; /**< maximal number of separation rounds in the root node (-1: no limit) */
103 int maxinvcuts; /**< maximal number of cuts separated per iteration in a branching node */
104 int maxinvcutsroot; /**< maximal number of cuts separated per iteration in the root node */
105 int maxconfsdelay; /**< delay separation if number of conflict graph edges is larger than predefined value (-1: no limit) */
106 int lastncutsfound; /**< total number of cuts found after last call of separator */
107};
108
109
110/** gets rank of variable corresponding to row of \f$B^{-1}\f$ */
111static
113 SCIP* scip, /**< SCIP pointer */
114 SCIP_Real* binvrow, /**< row of \f$B^{-1}\f$ */
115 SCIP_Real* rowsmaxval, /**< maximal row multiplicator from nonbasic matrix A_N */
116 SCIP_Real maxweightrange, /**< maximal valid range max(|weights|)/min(|weights|) of row weights */
117 SCIP_ROW** rows, /**< rows of LP relaxation of scip */
118 int nrows /**< number of rows */
119 )
120{
121 SCIP_Real maxweight = 0.0;
122 int maxrank = 0;
123 int r;
124
125 assert( scip != NULL );
126 assert( binvrow != NULL || nrows == 0 );
127 assert( rowsmaxval != NULL || nrows == 0 );
128 assert( rows != NULL || nrows == 0 );
129
130 /* compute maximum row weights resulting from multiplication */
131 for (r = 0; r < nrows; ++r)
132 {
133 SCIP_Real val;
134
135 val = REALABS(binvrow[r] * rowsmaxval[r]);/*lint !e613*/
136 if ( SCIPisGT(scip, val, maxweight) )
137 maxweight = val;
138 }
139
140 /* compute rank */
141 for (r = 0; r < nrows; ++r)
142 {
143 SCIP_Real val;
144 int rank;
145
146 val = REALABS(binvrow[r] * rowsmaxval[r]);/*lint !e613*/
147 rank = SCIProwGetRank(rows[r]);/*lint !e613*/
148 if ( rank > maxrank && SCIPisGT(scip, val * maxweightrange, maxweight) )
149 maxrank = rank;
150 }
151
152 return maxrank;
153}
154
155
156/** gets the nonbasic coefficients of a simplex row */
157static
159 SCIP* scip, /**< SCIP pointer */
160 SCIP_ROW** rows, /**< LP rows */
161 int nrows, /**< number LP rows */
162 SCIP_COL** cols, /**< LP columns */
163 int ncols, /**< number of LP columns */
164 SCIP_Real* coef, /**< row of \f$B^{-1} \cdot A\f$ */
165 SCIP_Real* binvrow, /**< row of \f$B^{-1}\f$ */
166 SCIP_Real* simplexcoefs, /**< pointer to store the nonbasic simplex-coefficients */
167 int* nonbasicnumber /**< pointer to store the number of nonbasic simplex-coefficients */
168 )
169{
170 int r;
171 int c;
172
173 assert( scip != NULL );
174 assert( rows != NULL );
175 assert( nonbasicnumber != NULL );
176 assert( simplexcoefs != NULL );
177 assert( cols != NULL );
178
179 *nonbasicnumber = 0;
180
181 /* note: the non-slack variables have to be added first (see the function generateDisjCutSOS1()) */
182
183 /* get simplex-coefficients of the non-basic non-slack variables */
184 for (c = 0; c < ncols; ++c)
185 {
186 SCIP_COL* col;
187
188 col = cols[c];
189 assert( col != NULL );
191 simplexcoefs[(*nonbasicnumber)++] = coef[c];
192 }
193
194 /* get simplex-coefficients of the non-basic slack variables */
195 for (r = 0; r < nrows; ++r)
196 {
197 SCIP_ROW* row;
198 row = rows[r];
199 assert( row != NULL );
200
202 {
204
205 simplexcoefs[(*nonbasicnumber)++] = binvrow[r];
206 }
207 }
208
209 return SCIP_OKAY;
210}
211
212
213/** computes a disjunctive cut inequality based on two simplex tableau rows */
214static
216 SCIP* scip, /**< SCIP pointer */
217 SCIP_SEPA* sepa, /**< separator */
218 int depth, /**< current depth */
219 SCIP_ROW** rows, /**< LP rows */
220 int nrows, /**< number of LP rows */
221 SCIP_COL** cols, /**< LP columns */
222 int ncols, /**< number of LP columns */
223 int ndisjcuts, /**< number of disjunctive cuts found so far */
224 SCIP_Bool scale, /**< should cut be scaled */
225 SCIP_Bool strengthen, /**< should cut be strengthened if integer variables are present */
226 SCIP_Real cutlhs1, /**< left hand side of the first simplex row */
227 SCIP_Real cutlhs2, /**< left hand side of the second simplex row */
228 SCIP_Real bound1, /**< bound of first simplex row */
229 SCIP_Real bound2, /**< bound of second simplex row */
230 SCIP_Real* simplexcoefs1, /**< simplex coefficients of first row */
231 SCIP_Real* simplexcoefs2, /**< simplex coefficients of second row */
232 SCIP_Real* cutcoefs, /**< pointer to store cut coefficients (length: nscipvars) */
233 SCIP_ROW** row, /**< pointer to store disjunctive cut inequality */
234 SCIP_Bool* madeintegral /**< pointer to store whether cut has been scaled to integral values */
235 )
236{
237 char cutname[SCIP_MAXSTRLEN];
238 SCIP_COL** rowcols;
239 SCIP_COL* col;
240 SCIP_Real* rowvals;
241 SCIP_Real lhsrow;
242 SCIP_Real rhsrow;
243 SCIP_Real cutlhs;
244 SCIP_Real sgn;
245 SCIP_Real lb;
246 SCIP_Real ub;
247 int nonbasicnumber = 0;
248 int rownnonz;
249 int ind;
250 int r;
251 int c;
252
253 assert( scip != NULL );
254 assert( row != NULL );
255 assert( rows != NULL );
256 assert( cols != NULL );
257 assert( simplexcoefs1 != NULL );
258 assert( simplexcoefs2 != NULL );
259 assert( cutcoefs != NULL );
260 assert( sepa != NULL );
261 assert( madeintegral != NULL );
262
263 *madeintegral = FALSE;
264
265 /* check signs */
266 if ( SCIPisFeasPositive(scip, cutlhs1) == SCIPisFeasPositive(scip, cutlhs2) )
267 sgn = 1.0;
268 else
269 sgn = -1.0;
270
271 /* check bounds */
272 if ( SCIPisInfinity(scip, REALABS(bound1)) || SCIPisInfinity(scip, REALABS(bound2)) )
273 strengthen = FALSE;
274
275 /* compute left hand side of row (a later update is possible, see below) */
276 cutlhs = sgn * cutlhs1 * cutlhs2;
277
278 /* add cut-coefficients of the non-basic non-slack variables */
279 for (c = 0; c < ncols; ++c)
280 {
281 col = cols[c];
282 assert( col != NULL );
283 ind = SCIPcolGetLPPos(col);
284 assert( ind >= 0 );
285
287 {
288 lb = SCIPcolGetLb(col);
289
290 /* for integer variables we may obtain stronger coefficients */
291 if ( strengthen && SCIPcolIsIntegral(col) )
292 {
293 SCIP_Real mval;
294 SCIP_Real mvalfloor;
295 SCIP_Real mvalceil;
296
297 mval = (cutlhs2 * simplexcoefs1[nonbasicnumber] - cutlhs1 * simplexcoefs2[nonbasicnumber]) / (cutlhs2 * bound1 + cutlhs1 * bound2);
298 mvalfloor = SCIPfloor(scip, mval);
299 mvalceil = SCIPceil(scip, mval);
300
301 cutcoefs[ind] = MIN(sgn * cutlhs2 * (simplexcoefs1[nonbasicnumber] - mvalfloor * bound1), sgn * cutlhs1 * (simplexcoefs2[nonbasicnumber] + mvalceil * bound2));
302 assert( SCIPisFeasLE(scip, cutcoefs[ind], MAX(sgn * cutlhs2 * simplexcoefs1[nonbasicnumber], sgn * cutlhs1 * simplexcoefs2[nonbasicnumber])) );
303 }
304 else
305 cutcoefs[ind] = MAX(sgn * cutlhs2 * simplexcoefs1[nonbasicnumber], sgn * cutlhs1 * simplexcoefs2[nonbasicnumber]);
306
307 cutlhs += cutcoefs[ind] * lb;
308 ++nonbasicnumber;
309 }
311 {
312 ub = SCIPcolGetUb(col);
313
314 /* for integer variables we may obtain stronger coefficients */
315 if ( strengthen && SCIPcolIsIntegral(col) )
316 {
317 SCIP_Real mval;
318 SCIP_Real mvalfloor;
319 SCIP_Real mvalceil;
320
321 mval = (cutlhs2 * simplexcoefs1[nonbasicnumber] - cutlhs1 * simplexcoefs2[nonbasicnumber]) / (cutlhs2 * bound1 + cutlhs1 * bound2);
322 mvalfloor = SCIPfloor(scip, -mval);
323 mvalceil = SCIPceil(scip, -mval);
324
325 cutcoefs[ind] = MAX(sgn * cutlhs2 * (simplexcoefs1[nonbasicnumber] + mvalfloor * bound1), sgn * cutlhs1 * (simplexcoefs2[nonbasicnumber] - mvalceil * bound2));
326 assert( SCIPisFeasLE(scip, -cutcoefs[ind], -MIN(sgn * cutlhs2 * simplexcoefs1[nonbasicnumber], sgn * cutlhs1 * simplexcoefs2[nonbasicnumber])) );
327 }
328 else
329 cutcoefs[ind] = MIN(sgn * cutlhs2 * simplexcoefs1[nonbasicnumber], sgn * cutlhs1 * simplexcoefs2[nonbasicnumber]);
330
331 cutlhs += cutcoefs[ind] * ub;
332 ++nonbasicnumber;
333 }
334 else
335 {
337 cutcoefs[ind] = 0.0;
338 }
339 }
340
341 /* add cut-coefficients of the non-basic slack variables */
342 for (r = 0; r < nrows; ++r)
343 {
344 rhsrow = SCIProwGetRhs(rows[r]) - SCIProwGetConstant(rows[r]);
345 lhsrow = SCIProwGetLhs(rows[r]) - SCIProwGetConstant(rows[r]);
346
348 assert( SCIPisFeasZero(scip, lhsrow - rhsrow) || SCIPisNegative(scip, lhsrow - rhsrow) );
349 assert( SCIProwIsInLP(rows[r]) );
350
352 {
353 SCIP_Real cutcoef;
354
356 {
358
359 cutcoef = MAX(sgn * cutlhs2 * simplexcoefs1[nonbasicnumber], sgn * cutlhs1 * simplexcoefs2[nonbasicnumber]);
360 cutlhs -= cutcoef * rhsrow;
361 ++nonbasicnumber;
362 }
363 else /* SCIProwGetBasisStatus(rows[r]) == SCIP_BASESTAT_LOWER */
364 {
367
368 cutcoef = MIN(sgn * cutlhs2 * simplexcoefs1[nonbasicnumber], sgn * cutlhs1 * simplexcoefs2[nonbasicnumber]);
369 cutlhs -= cutcoef * lhsrow;
370 ++nonbasicnumber;
371 }
372
373 rownnonz = SCIProwGetNNonz(rows[r]);
374 rowvals = SCIProwGetVals(rows[r]);
375 rowcols = SCIProwGetCols(rows[r]);
376
377 for (c = 0; c < rownnonz; ++c)
378 {
379 ind = SCIPcolGetLPPos(rowcols[c]);
380
381 /* if column is not in LP, then return without generating cut */
382 if ( ind < 0 )
383 {
384 *row = NULL;
385 return SCIP_OKAY;
386 }
387
388 cutcoefs[ind] -= cutcoef * rowvals[c];
389 }
390 }
391 }
392
393 /* create cut */
394 (void) SCIPsnprintf(cutname, SCIP_MAXSTRLEN, "%s_%" SCIP_LONGINT_FORMAT "_%d", SCIPsepaGetName(sepa), SCIPgetNLPs(scip), ndisjcuts);
395
396 /* we create the cut as locally valid, SCIP will make it globally valid if we are at the root node */
397 SCIP_CALL( SCIPcreateEmptyRowSepa(scip, row, sepa, cutname, cutlhs, SCIPinfinity(scip), TRUE, FALSE, TRUE) );
398
400 for (c = 0; c < ncols; ++c)
401 {
402 ind = SCIPcolGetLPPos(cols[c]);
403 assert( ind >= 0 );
404 if ( ! SCIPisFeasZero(scip, cutcoefs[ind]) )
405 {
406 SCIP_CALL( SCIPaddVarToRow(scip, *row, SCIPcolGetVar(cols[c]), cutcoefs[ind] ) );
407 }
408 }
410
411 /* try to scale the cut to integral values
412 * @todo find better but still stable disjunctive cut settings
413 */
414 if ( scale )
415 {
416 SCIP_Longint maxdnom;
417 SCIP_Real maxscale;
418
419 assert( depth >= 0 );
420 if( depth == 0 )
421 {
422 maxdnom = 100;
423 maxscale = 100.0;
424 }
425 else
426 {
427 maxdnom = 10;
428 maxscale = 10.0;
429 }
430
431 SCIP_CALL( SCIPmakeRowIntegral(scip, *row, -SCIPepsilon(scip), SCIPsumepsilon(scip), maxdnom, maxscale, TRUE, madeintegral) );
432 }
433
434 return SCIP_OKAY;
435}
436
437
438/*
439 * Callback methods
440 */
441
442/** copy method for separator plugins (called when SCIP copies plugins) */
443static
444SCIP_DECL_SEPACOPY(sepaCopyDisjunctive)
445{
446 assert( scip != NULL );
447 assert( sepa != NULL );
448
450
451 /* call inclusion method of constraint handler */
453
454 return SCIP_OKAY;
455}
456
457
458/** destructor of separator to free user data (called when SCIP is exiting) */
459static
460SCIP_DECL_SEPAFREE(sepaFreeDisjunctive)/*lint --e{715}*/
461{
463
465
466 /* free separator data */
469
471
473
474 return SCIP_OKAY;
475}
476
477
478/** solving process initialization method of separator */
479static
480SCIP_DECL_SEPAEXITSOL(sepaInitsolDisjunctive)
481{ /*lint --e{715}*/
483
485 assert(sepadata != NULL);
486
487 sepadata->conshdlr = SCIPfindConshdlr(scip, "SOS1");
488
489 return SCIP_OKAY;
490}
491
492
493/** LP solution separation method for disjunctive cuts */
494static
495SCIP_DECL_SEPAEXECLP(sepaExeclpDisjunctive)
496{
498 SCIP_CONSHDLR* conshdlr;
499 SCIP_DIGRAPH* conflictgraph;
500 SCIP_ROW** rows;
501 SCIP_COL** cols;
502 SCIP_Real* cutcoefs = NULL;
503 SCIP_Real* simplexcoefs1 = NULL;
504 SCIP_Real* simplexcoefs2 = NULL;
505 SCIP_Real* coef = NULL;
506 SCIP_Real* binvrow = NULL;
507 SCIP_Real* rowsmaxval = NULL;
508 SCIP_Real* violationarray = NULL;
509 int* fixings1 = NULL;
510 int* fixings2 = NULL;
511 int* basisind = NULL;
512 int* basisrow = NULL;
513 int* varrank = NULL;
514 int* edgearray = NULL;
515 int nedges;
516 int ndisjcuts;
517 int nrelevantedges;
518 int nsos1vars;
519 int nconss;
520 int maxcuts;
521 int ncalls;
522 int ncols;
523 int nrows;
524 int ind;
525 int j;
526 int i;
527
528 assert( sepa != NULL );
529 assert( scip != NULL );
530 assert( result != NULL );
531
533
535
536 if( !allowlocal )
537 return SCIP_OKAY;
538
539 /* only generate disjunctive cuts if we are not close to terminating */
540 if ( SCIPisStopped(scip) )
541 return SCIP_OKAY;
542
543 /* only generate disjunctive cuts if an optimal LP solution is at hand */
545 return SCIP_OKAY;
546
547 /* only generate disjunctive cuts if the LP solution is basic */
548 if ( ! SCIPisLPSolBasic(scip) )
549 return SCIP_OKAY;
550
551 /* get LP data */
552 SCIP_CALL( SCIPgetLPColsData(scip, &cols, &ncols) );
553 SCIP_CALL( SCIPgetLPRowsData(scip, &rows, &nrows) );
554
555 /* return if LP has no columns or no rows */
556 if ( ncols == 0 || nrows == 0 )
557 return SCIP_OKAY;
558
559 assert( cols != NULL );
560 assert( rows != NULL );
561
562 /* get sepa data */
564 assert( sepadata != NULL );
565
566 /* get constraint handler */
567 conshdlr = sepadata->conshdlr;
568 if ( conshdlr == NULL )
569 return SCIP_OKAY;
570
571 /* get number of constraints */
572 nconss = SCIPconshdlrGetNConss(conshdlr);
573 if ( nconss == 0 )
574 return SCIP_OKAY;
575
576 /* check for maxdepth < depth, maxinvcutsroot = 0 and maxinvcuts = 0 */
577 if ( ( sepadata->maxdepth >= 0 && sepadata->maxdepth < depth )
578 || ( depth == 0 && sepadata->maxinvcutsroot == 0 )
579 || ( depth > 0 && sepadata->maxinvcuts == 0 ) )
580 return SCIP_OKAY;
581
582 /* only call the cut separator a given number of times at each node */
584 if ( (depth == 0 && sepadata->maxroundsroot >= 0 && ncalls >= sepadata->maxroundsroot)
585 || (depth > 0 && sepadata->maxrounds >= 0 && ncalls >= sepadata->maxrounds) )
586 return SCIP_OKAY;
587
588 /* get conflict graph and number of conflict graph edges (note that the digraph arcs were added in both directions) */
589 conflictgraph = SCIPgetConflictgraphSOS1(conshdlr);
590 if( conflictgraph == NULL )
591 return SCIP_OKAY;
592
593 nedges = (int)SCIPceil(scip, (SCIP_Real)SCIPdigraphGetNArcs(conflictgraph)/2);
594
595 /* if too many conflict graph edges, the separator can be slow: delay it until no other cuts have been found */
596 if ( sepadata->maxconfsdelay >= 0 && nedges >= sepadata->maxconfsdelay )
597 {
598 int ncutsfound;
599
600 ncutsfound = SCIPgetNCutsFound(scip);
601 if ( ncutsfound > sepadata->lastncutsfound || ! SCIPsepaWasLPDelayed(sepa) )
602 {
603 sepadata->lastncutsfound = ncutsfound;
605 return SCIP_OKAY;
606 }
607 }
608
609 /* check basis status */
610 for (j = 0; j < ncols; ++j)
611 {
613 return SCIP_OKAY;
614 }
615
616 /* check accuracy of rows */
617 for (j = 0; j < nrows; ++j)
618 {
619 SCIP_ROW* row;
620
621 row = rows[j];
622
625 return SCIP_OKAY;
626 }
627
628 /* get number of SOS1 variables */
629 nsos1vars = SCIPgetNSOS1Vars(conshdlr);
630
631 /* allocate buffer arrays */
632 SCIP_CALL( SCIPallocBufferArray(scip, &edgearray, nedges) );
633 SCIP_CALL( SCIPallocBufferArray(scip, &fixings1, nedges) );
634 SCIP_CALL( SCIPallocBufferArray(scip, &fixings2, nedges) );
635 SCIP_CALL( SCIPallocBufferArray(scip, &violationarray, nedges) );
636
637 /* get all violated conflicts {i, j} in the conflict graph and sort them based on the degree of a violation value */
638 nrelevantedges = 0;
639 for (j = 0; j < nsos1vars; ++j)
640 {
641 SCIP_VAR* var;
642
643 var = SCIPnodeGetVarSOS1(conflictgraph, j);
644
646 {
647 int* succ;
648 int nsucc;
649
650 /* get successors and number of successors */
651 nsucc = SCIPdigraphGetNSuccessors(conflictgraph, j);
652 succ = SCIPdigraphGetSuccessors(conflictgraph, j);
653
654 for (i = 0; i < nsucc; ++i)
655 {
656 SCIP_VAR* varsucc;
657 int succind;
658
659 succind = succ[i];
660 varsucc = SCIPnodeGetVarSOS1(conflictgraph, succind);
661 if ( SCIPvarIsActive(varsucc) && succind < j && ! SCIPisFeasZero(scip, SCIPgetSolVal(scip, NULL, varsucc) ) &&
663 {
664 fixings1[nrelevantedges] = j;
665 fixings2[nrelevantedges] = succind;
666 edgearray[nrelevantedges] = nrelevantedges;
667 violationarray[nrelevantedges++] = SCIPgetSolVal(scip, NULL, var) * SCIPgetSolVal(scip, NULL, varsucc);
668 }
669 }
670 }
671 }
672
673 /* sort violation score values */
674 if ( nrelevantedges > 0)
675 SCIPsortDownRealInt(violationarray, edgearray, nrelevantedges);
676 else
677 {
678 SCIPfreeBufferArrayNull(scip, &violationarray);
679 SCIPfreeBufferArrayNull(scip, &fixings2);
680 SCIPfreeBufferArrayNull(scip, &fixings1);
681 SCIPfreeBufferArrayNull(scip, &edgearray);
682
683 return SCIP_OKAY;
684 }
685 SCIPfreeBufferArrayNull(scip, &violationarray);
686
687 /* compute maximal number of cuts */
688 if ( depth == 0 )
689 maxcuts = MIN(sepadata->maxinvcutsroot, nrelevantedges);
690 else
691 maxcuts = MIN(sepadata->maxinvcuts, nrelevantedges);
692 assert( maxcuts > 0 );
693
694 /* allocate buffer arrays */
695 SCIP_CALL( SCIPallocBufferArray(scip, &varrank, ncols) );
696 SCIP_CALL( SCIPallocBufferArray(scip, &rowsmaxval, nrows) );
697 SCIP_CALL( SCIPallocBufferArray(scip, &basisrow, ncols) );
698 SCIP_CALL( SCIPallocBufferArray(scip, &binvrow, nrows) );
699 SCIP_CALL( SCIPallocBufferArray(scip, &coef, ncols) );
700 SCIP_CALL( SCIPallocBufferArray(scip, &simplexcoefs1, ncols) );
701 SCIP_CALL( SCIPallocBufferArray(scip, &simplexcoefs2, ncols) );
702 SCIP_CALL( SCIPallocBufferArray(scip, &cutcoefs, ncols) );
703 SCIP_CALL( SCIPallocBufferArray(scip, &basisind, nrows) );
704
705 /* get basis indices */
706 SCIP_CALL( SCIPgetLPBasisInd(scip, basisind) );
707
708 /* create vector "basisrow" with basisrow[column of non-slack basis variable] = corresponding row of B^-1;
709 * compute maximum absolute value of nonbasic row coefficients */
710 for (j = 0; j < nrows; ++j)
711 {
712 SCIP_COL** rowcols;
713 SCIP_Real* rowvals;
714 SCIP_ROW* row;
715 SCIP_Real val;
716 SCIP_Real max = 0.0;
717 int nnonz;
718
719 /* fill basisrow vector */
720 ind = basisind[j];
721 if ( ind >= 0 )
722 basisrow[ind] = j;
723
724 /* compute maximum absolute value of nonbasic row coefficients */
725 row = rows[j];
726 assert( row != NULL );
727 rowvals = SCIProwGetVals(row);
728 nnonz = SCIProwGetNNonz(row);
729 rowcols = SCIProwGetCols(row);
730
731 for (i = 0; i < nnonz; ++i)
732 {
734 {
735 val = REALABS(rowvals[i]);
736 if ( SCIPisFeasGT(scip, val, max) )
737 max = REALABS(val);
738 }
739 }
740
741 /* handle slack variable coefficient and save maximum value */
742 rowsmaxval[j] = MAX(max, 1.0);
743 }
744
745 /* initialize variable ranks with -1 */
746 for (j = 0; j < ncols; ++j)
747 varrank[j] = -1;
748
749 /* free buffer array */
750 SCIPfreeBufferArrayNull(scip, &basisind);
751
752 /* for the most promising disjunctions: try to generate disjunctive cuts */
753 ndisjcuts = 0;
754 for (i = 0; i < maxcuts; ++i)
755 {
756 SCIP_Bool madeintegral;
757 SCIP_Real cutlhs1;
758 SCIP_Real cutlhs2;
759 SCIP_Real bound1;
760 SCIP_Real bound2;
761 SCIP_ROW* row = NULL;
762 SCIP_VAR* var;
763 SCIP_COL* col;
764
765 int nonbasicnumber;
766 int cutrank = 0;
767 int edgenumber;
768 int rownnonz;
769
770 edgenumber = edgearray[i];
771
772 /* determine first simplex row */
773 var = SCIPnodeGetVarSOS1(conflictgraph, fixings1[edgenumber]);
774 col = SCIPvarGetCol(var);
775 ind = SCIPcolGetLPPos(col);
776 assert( ind >= 0 );
778
779 /* get the 'ind'th row of B^-1 and B^-1 \cdot A */
780 SCIP_CALL( SCIPgetLPBInvRow(scip, basisrow[ind], binvrow, NULL, NULL) );
781 SCIP_CALL( SCIPgetLPBInvARow(scip, basisrow[ind], binvrow, coef, NULL, NULL) );
782
783 /* get the simplex-coefficients of the non-basic variables */
784 SCIP_CALL( getSimplexCoefficients(scip, rows, nrows, cols, ncols, coef, binvrow, simplexcoefs1, &nonbasicnumber) );
785
786 /* get rank of variable if not known already */
787 if ( varrank[ind] < 0 )
788 varrank[ind] = getVarRank(scip, binvrow, rowsmaxval, sepadata->maxweightrange, rows, nrows);
789 cutrank = MAX(cutrank, varrank[ind]);
790
791 /* get right hand side and bound of simplex talbeau row */
792 cutlhs1 = SCIPcolGetPrimsol(col);
793 if ( SCIPisFeasPositive(scip, cutlhs1) )
794 bound1 = SCIPcolGetUb(col);
795 else
796 bound1 = SCIPcolGetLb(col);
797
798 /* determine second simplex row */
799 var = SCIPnodeGetVarSOS1(conflictgraph, fixings2[edgenumber]);
800 col = SCIPvarGetCol(var);
801 ind = SCIPcolGetLPPos(col);
802 assert( ind >= 0 );
804
805 /* get the 'ind'th row of B^-1 and B^-1 \cdot A */
806 SCIP_CALL( SCIPgetLPBInvRow(scip, basisrow[ind], binvrow, NULL, NULL) );
807 SCIP_CALL( SCIPgetLPBInvARow(scip, basisrow[ind], binvrow, coef, NULL, NULL) );
808
809 /* get the simplex-coefficients of the non-basic variables */
810 SCIP_CALL( getSimplexCoefficients(scip, rows, nrows, cols, ncols, coef, binvrow, simplexcoefs2, &nonbasicnumber) );
811
812 /* get rank of variable if not known already */
813 if ( varrank[ind] < 0 )
814 varrank[ind] = getVarRank(scip, binvrow, rowsmaxval, sepadata->maxweightrange, rows, nrows);
815 cutrank = MAX(cutrank, varrank[ind]);
816
817 /* get right hand side and bound of simplex talbeau row */
818 cutlhs2 = SCIPcolGetPrimsol(col);
819 if ( SCIPisFeasPositive(scip, cutlhs2) )
820 bound2 = SCIPcolGetUb(col);
821 else
822 bound2 = SCIPcolGetLb(col);
823
824 /* add coefficients to cut */
825 SCIP_CALL( generateDisjCutSOS1(scip, sepa, depth, rows, nrows, cols, ncols, ndisjcuts, MAKECONTINTEGRAL, sepadata->strengthen, cutlhs1, cutlhs2, bound1, bound2, simplexcoefs1, simplexcoefs2, cutcoefs, &row, &madeintegral) );
826 if ( row == NULL )
827 continue;
828
829 /* raise cutrank for present cut */
830 ++cutrank;
831
832 /* check if there are numerical evidences */
833 if ( ( madeintegral && ( sepadata->maxrankintegral == -1 || cutrank <= sepadata->maxrankintegral ) )
834 || ( ! madeintegral && ( sepadata->maxrank == -1 || cutrank <= sepadata->maxrank ) ) )
835 {
836 /* possibly add cut to LP if it is useful; in case the lhs of the cut is minus infinity (due to scaling) the cut is useless */
837 rownnonz = SCIProwGetNNonz(row);
838 if ( rownnonz > 0 && ! SCIPisInfinity(scip, -SCIProwGetLhs(row)) && ! SCIProwIsInLP(row) && SCIPisCutEfficacious(scip, NULL, row) )
839 {
840 SCIP_Bool infeasible;
841
842 /* set cut rank */
843 SCIProwChgRank(row, cutrank);
844
845 /* add cut */
846 SCIP_CALL( SCIPaddRow(scip, row, FALSE, &infeasible) );
848 if ( infeasible )
849 {
851 break;
852 }
853 ++ndisjcuts;
854 }
855 }
856
857 /* release row */
858 SCIP_CALL( SCIPreleaseRow(scip, &row) );
859 }
860
861 /* save total number of cuts found so far */
862 sepadata->lastncutsfound = SCIPgetNCutsFound(scip);
863
864 /* evaluate the result of the separation */
865 if ( *result != SCIP_CUTOFF )
866 {
867 if ( ndisjcuts > 0 )
869 else
871 }
872
873 SCIPdebugMsg(scip, "Number of found disjunctive cuts: %d.\n", ndisjcuts);
874
875 /* free buffer arrays */
876 SCIPfreeBufferArrayNull(scip, &cutcoefs);
877 SCIPfreeBufferArrayNull(scip, &simplexcoefs2);
878 SCIPfreeBufferArrayNull(scip, &simplexcoefs1);
880 SCIPfreeBufferArrayNull(scip, &binvrow);
881 SCIPfreeBufferArrayNull(scip, &basisrow);
882 SCIPfreeBufferArrayNull(scip, &rowsmaxval);
883 SCIPfreeBufferArrayNull(scip, &varrank);
884 SCIPfreeBufferArrayNull(scip, &fixings2);
885 SCIPfreeBufferArrayNull(scip, &fixings1);
886 SCIPfreeBufferArrayNull(scip, &edgearray);
887
888 return SCIP_OKAY;
889}
890
891
892/** creates the disjunctive cut separator and includes it in SCIP */
894 SCIP* scip /**< SCIP data structure */
895 )
896{
898 SCIP_SEPA* sepa = NULL;
899
900 /* create separator data */
902 sepadata->conshdlr = NULL;
903 sepadata->lastncutsfound = 0;
904
905 /* include separator */
907 SEPA_USESSUBSCIP, SEPA_DELAY, sepaExeclpDisjunctive, NULL, sepadata) );
908
909 assert( sepa != NULL );
910
911 /* set non fundamental callbacks via setter functions */
912 SCIP_CALL( SCIPsetSepaCopy(scip, sepa, sepaCopyDisjunctive) );
913 SCIP_CALL( SCIPsetSepaFree(scip, sepa, sepaFreeDisjunctive) );
914 SCIP_CALL( SCIPsetSepaInitsol(scip, sepa, sepaInitsolDisjunctive) );
915
916 /* add separator parameters */
917 SCIP_CALL( SCIPaddBoolParam(scip, "separating/" SEPA_NAME "/strengthen",
918 "strengthen cut if integer variables are present.",
919 &sepadata->strengthen, TRUE, DEFAULT_STRENGTHEN, NULL, NULL) );
920
921 SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxdepth",
922 "node depth of separating bipartite disjunctive cuts (-1: no limit)",
923 &sepadata->maxdepth, TRUE, DEFAULT_MAXDEPTH, -1, INT_MAX, NULL, NULL) );
924
925 SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxrounds",
926 "maximal number of separation rounds per iteration in a branching node (-1: no limit)",
927 &sepadata->maxrounds, TRUE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
928
929 SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxroundsroot",
930 "maximal number of separation rounds in the root node (-1: no limit)",
931 &sepadata->maxroundsroot, TRUE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
932
933 SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxinvcuts",
934 "maximal number of cuts investigated per iteration in a branching node",
935 &sepadata->maxinvcuts, TRUE, DEFAULT_MAXINVCUTS, 0, INT_MAX, NULL, NULL) );
936
937 SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxinvcutsroot",
938 "maximal number of cuts investigated per iteration in the root node",
939 &sepadata->maxinvcutsroot, TRUE, DEFAULT_MAXINVCUTSROOT, 0, INT_MAX, NULL, NULL) );
940
941 SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxconfsdelay",
942 "delay separation if number of conflict graph edges is larger than predefined value (-1: no limit)",
943 &sepadata->maxconfsdelay, TRUE, DEFAULT_MAXCONFSDELAY, -1, INT_MAX, NULL, NULL) );
944
945 SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxrank",
946 "maximal rank of a disj. cut that could not be scaled to integral coefficients (-1: unlimited)",
947 &sepadata->maxrank, FALSE, DEFAULT_MAXRANK, -1, INT_MAX, NULL, NULL) );
948
949 SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxrankintegral",
950 "maximal rank of a disj. cut that could be scaled to integral coefficients (-1: unlimited)",
951 &sepadata->maxrankintegral, FALSE, DEFAULT_MAXRANKINTEGRAL, -1, INT_MAX, NULL, NULL) );
952
953 SCIP_CALL( SCIPaddRealParam(scip, "separating/" SEPA_NAME "/maxweightrange",
954 "maximal valid range max(|weights|)/min(|weights|) of row weights",
955 &sepadata->maxweightrange, TRUE, DEFAULT_MAXWEIGHTRANGE, 1.0, SCIP_REAL_MAX, NULL, NULL) );
956
957 return SCIP_OKAY;
958}
#define DEFAULT_MAXDEPTH
#define DEFAULT_MAXROUNDSROOT
#define DEFAULT_MAXROUNDS
#define DEFAULT_STRENGTHEN
constraint handler for SOS type 1 constraints
#define NULL
Definition def.h:257
#define SCIP_MAXSTRLEN
Definition def.h:278
#define SCIP_Longint
Definition def.h:150
#define SCIP_REAL_MAX
Definition def.h:167
#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 MAX(x, y)
Definition def.h:229
#define SCIP_LONGINT_FORMAT
Definition def.h:157
#define REALABS(x)
Definition def.h:191
#define SCIP_CALL(x)
Definition def.h:364
SCIP_DIGRAPH * SCIPgetConflictgraphSOS1(SCIP_CONSHDLR *conshdlr)
int SCIPgetNSOS1Vars(SCIP_CONSHDLR *conshdlr)
SCIP_VAR * SCIPnodeGetVarSOS1(SCIP_DIGRAPH *conflictgraph, int node)
int SCIPdigraphGetNSuccessors(SCIP_DIGRAPH *digraph, int node)
Definition misc.c:7881
int SCIPdigraphGetNArcs(SCIP_DIGRAPH *digraph)
Definition misc.c:7863
int * SCIPdigraphGetSuccessors(SCIP_DIGRAPH *digraph, int node)
Definition misc.c:7896
SCIP_Bool SCIPisStopped(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
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 SCIPcolGetPrimsol(SCIP_COL *col)
Definition lp.c:17379
SCIP_Real SCIPcolGetUb(SCIP_COL *col)
Definition lp.c:17356
SCIP_BASESTAT SCIPcolGetBasisStatus(SCIP_COL *col)
Definition lp.c:17414
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4782
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition scip_cons.c:940
SCIP_Bool SCIPisCutEfficacious(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
Definition scip_cut.c:117
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition scip_cut.c:225
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_Bool SCIPisLPSolBasic(SCIP *scip)
Definition scip_lp.c:673
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 SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition scip_mem.h:137
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition lp.c:17686
SCIP_RETCODE SCIPcacheRowExtensions(SCIP *scip, SCIP_ROW *row)
Definition scip_lp.c:1581
int SCIProwGetNNonz(SCIP_ROW *row)
Definition lp.c:17607
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition lp.c:17632
SCIP_Real SCIPgetRowLPActivity(SCIP *scip, SCIP_ROW *row)
Definition scip_lp.c:1957
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition lp.c:17696
SCIP_RETCODE SCIPflushRowExtensions(SCIP *scip, SCIP_ROW *row)
Definition scip_lp.c:1604
SCIP_RETCODE SCIPmakeRowIntegral(SCIP *scip, SCIP_ROW *row, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Real maxscale, SCIP_Bool usecontvars, SCIP_Bool *success)
Definition scip_lp.c:1790
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition scip_lp.c:1646
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
Definition scip_lp.c:2176
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition scip_lp.c:1508
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:1429
int SCIProwGetRank(SCIP_ROW *row)
Definition lp.c:17775
void SCIProwChgRank(SCIP_ROW *row, int rank)
Definition lp.c:17928
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition lp.c:17652
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition lp.c:17917
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition lp.c:17642
SCIP_BASESTAT SCIProwGetBasisStatus(SCIP_ROW *row)
Definition lp.c:17734
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:115
SCIP_RETCODE SCIPsetSepaFree(SCIP *scip, SCIP_SEPA *sepa,)
Definition scip_sepa.c:173
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
Definition sepa.c:746
int SCIPsepaGetNCallsAtNode(SCIP_SEPA *sepa)
Definition sepa.c:893
SCIP_Bool SCIPsepaWasLPDelayed(SCIP_SEPA *sepa)
Definition sepa.c:1112
SCIP_RETCODE SCIPsetSepaInitsol(SCIP *scip, SCIP_SEPA *sepa,)
Definition scip_sepa.c:221
SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
Definition sepa.c:636
SCIP_RETCODE SCIPsetSepaCopy(SCIP *scip, SCIP_SEPA *sepa,)
Definition scip_sepa.c:157
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1763
SCIP_Longint SCIPgetNLPs(SCIP *scip)
int SCIPgetNCutsFound(SCIP *scip)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPepsilon(SCIP *scip)
SCIP_Real SCIPsumepsilon(SCIP *scip)
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition var.c:23715
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition var.c:23674
SCIP_RETCODE SCIPincludeSepaDisjunctive(SCIP *scip)
void SCIPsortDownRealInt(SCIP_Real *realarray, int *intarray, int len)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10827
return SCIP_OKAY
SCIP_Longint ncalls
int c
int maxdepth
int depth
int r
assert(minobj< SCIPgetCutoffbound(scip))
SCIP_VAR * var
memory allocation routines
public methods for managing constraints
public methods for LP management
public methods for message output
#define SCIPdebug(x)
Definition pub_message.h:93
public data structures and miscellaneous methods
methods for sorting joint arrays of various types
public methods for separators
public methods for problem variables
public methods for constraint handler plugins and constraints
public methods for cuts and aggregation rows
general public methods
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 separator plugins
public methods for solutions
public methods for querying solving statistics
public methods for the branch-and-bound tree
#define SEPA_PRIORITY
#define SEPA_DELAY
#define SEPA_DESC
#define MAKECONTINTEGRAL
#define SEPA_USESSUBSCIP
#define SEPA_MAXBOUNDDIST
#define SEPA_FREQ
#define SEPA_NAME
#define DEFAULT_MAXINVCUTS
#define DEFAULT_MAXWEIGHTRANGE
#define DEFAULT_MAXINVCUTSROOT
#define DEFAULT_MAXRANKINTEGRAL
#define DEFAULT_MAXCONFSDELAY
SCIPsepaSetData(sepa, NULL)
static SCIP_RETCODE getSimplexCoefficients(SCIP *scip, SCIP_ROW **rows, int nrows, SCIP_COL **cols, int ncols, SCIP_Real *coef, SCIP_Real *binvrow, SCIP_Real *simplexcoefs, int *nonbasicnumber)
#define DEFAULT_MAXRANK
static SCIP_RETCODE generateDisjCutSOS1(SCIP *scip, SCIP_SEPA *sepa, int depth, SCIP_ROW **rows, int nrows, SCIP_COL **cols, int ncols, int ndisjcuts, SCIP_Bool scale, SCIP_Bool strengthen, SCIP_Real cutlhs1, SCIP_Real cutlhs2, SCIP_Real bound1, SCIP_Real bound2, SCIP_Real *simplexcoefs1, SCIP_Real *simplexcoefs2, SCIP_Real *cutcoefs, SCIP_ROW **row, SCIP_Bool *madeintegral)
static int getVarRank(SCIP *scip, SCIP_Real *binvrow, SCIP_Real *rowsmaxval, SCIP_Real maxweightrange, SCIP_ROW **rows, int nrows)
disjunctive cut separator
struct SCIP_Conshdlr SCIP_CONSHDLR
Definition type_cons.h:62
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
@ SCIP_BASESTAT_ZERO
Definition type_lpi.h:94
struct SCIP_Digraph SCIP_DIGRAPH
Definition type_misc.h:145
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_CUTOFF
Definition type_result.h:48
@ SCIP_DELAYED
Definition type_result.h:43
@ SCIP_DIDNOTFIND
Definition type_result.h:44
@ SCIP_SEPARATED
Definition type_result.h:49
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_SepaData SCIP_SEPADATA
Definition type_sepa.h:52
#define SCIP_DECL_SEPAEXECLP(x)
Definition type_sepa.h:136
#define SCIP_DECL_SEPAFREE(x)
Definition type_sepa.h:69
#define SCIP_DECL_SEPAEXITSOL(x)
Definition type_sepa.h:107
struct SCIP_Sepa SCIP_SEPA
Definition type_sepa.h:51
#define SCIP_DECL_SEPACOPY(x)
Definition type_sepa.h:61
struct SCIP_Var SCIP_VAR
Definition type_var.h:166