Scippy

SCIP

Solving Constraint Integer Programs

cons_orbisack.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-2025 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 cons_orbisack.c
26 * @ingroup DEFPLUGINS_CONS
27 * @brief constraint handler for orbisack constraints
28 * @author Christopher Hojny
29 * @author Jasper van Doornmalen
30 *
31 *
32 * The type of constraints of this constraint handler is described in cons_orbisack.h.
33 *
34 * The details of the method implemented here are described in the following papers:
35 *
36 * Describing Orbitopes by Linear Inequalities and Projection Based Tools@n
37 * Andreas Loos,@n
38 * PhD thesis, Otto-von-Guericke-Universitaet Magdeburg (2010).
39 *
40 * This thesis provides a complete linear description of orbisacks and a separation
41 * routine for its inequalities.
42 *
43 * Polytopes Associated with Symmetry Handling@n
44 * Christopher Hojny and Marc E. Pfetsch,@n
45 * (2017), preprint available at http://www.optimization-online.org/DB_HTML/2017/01/5835.html
46 *
47 * This paper describes a linear time separation routine for so-called cover inequalities of
48 * orbisacks.
49 */
50
51/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
52
54#include "scip/cons_orbisack.h"
55#include "scip/cons_orbitope.h"
56#include "scip/cons_setppc.h"
57#include "scip/pub_cons.h"
58#include "scip/pub_message.h"
59#include "scip/pub_var.h"
60#include "scip/scip.h"
61#include "scip/scip_branch.h"
62#include "scip/scip_conflict.h"
63#include "scip/scip_cons.h"
64#include "scip/scip_cut.h"
65#include "scip/scip_general.h"
66#include "scip/scip_lp.h"
67#include "scip/scip_mem.h"
68#include "scip/scip_message.h"
69#include "scip/scip_numerics.h"
70#include "scip/scip_param.h"
71#include "scip/scip_sol.h"
72#include "scip/scip_var.h"
73#include "scip/symmetry.h"
74
75
76/* constraint handler properties */
77#define CONSHDLR_NAME "orbisack"
78#define CONSHDLR_DESC "symmetry breaking constraint handler for orbisacks"
79#define CONSHDLR_SEPAPRIORITY +40100 /**< priority of the constraint handler for separation */
80#define CONSHDLR_ENFOPRIORITY -1005200 /**< priority of the constraint handler for constraint enforcing */
81#define CONSHDLR_CHECKPRIORITY -1005200 /**< priority of the constraint handler for checking feasibility */
82#define CONSHDLR_SEPAFREQ 5 /**< frequency for separating cuts; zero means to separate only in the root node */
83#define CONSHDLR_PROPFREQ 5 /**< frequency for propagating domains; zero means only preprocessing propagation */
84#define CONSHDLR_EAGERFREQ -1 /**< frequency for using all instead of only the useful constraints in separation,
85 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
86#define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
87#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
88#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
89#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
90
91#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
92#define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_EXHAUSTIVE
93
94/* default parameters for separation routines: */
95#define DEFAULT_ORBISEPARATION FALSE /**< whether orbisack inequalities should be separated */
96#define DEFAULT_COVERSEPARATION TRUE /**< whether cover inequalities should be separated */
97
98/* default parameters for constraints */
99#define DEFAULT_COEFFBOUND 1000000.0 /**< maximum size of coefficients in orbisack inequalities */
100#define DEFAULT_PPORBISACK TRUE /**< whether we allow upgrading to packing/partitioning orbisacks */
101#define DEFAULT_FORCECONSCOPY FALSE /**< whether orbisack constraints should be forced to be copied to sub SCIPs */
102
103/* Constants to store fixings */
104#define FIXED0 1 /* When a variable is fixed to 0. */
105#define FIXED1 2 /* When a variable is fixed to 1. */
106#define UNFIXED 3 /* When a variable is neither fixed to 0 or to 1. */
107
108
109/*
110 * Data structures
111 */
112
113/** constraint handler data */
114struct SCIP_ConshdlrData
115{
116 SCIP_Bool coverseparation; /**< whether only cover inequalities should be separated */
117 SCIP_Bool orbiseparation; /**< whether orbisack as well as cover inequalities should be separated */
118 SCIP_Real coeffbound; /**< maximum size of coefficients in orbisack inequalities */
119 SCIP_Bool checkpporbisack; /**< whether we allow upgrading to packing/partitioning orbisacks */
120 int maxnrows; /**< maximal number of rows in an orbisack constraint */
121 SCIP_Bool forceconscopy; /**< whether orbisack constraints should be forced to be copied to sub SCIPs */
122};
123
124/** constraint data for orbisack constraints */
125struct SCIP_ConsData
126{
127 SCIP_VAR** vars1; /**< first column of variable matrix */
128 SCIP_VAR** vars2; /**< second column of variable matrix */
129 int nrows; /**< number of rows of variable matrix */
130 SCIP_Bool ismodelcons; /**< whether the orbisack is a model constraint */
131};
132
133
134/*
135 * Local methods
136 */
137
138/** frees orbisack constraint data */
139static
141 SCIP* scip, /**< SCIP data structure */
142 SCIP_CONSDATA** consdata /**< pointer to orbisack constraint data */
143 )
144{
145 int nrows;
146 int i;
147
148 assert( consdata != NULL );
149 assert( *consdata != NULL );
150
151 nrows = (*consdata)->nrows;
152
153 /* release variables in vars1 and vars2 array */
154 for (i = 0; i < nrows; ++i)
155 {
156 assert( (*consdata)->vars1[i] != NULL );
157 SCIP_CALL( SCIPreleaseVar(scip, &(*consdata)->vars1[i] ) );
158
159 assert( (*consdata)->vars2[i] != NULL );
160 SCIP_CALL( SCIPreleaseVar(scip, &(*consdata)->vars2[i] ) );
161 }
162
163 SCIPfreeBlockMemoryArrayNull(scip, &((*consdata)->vars2), nrows);
164 SCIPfreeBlockMemoryArrayNull(scip, &((*consdata)->vars1), nrows);
165
166 SCIPfreeBlockMemory(scip, consdata);
167
168 return SCIP_OKAY;
169}
170
171
172/** creates orbisack constraint data */
173static
175 SCIP* scip, /**< SCIP data structure */
176 SCIP_CONSDATA** consdata, /**< pointer to store constraint data */
177 SCIP_VAR*const* vars1, /**< first column of variable matrix */
178 SCIP_VAR*const* vars2, /**< second column of variable matrix */
179 int nrows, /**< number of rows in variable matrix */
180 SCIP_Bool ismodelcons /**< whether the orbisack is a model constraint */
181 )
182{
183 int i;
184
185 assert( consdata != NULL );
186
187 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
188
189 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars1, vars1, nrows) );
190 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars2, vars2, nrows) );
191
192#ifndef NDEBUG
193 {
194 for (i = 0; i < nrows; ++i)
195 {
196 assert( SCIPvarIsBinary(vars1[i]) );
197 assert( SCIPvarIsBinary(vars2[i]) );
198 }
199 }
200#endif
201
202 (*consdata)->nrows = nrows;
203 (*consdata)->ismodelcons = ismodelcons;
204
205 /* get transformed variables, if we are in the transformed problem */
206 if ( SCIPisTransformed(scip) )
207 {
208 /* Make sure that all variables cannot be multiaggregated (cannot be handled by cons_orbisack, since one cannot
209 * easily eliminate single variables from an orbisack constraint. */
210 for (i = 0; i < nrows; ++i)
211 {
212 SCIP_CALL( SCIPgetTransformedVar(scip, (*consdata)->vars1[i], &(*consdata)->vars1[i]) );
213 SCIP_CALL( SCIPmarkDoNotMultaggrVar(scip, (*consdata)->vars1[i]) );
214
215 SCIP_CALL( SCIPgetTransformedVar(scip, (*consdata)->vars2[i], &(*consdata)->vars2[i]) );
216 SCIP_CALL( SCIPmarkDoNotMultaggrVar(scip, (*consdata)->vars2[i]) );
217 }
218 }
219
220 /* capture vars in vars1 and vars2 array */
221 for (i = 0; i < nrows; ++i)
222 {
223 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars1[i] ) );
224 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars2[i] ) );
225 }
226
227 return SCIP_OKAY;
228}
229
230
231/** check wether an orbisack is even a packing/partitioning orbisack */
232static
234 SCIP* scip, /**< SCIP pointer */
235 SCIP_VAR*const* vars1, /**< first column of matrix of variables on which the symmetry acts */
236 SCIP_VAR*const* vars2, /**< variables of second column */
237 int nrows, /**< number of rows of orbisack */
238 SCIP_Bool* success, /**< memory address to store whether constraint can be upgraded */
239 SCIP_Bool* isparttype /**< memory address to store whether upgraded orbisack is partitioning orbisack */
240 )
241{
242 SCIP_VAR*** vars;
244 int i;
245
246 assert( scip != NULL );
247 assert( vars1 != NULL );
248 assert( vars2 != NULL );
249 assert( success != NULL );
250 assert( isparttype != NULL );
251
252 *success = FALSE;
253 *isparttype = FALSE;
254
255 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nrows) );
256 for (i = 0; i < nrows; ++i)
257 {
258 SCIP_CALL( SCIPallocBufferArray(scip, &vars[i], 2) );
259 vars[i][0] = vars1[i];
260 vars[i][1] = vars2[i];
261 }
262
263 SCIP_CALL( SCIPisPackingPartitioningOrbitope(scip, vars, nrows, 2, NULL, NULL, &type) );
264
265 if ( type == SCIP_ORBITOPETYPE_PACKING )
266 *success = TRUE;
267 else if ( type == SCIP_ORBITOPETYPE_PARTITIONING )
268 {
269 *success = TRUE;
270 *isparttype = TRUE;
271 }
272
273 for (i = nrows - 1; i >= 0; --i)
274 {
275 SCIPfreeBufferArray(scip, &vars[i]);
276 }
278
279 return SCIP_OKAY;
280}
281
282
283/** generate initial LP cut
284 *
285 * We generate the inequality of the orbisack on the elements of the first row, i.e.,
286 * the inequality \f$-x_{1,1} + x_{1,2} \leq 0\f$.
287 */
288static
290 SCIP* scip, /**< SCIP pointer */
291 SCIP_CONS* cons, /**< constraint */
292 SCIP_Bool* infeasible /**< pointer to store whether we detected infeasibility */
293 )
294{
295 SCIP_CONSDATA* consdata;
296 SCIP_VAR** vars1;
297 SCIP_VAR** vars2;
298 SCIP_VAR* tmpvars[2];
299 SCIP_ROW* row;
300
301 assert( scip != NULL );
302 assert( cons != NULL );
303 assert( infeasible != NULL );
304
305 *infeasible = FALSE;
306
307 consdata = SCIPconsGetData(cons);
308 assert( consdata != 0 );
309 assert( consdata->nrows > 0 );
310 assert( consdata->vars1 != NULL );
311 assert( consdata->vars2 != NULL );
312
313 vars1 = consdata->vars1;
314 vars2 = consdata->vars2;
315
316 tmpvars[0] = vars1[0];
317 tmpvars[1] = vars2[0];
318
319 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &row, cons, "orbisack0#0", -SCIPinfinity(scip), 0.0, FALSE, FALSE, TRUE) );
320 SCIP_CALL( SCIPaddVarToRow(scip, row, tmpvars[0], -1.0) );
321 SCIP_CALL( SCIPaddVarToRow(scip, row, tmpvars[1], 1.0) );
322
323 SCIP_CALL( SCIPaddRow(scip, row, FALSE, infeasible) );
324#ifdef SCIP_DEBUG
326#endif
327 SCIP_CALL( SCIPreleaseRow(scip, &row) );
328
329 return SCIP_OKAY;
330}
331
332
333/** add orbisack cover inequality */
334static
336 SCIP* scip, /**< SCIP pointer */
337 SCIP_CONS* cons, /**< constraint */
338 int nrows, /**< number of rows of orbisack */
339 SCIP_VAR*const* vars1, /**< first column of matrix of variables on which the symmetry acts */
340 SCIP_VAR*const* vars2, /**< variables of second column */
341 SCIP_Real* coeffs1, /**< coefficients of the variables of the first column of the inequality to be added */
342 SCIP_Real* coeffs2, /**< coefficients of the variables of the second column of the inequality to be added */
343 SCIP_Real rhs, /**< right-hand side of inequality to be added */
344 SCIP_Bool* infeasible /**< pointer to store whether we detected infeasibility */
345 )
346{
347 SCIP_ROW* row;
348 int i;
349
350 assert( scip != NULL );
351 assert( cons != NULL );
352 assert( vars1 != NULL );
353 assert( vars2 != NULL );
354 assert( coeffs1 != NULL );
355 assert( coeffs2 != NULL );
356 assert( infeasible != NULL );
357
358 *infeasible = FALSE;
359
360 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &row, cons, "orbisackcover", -SCIPinfinity(scip), rhs, FALSE, FALSE, TRUE) );
362 for (i = 0; i < nrows; ++i)
363 {
364 SCIP_CALL( SCIPaddVarToRow(scip, row, vars1[i], coeffs1[i]) );
365 SCIP_CALL( SCIPaddVarToRow(scip, row, vars2[i], coeffs2[i]) );
366 }
368
369 SCIP_CALL( SCIPaddRow(scip, row, FALSE, infeasible) );
370#ifdef SCIP_DEBUG
372#endif
373 SCIP_CALL( SCIPreleaseRow(scip, &row) );
374
375 return SCIP_OKAY;
376}
377
378
379/** Separate lifted orbisack cover inequalities
380 *
381 * We currently do NOT enter cuts into the pool.
382 *
383 * We iterate over the nrows-many cover inequalities which are potentially
384 * maximal w.r.t. their violation.
385 */
386static
388 SCIP* scip, /**< SCIP pointer */
389 SCIP_CONS* cons, /**< constraint */
390 int nrows, /**< number of rows of orbisack */
391 SCIP_VAR*const* vars1, /**< first column of matrix of variables on which the symmetry acts */
392 SCIP_VAR*const* vars2, /**< variables of second column */
393 SCIP_Real* vals1, /**< LP-solution for those variables in first column */
394 SCIP_Real* vals2, /**< LP-solution for those variables in second column */
395 int* ngen, /**< number of separated covers */
396 SCIP_Bool* infeasible /**< pointer to store whether we detected infeasibility */
397 )
398{
399 SCIP_Real rhs = 0.0;
400 SCIP_Real lhs = 0.0;
401 SCIP_Real* coeff1;
402 SCIP_Real* coeff2;
403 int i;
404
405 assert( scip != NULL );
406 assert( cons != NULL );
407 assert( nrows > 0 );
408 assert( vars1 != NULL );
409 assert( vars2 != NULL );
410 assert( infeasible != NULL );
411 assert( ngen != NULL );
412
413 *infeasible = FALSE;
414 *ngen = 0;
415
416 /* allocate memory for inequality coefficients */
417 SCIP_CALL( SCIPallocBufferArray(scip, &coeff1, nrows) );
418 SCIP_CALL( SCIPallocBufferArray(scip, &coeff2, nrows) );
419
420 /* initialize coefficient matrix */
421 for (i = 0; i < nrows; ++i)
422 {
423 coeff1[i] = 0.0;
424 coeff2[i] = 0.0;
425 }
426
427 /* detect violated covers */
428 for (i = 0; i < nrows; ++i)
429 {
430 /* cover inequality is violated */
431 if ( SCIPisEfficacious(scip, -vals1[i] + vals2[i] + lhs - rhs) )
432 {
433 /* set coefficients for inequality */
434 coeff1[i] = -1.0;
435 coeff2[i] = 1.0;
436
437 SCIP_CALL( addOrbisackCover(scip, cons, nrows, vars1, vars2, coeff1, coeff2, rhs, infeasible) );
438 ++(*ngen);
439 if ( *infeasible )
440 break;
441
442 /* reset coefficients for next inequality */
443 coeff1[i] = 0.0;
444 coeff2[i] = 0.0;
445 }
446
447 /* add argmax( 1 - vals[i][0], vals[i][1] ) as coefficient and ensure that both vars1[0] and vars2[0] are
448 * contained in the LIFTED cover inequality */
449 if ( SCIPisEfficacious(scip, 1.0 - vals1[i] - vals2[i]) )
450 {
451 coeff1[i] = -1.0;
452 lhs = lhs - vals1[i];
453
454 /* lifting */
455 if ( i == 0 )
456 {
457 coeff2[0] = 1.0;
458 lhs += vals2[i];
459 }
460 }
461 else
462 {
463 coeff2[i] = 1.0;
464 rhs += 1.0;
465 lhs = lhs + vals2[i];
466
467 /* lifting */
468 if ( i == 0 )
469 {
470 coeff1[0] = -1.0;
471 lhs -= vals1[i];
472 rhs -= 1.0;
473 }
474 }
475 }
476
477 /* free coefficient matrix */
478 SCIPfreeBufferArray(scip, &coeff2);
479 SCIPfreeBufferArray(scip, &coeff1);
480
481 return SCIP_OKAY;
482}
483
484
485/** add orbisack inequality */
486static
488 SCIP* scip, /**< SCIP pointer */
489 SCIP_CONS* cons, /**< constraint */
490 int nrows, /**< number of rows of orbisack */
491 SCIP_VAR*const* vars1, /**< first column of matrix of variables on which the symmetry acts */
492 SCIP_VAR*const* vars2, /**< variables of second column */
493 SCIP_Real* coeffs1, /**< first column of coefficient matrix of inequality to be added */
494 SCIP_Real* coeffs2, /**< second column of coefficient matrix of inequality to be added */
495 SCIP_Real rhs, /**< right-hand side of inequality to be added */
496 SCIP_Bool* infeasible /**< pointer to store whether we detected infeasibility */
497 )
498{
499 SCIP_ROW* row;
500 int i;
501
502 assert( scip != NULL );
503 assert( cons != NULL );
504 assert( vars1 != NULL );
505 assert( vars2 != NULL );
506 assert( coeffs1 != NULL );
507 assert( coeffs2 != NULL );
508 assert( infeasible != NULL );
509
510 *infeasible = FALSE;
511
512 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &row, cons, "orbisack", -SCIPinfinity(scip), rhs, FALSE, FALSE, TRUE) );
514
515 for (i = 0; i < nrows; ++i)
516 {
517 SCIP_CALL( SCIPaddVarToRow(scip, row, vars1[i], coeffs1[i]) );
518 SCIP_CALL( SCIPaddVarToRow(scip, row, vars2[i], coeffs2[i]) );
519 }
521
522 SCIP_CALL( SCIPaddRow(scip, row, FALSE, infeasible) );
523#ifdef SCIP_DEBUG
525#endif
526 SCIP_CALL( SCIPreleaseRow(scip, &row) );
527
528 return SCIP_OKAY;
529}
530
531
532/** separate orbisack inequalities
533 *
534 * We currently do NOT enter cuts into the pool.
535 *
536 * We stop if we checked for each possible basement row, whether a cut could be added. If the coefficients grow too
537 * large, we start separating cover inequalities.
538 *
539 * We implement the separation algorithm for orbisacks described in@n
540 * A. Loos. Describing Orbitopes by Linear Inequalities and Projection Based Tools.
541 * PhD thesis, Otto-von-Guericke-Universitaet Magdeburg, 2010.
542 */
543static
545 SCIP* scip, /**< SCIP pointer */
546 SCIP_CONS* cons, /**< constraint */
547 int nrows, /**< number of rows of orbisack */
548 SCIP_VAR*const* vars1, /**< first column of matrix of variables on which the symmetry acts */
549 SCIP_VAR*const* vars2, /**< variables of second column */
550 SCIP_Real* vals1, /**< LP-solution for those variables in first column */
551 SCIP_Real* vals2, /**< LP-solution for those variables in second column */
552 SCIP_Bool coverseparation, /**< whether we separate cover inequalities */
553 SCIP_Real coeffbound, /**< maximum size of coefficients in orbisack inequalities */
554 int* ngen, /**< pointer to store the number of generated cuts */
555 SCIP_Bool* infeasible /**< pointer to store whether we detected infeasibility */
556 )
557{
558 SCIP_Real* coeff1;
559 SCIP_Real* coeff2;
560 SCIP_Real rhs;
561 SCIP_Real lhs;
562 SCIP_Real valueA;
563 SCIP_Real valueB;
564 SCIP_Real valueC;
565 int basement;
566 int i;
567
568 assert( scip != NULL );
569 assert( cons != NULL );
570 assert( nrows > 0 );
571 assert( vars1 != NULL );
572 assert( vars2 != NULL );
573 assert( coeffbound >= 0.0 );
574 assert( ngen != NULL );
575 assert( infeasible != NULL );
576
577 *infeasible = FALSE;
578 *ngen = 0;
579
580 /* if there is only one row, all cuts are added by initLP */
581 if ( nrows < 2 )
582 return SCIP_OKAY;
583
584 /* allocate memory for inequality coefficients */
585 SCIP_CALL( SCIPallocBufferArray(scip, &coeff1, nrows) );
586 SCIP_CALL( SCIPallocBufferArray(scip, &coeff2, nrows) );
587
588 /* initialize coefficient matrix row 0 */
589 coeff1[0] = -1.0;
590 coeff2[0] = 1.0;
591 for (i = 2; i < nrows; ++i)
592 {
593 coeff1[i] = 0.0;
594 coeff2[i] = 0.0;
595 }
596
597 /* initialize right-hand side and left-hand side (lhs for row 0) */
598 rhs = 0.0;
599 lhs = - vals1[0] + vals2[0];
600
601 /* basement row of orbisack */
602 basement = 1;
603
604 /* update value of left-hand side and coefficients for basement row = 1 */
605 lhs += - vals1[1] + vals2[1];
606 coeff1[1] = -1.0;
607 coeff2[1] = 1.0;
608
609 /* check whether cut for basement row = 1 is violated */
610 if ( SCIPisEfficacious(scip, lhs - rhs) )
611 {
612 SCIP_CALL( addOrbisackInequality(scip, cons, nrows, vars1, vars2, coeff1, coeff2, rhs, infeasible) );
613 ++(*ngen);
614 }
615
616 /* check whether there exists a cut with basement rows > 1 that is violated */
617 while ( basement < nrows - 1 && ! *infeasible )
618 {
619 valueA = lhs + vals1[basement] - vals1[basement + 1] + vals2[basement + 1] - rhs - 1.0; /*lint !e679, !e834*/
620 valueB = lhs - vals2[basement] - vals1[basement + 1] + vals2[basement + 1] - rhs; /*lint !e679, !e834*/
621 valueC = 2.0 * lhs + vals1[basement] - vals2[basement] - vals1[basement + 1] + vals2[basement + 1] - 2.0 * rhs; /*lint !e679, !e834*/
622
623 /* update inequality */
624 if ( valueA >= valueB && valueA >= valueC )
625 {
626 ++rhs;
627 coeff1[basement] = 0.0;
628 lhs += vals1[basement++];
629 coeff1[basement] = -1.0;
630 coeff2[basement] = 1.0;
631 lhs += - vals1[basement] + vals2[basement];
632 }
633 else if ( valueB >= valueA && valueB >= valueC )
634 {
635 coeff2[basement] = 0.0;
636 lhs -= vals2[basement++];
637 coeff1[basement] = -1.0;
638 coeff2[basement] = 1.0;
639 lhs += - vals1[basement] + vals2[basement];
640 }
641 else
642 {
643 rhs *= 2.0;
644 lhs = 0.0;
645 for (i = 0; i < basement; ++i)
646 {
647 coeff1[i] = 2.0 * coeff1[i];
648 coeff2[i] = 2.0 * coeff2[i];
649 lhs += coeff1[i] * vals1[i] + coeff2[i] * vals2[i];
650 }
651 coeff1[basement] = -1.0;
652 coeff2[basement] = 1.0;
653 lhs -= vals1[basement];
654 lhs += vals2[basement++];
655 coeff1[basement] = -1.0;
656 coeff2[basement] = 1.0;
657 lhs -= vals1[basement];
658 lhs += vals2[basement];
659 }
660
661 /* to avoid numerical troubles, we bound the size of coefficients and rhs */
662 if ( rhs > coeffbound || -coeff1[0] > coeffbound || coeff2[0] > coeffbound )
663 {
664 /* avoid separating cover inequalities twice */
665 if ( ! coverseparation )
666 {
667 int ncuts;
668 SCIP_CALL( separateOrbisackCovers(scip, cons, nrows, vars1, vars2, vals1, vals2, &ncuts, infeasible) );
669 *ngen += ncuts;
670 }
671 break;
672 }
673
674 /* if current inequality is violated */
675 if ( SCIPisEfficacious(scip, lhs - rhs) )
676 {
677 SCIP_CALL( addOrbisackInequality(scip, cons, nrows, vars1, vars2, coeff1, coeff2, rhs, infeasible) );
678 ++(*ngen);
679 }
680 }
681
682 /* free allocated memory */
683 SCIPfreeBufferArray(scip, &coeff2);
684 SCIPfreeBufferArray(scip, &coeff1);
685
686 return SCIP_OKAY;
687}
688
689
690/** Determines if a vector with additional fixings could exist that is lexicographically larger than another vector.
691 *
692 * Given two vectors of variables with local lower and upper bounds, and a set of additional (virtual) fixings.
693 * Assuming that the entries of both vectors are equal until entry "start", this function determines if there exists
694 * a vector where the left vector is lexicographically larger or equal to the right vector.
695 * If a vector exsits, infeasible is set to FALSE, otherwise TRUE.
696 */
697static
699 SCIP* scip, /**< SCIP pointer */
700 SCIP_VAR** vars1, /**< array of variables in first vector */
701 SCIP_VAR** vars2, /**< array of variables in second vector */
702 int nrows, /**< number of rows */
703 int start, /**< at which row to start (assuming previous rows are equal) */
704 SCIP_Bool* infeasible, /**< pointer to store whether infeasibility is detected in these fixings */
705 int* infeasiblerow /**< pointer to store at which row a (0, 1) pattern is found */
706 )
707{
708 SCIP_VAR* var1;
709 SCIP_VAR* var2;
710 int var1fix;
711 int var2fix;
712 int i;
713
714 assert( scip != NULL );
715 assert( vars1 != NULL );
716 assert( vars2 != NULL );
717 assert( infeasible != NULL );
718 assert( start >= 0 );
719
720 *infeasible = FALSE;
721
722 for (i = start; i < nrows; ++i)
723 {
724 /* get variables of first and second vector */
725 var1 = vars1[i];
726 var2 = vars2[i];
727
728 assert( var1 != NULL );
729 assert( var2 != NULL );
730
731 /* Get virtual fixing of variable in first vector, for var1 */
732 if ( SCIPvarGetUbLocal(var1) < 0.5 )
733 {
734 var1fix = FIXED0;
735 assert( SCIPvarGetLbLocal(var1) <= 0.5 );
736 }
737 else if ( SCIPvarGetLbLocal(var1) > 0.5 )
738 var1fix = FIXED1;
739 else
740 var1fix = UNFIXED;
741
742 /* Get virtual fixing of variable in second vector, for var2 */
743 if ( SCIPvarGetUbLocal(var2) < 0.5 )
744 {
745 var2fix = FIXED0;
746 assert( SCIPvarGetLbLocal(var2) <= 0.5 );
747 }
748 else if ( SCIPvarGetLbLocal(var2) > 0.5 )
749 var2fix = FIXED1;
750 else
751 var2fix = UNFIXED;
752
753 /* Encounter one of (_, _), (_, 0), (1, _), (1, 0). In all cases (1, 0) can be constructed. Thus feasible. */
754 if ( var1fix != FIXED0 && var2fix != FIXED1 )
755 break;
756 /* Encounter (0, 1). Infeasible. */
757 else if ( var1fix == FIXED0 && var2fix == FIXED1 )
758 {
759 *infeasible = TRUE;
760 *infeasiblerow = i;
761 break;
762 }
763 /* Remaining cases are (0, _), (_, 1), (0, 0) and (1, 1). In all cases: continue. */
764 }
765
766 return SCIP_OKAY;
767}
768
769
770/** propagation */
771static
773 SCIP* scip, /**< SCIP pointer */
774 SCIP_CONS* cons, /**< constraint to be propagated */
775 SCIP_Bool* infeasible, /**< pointer to store whether it was detected that the node is infeasible */
776 SCIP_Bool* found, /**< pointer to store whether a new propagation could be found */
777 int* ngen /**< pointer to store the number of generated bound strengthenings */
778 )
779{
780 SCIP_CONSDATA* consdata;
781 SCIP_VAR** vars1;
782 SCIP_VAR** vars2;
783 SCIP_VAR* var1;
784 SCIP_VAR* var2;
785 int var1fix;
786 int var2fix;
787 SCIP_Bool tightened;
788 SCIP_Bool peekinfeasible;
789 int peekinfeasiblerow;
790 int nrows;
791 int i;
792
793 assert( scip != NULL );
794 assert( cons != NULL );
795 assert( infeasible != NULL );
796 assert( ngen != NULL );
797 assert( found != NULL );
798
799 SCIPdebugMsg(scip, "Propagating variables of constraint <%s>.\n", SCIPconsGetName(cons));
800
801 *ngen = 0;
802 *infeasible = FALSE;
803 *found = FALSE;
804
805 /* get data of constraint */
806 consdata = SCIPconsGetData(cons);
807 assert( consdata != NULL );
808 assert( consdata->vars1 != NULL );
809 assert( consdata->vars2 != NULL );
810 assert( consdata->nrows > 0 );
811
812 nrows = consdata->nrows;
813 vars1 = consdata->vars1;
814 vars2 = consdata->vars2;
815
816 /* loop through all variables */
817 for (i = 0; i < nrows; ++i)
818 {
819 /* get variables of first and second column */
820 var1 = vars1[i];
821 var2 = vars2[i];
822 assert( var1 != NULL );
823 assert( var2 != NULL );
824
825 /* Get the fixing status of the left column variable var1 */
826 if ( SCIPvarGetUbLocal(var1) < 0.5 )
827 {
828 var1fix = FIXED0;
829 assert( SCIPvarGetLbLocal(var1) <= 0.5 );
830 }
831 else if ( SCIPvarGetLbLocal(var1) > 0.5 )
832 var1fix = FIXED1;
833 else
834 var1fix = UNFIXED;
835
836 /* Get the fixing status of the right column variable var2 */
837 if ( SCIPvarGetUbLocal(var2) < 0.5 )
838 {
839 var2fix = FIXED0;
840 assert( SCIPvarGetLbLocal(var2) <= 0.5 );
841 }
842 else if ( SCIPvarGetLbLocal(var2) > 0.5 )
843 var2fix = FIXED1;
844 else
845 var2fix = UNFIXED;
846
847 /* Encounter one of (1, 0). All above rows are constant. This is a feasible situation. Stop. */
848 if ( var1fix == FIXED1 && var2fix == FIXED0 )
849 {
850 assert( SCIPvarGetLbLocal(var1) > 0.5 );
851 assert( SCIPvarGetUbLocal(var2) < 0.5 );
852
853 SCIPdebugMsg(scip, "Row %d is (1, 0)\n", i);
854 break;
855 }
856 /* Encounter one of (_, _), (_, 0), (1, _). Check if a constant row is possible, otherwise fix to (1, 0). */
857 if ( var1fix != FIXED0 && var2fix != FIXED1 )
858 {
859 assert( SCIPvarGetUbLocal(var1) > 0.5 );
860 assert( SCIPvarGetLbLocal(var2) < 0.5 );
861
862 SCIPdebugMsg(scip, "Row %d is (_, _), (_, 0) or (1, _).\n", i);
863
864 SCIP_CALL( checkFeasible(scip, vars1, vars2, nrows, i + 1, &peekinfeasible, &peekinfeasiblerow) );
865
866 if ( peekinfeasible )
867 {
868 /* If row i is constant, then we end up in an infeasible solution. Hence, row i must be (1, 0). */
869 SCIPdebugMsg(scip, "Making row %d constant is infeasible. Fix to (1, 0).\n", i);
870
871 assert( peekinfeasiblerow > i );
872 assert( peekinfeasiblerow < nrows );
873
874 if ( var1fix != FIXED1 )
875 {
876 /* Fix variable in first column to 1 */
877 SCIP_CALL( SCIPinferVarLbCons(scip, var1, 1.0, cons, i + nrows * peekinfeasiblerow, FALSE, infeasible,
878 &tightened) ); /*lint !e713*/
879 assert( ! *infeasible );
880
881 *found = *found || tightened;
882 if ( tightened )
883 ++(*ngen);
884 }
885
886 if ( var2fix != FIXED0 )
887 {
888 /* Fix variable in second column to 0 */
889 SCIP_CALL( SCIPinferVarUbCons(scip, var2, 0.0, cons, i + nrows * peekinfeasiblerow, FALSE, infeasible,
890 &tightened) ); /*lint !e713*/
891 assert( ! *infeasible );
892
893 *found = *found || tightened;
894 if ( tightened )
895 ++(*ngen);
896 }
897 }
898
899 /* In all cases, we could make this row (1, 0), so it is feasible. Stop. */
900 break;
901 }
902 /* Encounter (0, 1): if variable in first column is fixed to 0 and variable in second column is fixed to 1 */
903 else if ( var1fix == FIXED0 && var2fix == FIXED1 )
904 {
905 assert( SCIPvarGetUbLocal(var1) < 0.5 );
906 assert( SCIPvarGetLbLocal(var2) > 0.5 );
907
908 SCIPdebugMsg(scip, "Row %d is (0, 1). Infeasible!\n", i);
909
910 /* Mark solution as infeasible. */
911 *infeasible = TRUE;
912
913 /* Perform conflict analysis */
915 {
917
918 /* Mark all variables from row i and above as part of the conflict */
919 while (i >= 0)
920 {
922 SCIP_CALL( SCIPaddConflictBinvar(scip, vars2[i--]) ); /*lint !e850*/
923 }
924
926 }
927
928 break;
929 }
930 /* Encounter (0, _): Fix second part to 0 */
931 else if ( var1fix == FIXED0 && var2fix != FIXED0 )
932 {
933 assert( SCIPvarGetUbLocal(var1) < 0.5 );
934 assert( SCIPvarGetLbLocal(var2) < 0.5 );
935 assert( SCIPvarGetUbLocal(var2) > 0.5 );
936
937 SCIPdebugMsg(scip, "Row %d is (0, _). Fixing to (0, 0).\n", i);
938
939 SCIP_CALL( SCIPinferVarUbCons(scip, var2, 0.0, cons, i, FALSE, infeasible, &tightened) ); /*lint !e713*/
940 assert( ! *infeasible );
941
942 *found = *found || tightened;
943 if ( tightened )
944 ++(*ngen);
945 }
946 /* Encounter (_, 1): fix first part to 1 */
947 else if ( var1fix != FIXED1 && var2fix == FIXED1 )
948 {
949 assert( SCIPvarGetLbLocal(var1) < 0.5 );
950 assert( SCIPvarGetUbLocal(var1) > 0.5 );
951 assert( SCIPvarGetLbLocal(var2) > 0.5 );
952
953 SCIPdebugMsg(scip, "Row %d is (_, 1). Fixing to (1, 1).\n", i);
954
955 SCIP_CALL( SCIPinferVarLbCons(scip, var1, 1.0, cons, i, FALSE, infeasible, &tightened) ); /*lint !e713*/
956 assert( ! *infeasible );
957
958 *found = *found || tightened;
959 if ( tightened )
960 ++(*ngen);
961 }
962 /* Remaining cases are (0, 0) and (1, 1). In these cases we can continue! */
963 }
964
965 SCIPdebugMsg(scip, "No further fixings possible. Stopping at row %d\n", i);
966 return SCIP_OKAY;
967}
968
969
970/** separate orbisack and cover inequalities */
971static
973 SCIP* scip, /**< pointer to scip */
974 SCIP_RESULT* result, /**< pointer to store the result of separation */
975 SCIP_CONS* cons, /**< constraint */
976 int nrows, /**< number of rows of orbisack */
977 SCIP_VAR*const* vars1, /**< first column of matrix of variables on which the symmetry acts */
978 SCIP_VAR*const* vars2, /**< variables of second column */
979 SCIP_Real* vals1, /**< LP-solution for those variables in first column */
980 SCIP_Real* vals2 /**< LP-solution for those variables in second column */
981 )
982{
983 SCIP_CONSHDLRDATA* conshdlrdata;
984 SCIP_Bool infeasible = FALSE;
985 int ngen1 = 0;
986 int ngen2 = 0;
987
988 assert( scip != NULL );
989 assert( result != NULL );
990 assert( cons != NULL );
991 assert( vars1 != NULL );
992 assert( vars2 != NULL );
993 assert( vals1 != NULL );
994 assert( vals2 != NULL );
995
996 conshdlrdata = SCIPconshdlrGetData(SCIPconsGetHdlr(cons));
997 assert( conshdlrdata != NULL );
998
999 if ( conshdlrdata->orbiseparation )
1000 {
1001 SCIP_CALL( separateOrbisack(scip, cons, nrows, vars1, vars2, vals1, vals2, FALSE, conshdlrdata->coeffbound, &ngen1, &infeasible) );
1002 }
1003
1004 if ( ! infeasible && conshdlrdata->coverseparation )
1005 {
1006 SCIP_CALL( separateOrbisackCovers(scip, cons, nrows, vars1, vars2, vals1, vals2, &ngen2, &infeasible) );
1007 }
1008
1009 if ( infeasible )
1010 {
1011 *result = SCIP_CUTOFF;
1012 return SCIP_OKAY;
1013 }
1014
1015 if ( ngen1 + ngen2 > 0 )
1016 *result = SCIP_SEPARATED;
1017
1018 return SCIP_OKAY;
1019}
1020
1021
1022/** replace aggregated variables by active variables */
1023static
1025 SCIP* scip, /**< SCIP data structure */
1026 SCIP_CONS* cons /**< constraint to be processed */
1027 )
1028{
1029 SCIP_CONSDATA* consdata;
1030 SCIP_VAR** vars1;
1031 SCIP_VAR** vars2;
1032 int i;
1033 int nrows;
1034
1035 assert( scip != NULL );
1036 assert( cons != NULL );
1037
1038 /* get data of constraint */
1039 consdata = SCIPconsGetData(cons);
1040 assert( consdata != NULL );
1041 assert( consdata->vars1 != NULL );
1042 assert( consdata->vars2 != NULL );
1043 assert( consdata->nrows > 0 );
1044
1045 nrows = consdata->nrows;
1046 vars1 = consdata->vars1;
1047 vars2 = consdata->vars2;
1048
1049 /* loop through all variables */
1050 for (i = 0; i < nrows; ++i)
1051 {
1052 SCIP_VAR* var;
1053 SCIP_Bool negated;
1054
1055 /* treat first column */
1056 assert( SCIPvarGetStatus(vars1[i]) != SCIP_VARSTATUS_MULTAGGR ); /* variables are marked as not to be multi-aggregated */
1057
1058 SCIP_CALL( SCIPgetBinvarRepresentative(scip, vars1[i], &var, &negated) );
1059 SCIP_UNUSED( negated );
1061 if ( var != vars1[i] )
1062 {
1063 SCIP_CALL( SCIPreleaseVar(scip, &vars1[i]) );
1064 vars1[i] = var;
1065 SCIP_CALL( SCIPcaptureVar(scip, var) );
1066 }
1067
1068 /* treat second column */
1069 assert( SCIPvarGetStatus(vars2[i]) != SCIP_VARSTATUS_MULTAGGR ); /* variables are marked as not to be multi-aggregated */
1070
1071 SCIP_CALL( SCIPgetBinvarRepresentative(scip, vars2[i], &var, &negated) );
1072 SCIP_UNUSED( negated );
1074 if ( var != vars2[i] )
1075 {
1076 SCIP_CALL( SCIPreleaseVar(scip, &vars2[i]) );
1077 vars2[i] = var;
1078 SCIP_CALL( SCIPcaptureVar(scip, var) );
1079 }
1080 }
1081
1082 return SCIP_OKAY;
1083}
1084
1085
1086/*--------------------------------------------------------------------------------------------
1087 *--------------------------------- SCIP functions -------------------------------------------
1088 *--------------------------------------------------------------------------------------------*/
1089
1090/** copy method for constraint handler plugins (called when SCIP copies plugins) */
1091static
1092SCIP_DECL_CONSHDLRCOPY(conshdlrCopyOrbisack)
1093{ /*lint --e{715}*/
1094 assert(scip != NULL);
1095 assert(conshdlr != NULL);
1096 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
1097
1098 /* call inclusion method of constraint handler */
1100
1101 *valid = TRUE;
1102
1103 return SCIP_OKAY;
1104}
1105
1106/** frees specific constraint data */
1107static
1108SCIP_DECL_CONSDELETE(consDeleteOrbisack)
1109{ /*lint --e{715}*/
1110 assert( scip != 0 );
1111 assert( conshdlr != 0 );
1112 assert( consdata != 0 );
1113 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1114
1115 SCIP_CALL( consdataFree(scip, consdata) );
1116
1117 return SCIP_OKAY;
1118}
1119
1120
1121/** frees constraint handler */
1122static
1123SCIP_DECL_CONSFREE(consFreeOrbisack)
1124{ /*lint --e{715}*/
1125 SCIP_CONSHDLRDATA* conshdlrdata;
1126
1127 assert( scip != 0 );
1128 assert( conshdlr != 0 );
1129 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1130
1131 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1132 assert( conshdlrdata != NULL );
1133
1134 SCIPfreeBlockMemory(scip, &conshdlrdata);
1135
1136 return SCIP_OKAY;
1137}
1138
1139
1140/** transforms constraint data into data belonging to the transformed problem */
1141static
1142SCIP_DECL_CONSTRANS(consTransOrbisack)
1143{
1144 SCIP_CONSDATA* sourcedata;
1145 SCIP_CONSDATA* consdata = NULL;
1146
1147 assert( scip != NULL );
1148 assert( conshdlr != NULL );
1149 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1150 assert( sourcecons != NULL );
1151 assert( targetcons != NULL );
1152
1153 SCIPdebugMsg(scip, "Transforming constraint.\n");
1154
1155 /* get data of original constraint */
1156 sourcedata = SCIPconsGetData(sourcecons);
1157
1158 /* create constraint data */
1159 SCIP_CALL( consdataCreate(scip, &consdata, sourcedata->vars1, sourcedata->vars2,
1160 sourcedata->nrows, sourcedata->ismodelcons) );
1161
1162 /* create transformed constraint */
1163 SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, consdata,
1164 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons),
1165 SCIPconsIsEnforced(sourcecons), SCIPconsIsChecked(sourcecons),
1166 SCIPconsIsPropagated(sourcecons), SCIPconsIsLocal(sourcecons),
1167 SCIPconsIsModifiable(sourcecons), SCIPconsIsDynamic(sourcecons),
1168 SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
1169
1170 return SCIP_OKAY;
1171}
1172
1173
1174/** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
1175static
1176SCIP_DECL_CONSINITLP(consInitlpOrbisack)
1177{
1178 int c;
1179
1180 assert( infeasible != NULL );
1181 *infeasible = FALSE;
1182
1183 assert( scip != 0 );
1184 assert( conshdlr != 0 );
1185 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1186
1187 /* loop through constraints */
1188 for (c = 0; c < nconss; ++c)
1189 {
1190 assert( conss[c] != 0 );
1191
1192 SCIPdebugMsg(scip, "Generating initial orbisack cut for constraint <%s> ...\n", SCIPconsGetName(conss[c]));
1193
1194 SCIP_CALL( initLP(scip, conss[c], infeasible) );
1195 if ( *infeasible )
1196 break;
1197
1198 SCIPdebugMsg(scip, "Generated initial orbisack cut.\n");
1199 }
1200
1201 return SCIP_OKAY;
1202}
1203
1204
1205/** solving process initialization method of constraint handler (called when branch and bound process is about to begin) */
1206static
1207SCIP_DECL_CONSINITSOL(consInitsolOrbisack)
1208{
1209 SCIP_CONSHDLRDATA* conshdlrdata;
1210 int c;
1211
1212 assert( scip != NULL );
1213 assert( conshdlr != NULL );
1214 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1215
1216 /* determine maximum number of rows in an orbisack constraint */
1217 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1218 assert( conshdlrdata != NULL );
1219
1220 conshdlrdata->maxnrows = 0;
1221
1222 /* loop through constraints */
1223 for (c = 0; c < nconss; ++c)
1224 {
1225 SCIP_CONSDATA* consdata;
1226
1227 assert( conss[c] != NULL );
1228
1229 consdata = SCIPconsGetData(conss[c]);
1230 assert( consdata != NULL );
1231
1232 /* update conshdlrdata if necessary */
1233 if ( consdata->nrows > conshdlrdata->maxnrows )
1234 conshdlrdata->maxnrows = consdata->nrows;
1235 }
1236
1237 return SCIP_OKAY;
1238}
1239
1240
1241/** separation method of constraint handler for LP solution */
1242static
1243SCIP_DECL_CONSSEPALP(consSepalpOrbisack)
1244{ /*lint --e{715}*/
1245 SCIP_CONSDATA* consdata;
1246 SCIP_Real* vals1;
1247 SCIP_Real* vals2;
1248 int c;
1249
1250 assert( scip != NULL );
1251 assert( conshdlr != NULL );
1252 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1253 assert( result != NULL );
1254
1255 SCIPdebugMsg(scip, "Separation method for orbisack constraints.\n");
1256
1257 *result = SCIP_DIDNOTRUN;
1258
1259 /* if solution is not integer */
1260 if ( SCIPgetNLPBranchCands(scip) > 0 )
1261 {
1262 SCIP_CONSHDLRDATA* conshdlrdata;
1263 int nvals;
1264
1265 *result = SCIP_DIDNOTFIND;
1266
1267 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1268 assert( conshdlrdata != NULL );
1269
1270 nvals = conshdlrdata->maxnrows;
1271 assert( nvals > 0 );
1272
1273 SCIP_CALL( SCIPallocBufferArray(scip, &vals1, nvals) );
1274 SCIP_CALL( SCIPallocBufferArray(scip, &vals2, nvals) );
1275
1276 /* loop through constraints */
1277 for (c = 0; c < nconss; ++c)
1278 {
1279 /* get data of constraint */
1280 assert( conss[c] != NULL );
1281 consdata = SCIPconsGetData(conss[c]);
1282
1283 /* get solution */
1284 SCIP_CALL( SCIPgetSolVals(scip, NULL, consdata->nrows, consdata->vars1, vals1) );
1285 SCIP_CALL( SCIPgetSolVals(scip, NULL, consdata->nrows, consdata->vars2, vals2) );
1286
1287 SCIPdebugMsg(scip, "Separating orbisack constraint <%s> ...\n", SCIPconsGetName(conss[c]));
1288
1289 SCIP_CALL( separateInequalities(scip, result, conss[c], consdata->nrows, consdata->vars1, consdata->vars2, vals1, vals2) );
1290
1291 if ( *result == SCIP_CUTOFF )
1292 break;
1293 }
1294
1295 SCIPfreeBufferArray(scip, &vals2);
1296 SCIPfreeBufferArray(scip, &vals1);
1297 }
1298
1299 return SCIP_OKAY;
1300}
1301
1302
1303/** separation method of constraint handler for arbitrary primal solution */
1304static
1305SCIP_DECL_CONSSEPASOL(consSepasolOrbisack)
1306{ /*lint --e{715}*/
1307 SCIP_CONSDATA* consdata;
1308 SCIP_Real* vals1;
1309 SCIP_Real* vals2;
1310 int c;
1311
1312 assert( scip != NULL );
1313 assert( conshdlr != NULL );
1314 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1315 assert( result != NULL );
1316
1317 SCIPdebugMsg(scip, "Separation method for orbisack constraints\n");
1318
1319 *result = SCIP_DIDNOTFIND;
1320
1321 if ( nconss > 0 )
1322 {
1323 SCIP_CONSHDLRDATA* conshdlrdata;
1324 int nvals;
1325
1326 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1327 assert( conshdlrdata != NULL );
1328
1329 nvals = conshdlrdata->maxnrows;
1330 assert( nvals > 0 );
1331
1332 SCIP_CALL( SCIPallocBufferArray(scip, &vals1, nvals) );
1333 SCIP_CALL( SCIPallocBufferArray(scip, &vals2, nvals) );
1334
1335 /* loop through constraints */
1336 for (c = 0; c < nconss; ++c)
1337 {
1338 /* get data of constraint */
1339 assert( conss[c] != NULL );
1340 consdata = SCIPconsGetData(conss[c]);
1341
1342 /* get solution */
1343 assert( consdata->nrows <= nvals );
1344 SCIP_CALL( SCIPgetSolVals(scip, sol, consdata->nrows, consdata->vars1, vals1) );
1345 SCIP_CALL( SCIPgetSolVals(scip, sol, consdata->nrows, consdata->vars2, vals2) );
1346
1347 SCIPdebugMsg(scip, "Separating orbisack constraint <%s> ...\n", SCIPconsGetName(conss[c]));
1348
1349 SCIP_CALL( separateInequalities(scip, result, conss[c], consdata->nrows, consdata->vars1, consdata->vars2, vals1, vals2) );
1350 if ( *result == SCIP_CUTOFF )
1351 break;
1352 }
1353
1354 SCIPfreeBufferArray(scip, &vals2);
1355 SCIPfreeBufferArray(scip, &vals1);
1356 }
1357
1358 return SCIP_OKAY;
1359}
1360
1361
1362/** constraint enforcing method of constraint handler for LP solutions
1363 *
1364 * @pre It is assumed that the solution is integral (this can be ensured by appropriate priorities).
1365 */
1366static
1367SCIP_DECL_CONSENFOLP(consEnfolpOrbisack)
1368{ /*lint --e{715}*/
1369 SCIP_CONSDATA* consdata;
1370 SCIP_Bool infeasible = FALSE;
1371 SCIP_Real* vals1;
1372 SCIP_Real* vals2;
1373 int ngen = 0;
1374 int c;
1375
1376 assert( scip != 0 );
1377 assert( conshdlr != 0 );
1378 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1379 assert( result != 0 );
1380
1381 SCIPdebugMsg(scip, "Enfolp method for orbisack constraints\n");
1382
1383 /* we have a negative priority, so we should come after the integrality conshdlr. */
1384 assert( SCIPgetNLPBranchCands(scip) == 0 );
1385
1386 *result = SCIP_FEASIBLE;
1387
1388 if ( nconss > 0 )
1389 {
1390 SCIP_CONSHDLRDATA* conshdlrdata;
1391 int nvals;
1392
1393 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1394 assert( conshdlrdata != NULL );
1395
1396 nvals = conshdlrdata->maxnrows;
1397 assert( nvals > 0 );
1398
1399 SCIP_CALL( SCIPallocBufferArray(scip, &vals1, nvals) );
1400 SCIP_CALL( SCIPallocBufferArray(scip, &vals2, nvals) );
1401
1402 /* loop through constraints */
1403 for (c = 0; c < nconss; ++c)
1404 {
1405 /* get data of constraint */
1406 assert( conss[c] != 0 );
1407 consdata = SCIPconsGetData(conss[c]);
1408 assert( consdata != NULL );
1409
1410 /* do not enforce non-model constraints */
1411 if ( !consdata->ismodelcons )
1412 continue;
1413
1414 /* get solution */
1415 assert( consdata->nrows <= nvals );
1416 SCIP_CALL( SCIPgetSolVals(scip, NULL, consdata->nrows, consdata->vars1, vals1) );
1417 SCIP_CALL( SCIPgetSolVals(scip, NULL, consdata->nrows, consdata->vars2, vals2) );
1418
1419 SCIPdebugMsg(scip, "Enforcing orbisack constraint <%s> ...\n", SCIPconsGetName(conss[c]));
1420
1421 /* Separate only cover inequalities to ensure that enforcing works correctly. */
1422 /* Otherwise, it may happen that infeasible solutions cannot be detected, since */
1423 /* we bound the size of the coefficients for the orbisack inequalities. */
1424 SCIP_CALL( separateOrbisackCovers(scip, conss[c], consdata->nrows, consdata->vars1, consdata->vars2, vals1, vals2, &ngen, &infeasible) );
1425
1426 if ( infeasible )
1427 {
1428 *result = SCIP_CUTOFF;
1429 break;
1430 }
1431
1432 SCIPdebugMsg(scip, "Generated orbisack inequalities for <%s>: %d\n", SCIPconsGetName(conss[c]), ngen);
1433
1434 if ( ngen > 0 )
1435 *result = SCIP_SEPARATED;
1436 }
1437
1438 SCIPfreeBufferArray(scip, &vals2);
1439 SCIPfreeBufferArray(scip, &vals1);
1440 }
1441
1442 return SCIP_OKAY;
1443}
1444
1445
1446/** constraint enforcing method of constraint handler for pseudo solutions */
1447static
1448SCIP_DECL_CONSENFOPS(consEnfopsOrbisack)
1449{ /*lint --e{715}*/
1450 SCIP_Bool feasible = TRUE;
1451 SCIP_CONSDATA* consdata;
1452 int c;
1453
1454 assert( scip != NULL );
1455 assert( conshdlr != NULL );
1456 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1457 assert( result != NULL );
1458
1459 SCIPdebugMsg(scip, "Enforcing method for orbisack constraints (pseudo solutions) ...\n");
1460
1461 *result = SCIP_FEASIBLE;
1462
1463 if ( objinfeasible || solinfeasible )
1464 return SCIP_OKAY;
1465
1466 /* loop through constraints */
1467 for (c = 0; c < nconss; ++c)
1468 {
1469 /* get data of constraint */
1470 assert( conss[c] != NULL );
1471 consdata = SCIPconsGetData(conss[c]);
1472 assert( consdata != NULL);
1473 assert( consdata->nrows > 0 );
1474 assert( consdata->vars1 != NULL );
1475 assert( consdata->vars2 != NULL );
1476
1477 /* do not enforce non-model constraints */
1478 if ( !consdata->ismodelcons )
1479 continue;
1480
1481 SCIP_CALL( SCIPcheckSolutionOrbisack(scip, NULL, consdata->vars1, consdata->vars2, consdata->nrows, FALSE, &feasible) );
1482
1483 if ( ! feasible )
1484 {
1485 *result = SCIP_INFEASIBLE;
1486 break;
1487 }
1488 }
1489
1490 return SCIP_OKAY;
1491}
1492
1493
1494/** constraint enforcing method of constraint handler for relaxation solutions */
1495static
1496SCIP_DECL_CONSENFORELAX(consEnforelaxOrbisack)
1497{ /*lint --e{715}*/
1498 SCIP_CONSDATA* consdata;
1499 SCIP_Bool infeasible = FALSE;
1500 SCIP_Real* vals1;
1501 SCIP_Real* vals2;
1502 int ngen = 0;
1503 int c;
1504
1505 assert( scip != 0 );
1506 assert( conshdlr != 0 );
1507 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1508 assert( result != 0 );
1509
1510 SCIPdebugMsg(scip, "Enforelax method for orbisack constraints.\n");
1511
1512 /* we have a negative priority, so we should come after the integrality conshdlr. */
1513 assert( SCIPgetNLPBranchCands(scip) == 0 );
1514
1515 *result = SCIP_FEASIBLE;
1516
1517 if ( nconss > 0 )
1518 {
1519 SCIP_CONSHDLRDATA* conshdlrdata;
1520 int nvals;
1521
1522 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1523 assert( conshdlrdata != NULL );
1524
1525 nvals = conshdlrdata->maxnrows;
1526 assert( nvals > 0 );
1527
1528 SCIP_CALL( SCIPallocBufferArray(scip, &vals1, nvals) );
1529 SCIP_CALL( SCIPallocBufferArray(scip, &vals2, nvals) );
1530
1531 /* loop through constraints */
1532 for (c = 0; c < nconss; ++c)
1533 {
1534 /* get data of constraint */
1535 assert( conss[c] != 0 );
1536 consdata = SCIPconsGetData(conss[c]);
1537 assert( consdata != NULL );
1538
1539 /* do not enforce non-model constraints */
1540 if ( !consdata->ismodelcons )
1541 continue;
1542
1543 /* get solution */
1544 assert( consdata->nrows <= nvals );
1545 SCIP_CALL( SCIPgetSolVals(scip, sol, consdata->nrows, consdata->vars1, vals1) );
1546 SCIP_CALL( SCIPgetSolVals(scip, sol, consdata->nrows, consdata->vars2, vals2) );
1547
1548 SCIPdebugMsg(scip, "Enforcing orbisack constraint <%s> ...\n", SCIPconsGetName(conss[c]));
1549
1550 /* Separate only cover inequalities to ensure that enforcing works correctly. */
1551 /* Otherwise, it may happen that infeasible solutions cannot be detected, since */
1552 /* we bound the size of the coefficients for the orbisack inequalities. */
1553 SCIP_CALL( separateOrbisackCovers(scip, conss[c], consdata->nrows, consdata->vars1, consdata->vars2, vals1, vals2, &ngen, &infeasible) );
1554
1555 if ( infeasible )
1556 {
1557 *result = SCIP_CUTOFF;
1558 break;
1559 }
1560
1561 SCIPdebugMsg(scip, "Generated orbisack inequalities for <%s>: %d\n", SCIPconsGetName(conss[c]), ngen);
1562
1563 if ( ngen > 0 )
1564 *result = SCIP_SEPARATED;
1565 }
1566
1567 SCIPfreeBufferArray(scip, &vals2);
1568 SCIPfreeBufferArray(scip, &vals1);
1569 }
1570
1571 return SCIP_OKAY;
1572}
1573
1574
1575/** feasibility check method of constraint handler for integral solutions */
1576static
1577SCIP_DECL_CONSCHECK(consCheckOrbisack)
1578{ /*lint --e{715}*/
1579 SCIP_Bool feasible = TRUE;
1580 SCIP_CONSDATA* consdata;
1581 int c;
1582
1583 assert( scip != NULL );
1584 assert( conshdlr != NULL );
1585 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1586 assert( result != NULL );
1587
1588 *result = SCIP_FEASIBLE;
1589
1590 /* loop through constraints */
1591 for (c = 0; c < nconss; ++c)
1592 {
1593 /* get data of constraint */
1594 assert( conss[c] != NULL );
1595 consdata = SCIPconsGetData(conss[c]);
1596 assert( consdata != NULL);
1597 assert( consdata->nrows > 0 );
1598 assert( consdata->vars1 != NULL );
1599 assert( consdata->vars2 != NULL );
1600
1601 SCIPdebugMsg(scip, "Check method for orbisack constraint <%s> (%d rows) ...\n", SCIPconsGetName(conss[c]), consdata->nrows);
1602
1603 /* do not check non-model constraints */
1604 if ( !consdata->ismodelcons )
1605 continue;
1606
1607 SCIP_CALL( SCIPcheckSolutionOrbisack(scip, sol, consdata->vars1, consdata->vars2, consdata->nrows, printreason, &feasible) );
1608
1609 if ( ! feasible )
1610 {
1611 *result = SCIP_INFEASIBLE;
1612 SCIPdebugMsg(scip, "Solution is feasible.\n");
1613 break;
1614 }
1615 }
1616
1617 if ( feasible )
1618 SCIPdebugMsg(scip, "Solution is feasible.\n");
1619
1620 return SCIP_OKAY;
1621}
1622
1623
1624/** domain propagation method of constraint handler */
1625static
1626SCIP_DECL_CONSPROP(consPropOrbisack)
1627{ /*lint --e{715}*/
1628 int c;
1629
1630 assert( scip != NULL );
1631 assert( conshdlr != NULL );
1632 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1633 assert( result != NULL );
1634
1635 *result = SCIP_DIDNOTRUN;
1636
1637 SCIPdebugMsg(scip, "Propagation method of orbisack constraint handler.\n");
1638
1639 /* loop through constraints */
1640 for (c = 0; c < nconss; ++c)
1641 {
1642 SCIP_Bool infeasible = FALSE;
1643 SCIP_Bool found = FALSE;
1644 int ngen = 0;
1645
1646 assert( conss[c] != NULL );
1647
1648 SCIP_CALL( propVariables(scip, conss[c], &infeasible, &found, &ngen) );
1649
1650 if ( infeasible )
1651 {
1652 *result = SCIP_CUTOFF;
1653 return SCIP_OKAY;
1654 }
1655
1656 if ( found )
1657 *result = SCIP_REDUCEDDOM;
1658 }
1659
1660 return SCIP_OKAY;
1661}
1662
1663
1664/** presolving method of constraint handler */
1665static
1666SCIP_DECL_CONSPRESOL(consPresolOrbisack)
1667{ /*lint --e{715}*/
1668 int c;
1669 int ngen = 0;
1670
1671 assert( scip != NULL );
1672 assert( conshdlr != NULL );
1673 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1674 assert( result != NULL );
1675
1676 SCIPdebugMsg(scip, "Presolving method of orbisack constraint handler. Propagating orbisack inequalities.\n");
1677
1678 *result = SCIP_DIDNOTFIND;
1679
1680 /* loop through constraints */
1681 for (c = 0; c < nconss; ++c)
1682 {
1683 SCIP_Bool infeasible = FALSE;
1684 SCIP_Bool found = FALSE;
1685 int curngen = 0;
1686
1687 assert( conss[c] != NULL );
1688 SCIP_CALL( propVariables(scip, conss[c], &infeasible, &found, &curngen) );
1689
1690 if ( infeasible )
1691 {
1692 *result = SCIP_CUTOFF;
1693 break;
1694 }
1695
1696 ngen += curngen;
1697 }
1698
1699 if ( ngen > 0 )
1700 {
1701 *nfixedvars += ngen;
1702 *result = SCIP_SUCCESS;
1703 }
1704
1705 return SCIP_OKAY;
1706}
1707
1708
1709/** Propagation resolution for conflict analysis */
1710static
1711SCIP_DECL_CONSRESPROP(consRespropOrbisack)
1712{ /*lint --e{715}*/
1713 SCIP_CONSDATA* consdata;
1714 SCIP_VAR** vars1;
1715 SCIP_VAR** vars2;
1716 int i;
1717 int varrow;
1718 int infrow;
1719
1720 assert( scip != NULL );
1721 assert( conshdlr != NULL );
1722 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1723 assert( cons != NULL );
1724 assert( infervar != NULL );
1725 assert( bdchgidx != NULL );
1726 assert( result != NULL );
1727
1728 SCIPdebugMsg(scip, "Propagation resolution method of orbisack constraint handler.\n");
1729
1730 *result = SCIP_DIDNOTFIND;
1731
1732 consdata = SCIPconsGetData(cons);
1733 assert( consdata != NULL);
1734 assert( consdata->nrows > 0 );
1735 assert( consdata->vars1 != NULL );
1736 assert( consdata->vars2 != NULL );
1737
1738 vars1 = consdata->vars1;
1739 vars2 = consdata->vars2;
1740
1741 /* inferinfo == varrow + infrow * nrows. infrow is 0 if the fixing is not caused by a lookahead. */
1742 varrow = inferinfo % consdata->nrows;
1743 infrow = inferinfo / consdata->nrows;
1744
1745 assert( varrow >= 0 );
1746 assert( varrow < consdata->nrows );
1747 assert( infrow >= 0 );
1748 assert( infrow < consdata->nrows );
1749
1750 /* In both cases, the rows until "varrow" are constants. */
1751 for (i = 0; i < varrow; ++i)
1752 {
1753 /* Conflict caused by bounds of previous variables */
1754 SCIP_CALL( SCIPaddConflictUb(scip, vars1[i], bdchgidx) );
1755 SCIP_CALL( SCIPaddConflictLb(scip, vars1[i], bdchgidx) );
1756 SCIP_CALL( SCIPaddConflictUb(scip, vars2[i], bdchgidx) );
1757 SCIP_CALL( SCIPaddConflictLb(scip, vars2[i], bdchgidx) );
1758 }
1759
1760 if ( infrow > 0 )
1761 {
1762 /* The fixing of infervar is caused by a lookahead (checkFeasible).
1763 * The rows until "varrow" are constants, and row "varrow" is (_, _), (1, _), (_, 0).
1764 * If we assume "varrow" is constant, then the next rows until infrow are constants, and infrow is (0, 1).
1765 */
1766 for (i = varrow + 1; i < infrow; ++i)
1767 {
1768 /* These rows are one of (0, 0), (1, 1), (0, _), (_, 1), making them constants. */
1769 SCIP_CALL( SCIPaddConflictUb(scip, vars1[i], bdchgidx) );
1770 SCIP_CALL( SCIPaddConflictLb(scip, vars1[i], bdchgidx) );
1771 SCIP_CALL( SCIPaddConflictUb(scip, vars2[i], bdchgidx) );
1772 SCIP_CALL( SCIPaddConflictLb(scip, vars2[i], bdchgidx) );
1773 }
1774
1775 /* And infrow itself is (0, 1). */
1776 assert( SCIPgetVarUbAtIndex(scip, vars1[infrow], bdchgidx, TRUE) < 0.5 );
1777 assert( SCIPgetVarUbAtIndex(scip, vars1[infrow], bdchgidx, FALSE) < 0.5 );
1778 assert( SCIPgetVarLbAtIndex(scip, vars2[infrow], bdchgidx, TRUE) > 0.5 );
1779 assert( SCIPgetVarLbAtIndex(scip, vars2[infrow], bdchgidx, FALSE) > 0.5 );
1780
1781 SCIP_CALL( SCIPaddConflictUb(scip, vars1[infrow], bdchgidx) );
1782 SCIP_CALL( SCIPaddConflictLb(scip, vars2[infrow], bdchgidx) );
1783 }
1784 else
1785 {
1786 /* This is not a fixing caused by lookahead (checkFeasible),
1787 * so row "varrow" was (0, _) or (_, 1) and its previous rows are constants.
1788 */
1789 if ( boundtype == SCIP_BOUNDTYPE_LOWER )
1790 {
1791 /* We changed the lower bound of infervar to 1. This means that this fixing is due to (_, 1) */
1792 assert( infervar == vars1[varrow] );
1793 assert( SCIPgetVarLbAtIndex(scip, vars1[varrow], bdchgidx, FALSE) < 0.5 );
1794 assert( SCIPgetVarLbAtIndex(scip, vars1[varrow], bdchgidx, TRUE) > 0.5 );
1795 assert( SCIPgetVarLbAtIndex(scip, vars2[varrow], bdchgidx, FALSE) > 0.5);
1796 assert( SCIPgetVarUbAtIndex(scip, vars2[varrow], bdchgidx, FALSE) > 0.5);
1797
1798 SCIP_CALL( SCIPaddConflictUb(scip, vars2[varrow], bdchgidx) );
1799 SCIP_CALL( SCIPaddConflictLb(scip, vars2[varrow], bdchgidx) );
1800 }
1801 else
1802 {
1803 /* We changed the upper bound to 0. This means that this fixing is due to (0, _) */
1804 assert( infervar == vars2[varrow] );
1805 assert( SCIPgetVarLbAtIndex(scip, vars1[varrow], bdchgidx, FALSE) < 0.5);
1806 assert( SCIPgetVarUbAtIndex(scip, vars1[varrow], bdchgidx, FALSE) < 0.5);
1807 assert( SCIPgetVarUbAtIndex(scip, vars2[varrow], bdchgidx, FALSE) > 0.5 );
1808 assert( SCIPgetVarUbAtIndex(scip, vars2[varrow], bdchgidx, TRUE) < 0.5 );
1809
1810 SCIP_CALL( SCIPaddConflictUb(scip, vars1[varrow], bdchgidx) );
1811 SCIP_CALL( SCIPaddConflictLb(scip, vars1[varrow], bdchgidx) );
1812 }
1813 }
1814
1815 *result = SCIP_SUCCESS;
1816 return SCIP_OKAY;
1817}
1818
1819
1820/** presolving deinitialization method of constraint handler (called after presolving has been finished) */
1821static
1822SCIP_DECL_CONSEXITPRE(consExitpreOrbisack)
1823{
1824 int c;
1825
1826 assert( scip != NULL );
1827 assert( conshdlr != NULL );
1828 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1829
1830 for (c = 0; c < nconss; ++c)
1831 {
1832 /* replace aggregated variables by active variables */
1834 }
1835 return SCIP_OKAY;
1836}
1837
1838
1839/** Lock variables
1840 *
1841 * We assume we have only one global (void) constraint and lock all variables.
1842 *
1843 * - Orbisack constraints may get violated if the variables of the first column
1844 * are rounded down, we therefor call SCIPaddVarLocksType(..., nlockspos, nlocksneg).
1845 * - Orbisack constraints may get violated if the variables of the second column
1846 * are rounded up , we therefor call SCIPaddVarLocksType(..., nlocksneg, nlockspo ).
1847 */
1848static
1849SCIP_DECL_CONSLOCK(consLockOrbisack)
1850{ /*lint --e{715}*/
1851 SCIP_CONSDATA* consdata;
1852 SCIP_VAR** vars1;
1853 SCIP_VAR** vars2;
1854 int nrows;
1855 int i;
1856
1857 assert( scip != NULL );
1858 assert( conshdlr != NULL );
1859 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
1860 assert( cons != NULL );
1861
1862 SCIPdebugMsg(scip, "Locking method for orbisack constraint handler.\n");
1863
1864 /* get data of original constraint */
1865 consdata = SCIPconsGetData(cons);
1866 assert( consdata != NULL);
1867 assert( consdata->nrows > 0 );
1868 assert( consdata->vars1 != NULL );
1869 assert( consdata->vars2 != NULL );
1870
1871 nrows = consdata->nrows;
1872 vars1 = consdata->vars1;
1873 vars2 = consdata->vars2;
1874
1875 for (i = 0; i < nrows; ++i)
1876 {
1877 SCIP_CALL( SCIPaddVarLocksType(scip, vars1[i], locktype, nlockspos, nlocksneg) );
1878 SCIP_CALL( SCIPaddVarLocksType(scip, vars2[i], locktype, nlocksneg, nlockspos) );
1879 }
1880
1881 return SCIP_OKAY;
1882}
1883
1884
1885/** constraint copying method of constraint handler */
1886static
1887SCIP_DECL_CONSCOPY(consCopyOrbisack)
1888{
1889 SCIP_CONSHDLRDATA* conshdlrdata;
1890 SCIP_CONSDATA* sourcedata;
1891 SCIP_VAR** sourcevars1;
1892 SCIP_VAR** sourcevars2;
1893 SCIP_VAR** vars1;
1894 SCIP_VAR** vars2;
1895 int nrows;
1896 int i;
1897
1898 assert( scip != NULL );
1899 assert( cons != NULL );
1900 assert( sourcescip != NULL );
1901 assert( sourceconshdlr != NULL );
1902 assert( strcmp(SCIPconshdlrGetName(sourceconshdlr), CONSHDLR_NAME) == 0 );
1903 assert( sourcecons != NULL );
1904 assert( varmap != NULL );
1905 assert( valid != NULL );
1906
1907 *valid = TRUE;
1908
1909 SCIPdebugMsg(scip, "Copying method for orbisack constraint handler.\n");
1910
1911 sourcedata = SCIPconsGetData(sourcecons);
1912 assert( sourcedata != NULL );
1913 assert( sourcedata->vars1 != NULL );
1914 assert( sourcedata->vars2 != NULL );
1915 assert( sourcedata->nrows > 0 );
1916
1917 conshdlrdata = SCIPconshdlrGetData(sourceconshdlr);
1918 assert( conshdlrdata != NULL );
1919
1920 /* do not copy non-model constraints */
1921 if ( !sourcedata->ismodelcons && !conshdlrdata->forceconscopy )
1922 {
1923 *valid = FALSE;
1924
1925 return SCIP_OKAY;
1926 }
1927
1928 sourcevars1 = sourcedata->vars1;
1929 sourcevars2 = sourcedata->vars2;
1930 nrows = sourcedata->nrows;
1931
1932 SCIP_CALL( SCIPallocBufferArray(scip, &vars1, nrows) );
1933
1934 for (i = 0; i < nrows && *valid; ++i)
1935 {
1936 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcevars1[i], &(vars1[i]), varmap, consmap, global, valid) );
1937 assert( !(*valid) || vars1[i] != NULL );
1938 }
1939
1940 /* only create the target constraint, if all variables could be copied */
1941 if ( !(*valid) )
1942 {
1943 SCIPfreeBufferArray(scip, &vars1);
1944
1945 return SCIP_OKAY;
1946 }
1947
1948 SCIP_CALL( SCIPallocBufferArray(scip, &vars2, nrows) );
1949
1950 for (i = 0; i < nrows && *valid; ++i)
1951 {
1952 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcevars2[i], &(vars2[i]), varmap, consmap, global, valid) );
1953 assert( !(*valid) || vars2[i] != NULL );
1954 }
1955
1956 /* only create the target constraint, if all variables could be copied */
1957 if ( *valid )
1958 {
1959 /* create copied constraint */
1960 if ( name == NULL )
1961 name = SCIPconsGetName(sourcecons);
1962
1963 SCIP_CALL( SCIPcreateConsOrbisack(scip, cons, name, vars1, vars2, nrows, FALSE, FALSE, sourcedata->ismodelcons,
1964 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
1965 }
1966
1967 SCIPfreeBufferArray(scip, &vars2);
1968 SCIPfreeBufferArray(scip, &vars1);
1969
1970 return SCIP_OKAY;
1971}
1972
1973
1974/** constraint parsing method of constraint handler */
1975static
1976SCIP_DECL_CONSPARSE(consParseOrbisack)
1977{ /*lint --e{715}*/
1978 const char* s;
1979 char* endptr;
1980 SCIP_VAR** vars1;
1981 SCIP_VAR** vars2;
1982 SCIP_VAR* var;
1983 int nrows = 0;
1984 int maxnrows = 128;
1985 SCIP_Bool firstcolumn = TRUE;
1986 SCIP_Bool ispporbisack = FALSE;
1987 SCIP_Bool isparttype = FALSE;
1988
1989 assert( success != NULL );
1990
1991 *success = TRUE;
1992 s = str;
1993
1994 /* skip white space */
1995 SCIP_CALL( SCIPskipSpace((char**)&s) );
1996
1997 if( strncmp(s, "partOrbisack(", 13) == 0 )
1998 {
1999 ispporbisack = TRUE;
2000 isparttype = TRUE;
2001 }
2002 else if( strncmp(s, "packOrbisack(", 13) == 0 )
2003 ispporbisack = TRUE;
2004 else
2005 {
2006 if( strncmp(s, "fullOrbisack(", 13) != 0 )
2007 {
2008 SCIPerrorMessage("Syntax error - expected \"fullOrbisack(\", \"partOrbisack\" or \"packOrbisacj\": %s\n", s);
2009 *success = FALSE;
2010 return SCIP_OKAY;
2011 }
2012 }
2013 s += 13;
2014
2015 /* loop through string */
2016 SCIP_CALL( SCIPallocBufferArray(scip, &vars1, maxnrows) );
2017 SCIP_CALL( SCIPallocBufferArray(scip, &vars2, maxnrows) );
2018
2019 do
2020 {
2021 /* parse variable name */
2022 SCIP_CALL( SCIPparseVarName(scip, s, &var, &endptr) );
2023
2024 if( var == NULL )
2025 {
2026 endptr = strchr(endptr, ')');
2027
2028 if( endptr == NULL || !firstcolumn )
2029 {
2030 SCIPerrorMessage("variable is missing.\n");
2031 *success = FALSE;
2032 }
2033
2034 break;
2035 }
2036
2037 s = endptr;
2038 assert( s != NULL );
2039
2040 /* skip white space */
2041 SCIP_CALL( SCIPskipSpace((char**)&s) );
2042
2043 if( firstcolumn == ( *s == '.' || *s == ')' ) )
2044 {
2045 SCIPerrorMessage("there are not two variables per row.\n");
2046 *success = FALSE;
2047 break;
2048 }
2049
2050 /* begin new row if required */
2051 if( firstcolumn )
2052 {
2053 ++nrows;
2054
2055 if( nrows > maxnrows )
2056 {
2057 maxnrows = SCIPcalcMemGrowSize(scip, nrows);
2058 SCIP_CALL( SCIPreallocBufferArray(scip, &vars1, maxnrows) );
2059 SCIP_CALL( SCIPreallocBufferArray(scip, &vars2, maxnrows) );
2060 assert( nrows <= maxnrows );
2061 }
2062
2063 vars1[nrows-1] = var;
2064 }
2065 else
2066 vars2[nrows-1] = var;
2067
2068 firstcolumn = !firstcolumn;
2069
2070 /* skip ',' or '.' */
2071 if( *s == ',' || *s == '.' )
2072 ++s;
2073 }
2074 while( *s != ')' );
2075
2076 if( *success )
2077 SCIP_CALL( SCIPcreateConsBasicOrbisack(scip, cons, name, vars1, vars2, nrows, ispporbisack, isparttype, TRUE) );
2078
2079 SCIPfreeBufferArray(scip, &vars2);
2080 SCIPfreeBufferArray(scip, &vars1);
2081
2082 return SCIP_OKAY;
2083}
2084
2085
2086/** constraint display method of constraint handler
2087 *
2088 * The constraint handler should output a representation of the constraint into the given text file.
2089 */
2090static
2091SCIP_DECL_CONSPRINT(consPrintOrbisack)
2092{ /*lint --e{715}*/
2093 SCIP_CONSDATA* consdata;
2094 SCIP_VAR** vars1;
2095 SCIP_VAR** vars2;
2096 int nrows;
2097 int i;
2098
2099 assert( scip != NULL );
2100 assert( conshdlr != NULL );
2101 assert( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0 );
2102 assert( cons != NULL );
2103
2104 consdata = SCIPconsGetData(cons);
2105 assert( consdata != NULL );
2106 assert( consdata->vars1 != NULL );
2107 assert( consdata->vars2 != NULL );
2108 assert( consdata->nrows > 0 );
2109
2110 vars1 = consdata->vars1;
2111 vars2 = consdata->vars2;
2112 nrows = consdata->nrows;
2113
2114 SCIPdebugMsg(scip, "Printing method for orbisack constraint handler\n");
2115
2116 SCIPinfoMessage(scip, file, "fullOrbisack(");
2117
2118 for (i = 0; i < nrows; ++i)
2119 {
2120 SCIP_CALL( SCIPwriteVarName(scip, file, vars1[i], TRUE) );
2121 SCIPinfoMessage(scip, file, ",");
2122 SCIP_CALL( SCIPwriteVarName(scip, file, vars2[i], TRUE) );
2123 if ( i < nrows-1 )
2124 SCIPinfoMessage(scip, file, ".");
2125 }
2126
2127 SCIPinfoMessage(scip, file, ")");
2128
2129 return SCIP_OKAY;
2130}
2131
2132
2133/** checks given solution for feasibility */
2135 SCIP* scip, /**< SCIP data structure */
2136 SCIP_SOL* sol, /**< solution to check for feasibility */
2137 SCIP_VAR** vars1, /**< variables of first column */
2138 SCIP_VAR** vars2, /**< variables of second column */
2139 int nrows, /**< number of rows */
2140 SCIP_Bool printreason, /**< whether reason for infeasibility should be printed */
2141 SCIP_Bool* feasible /**< memory address to store whether sol is feasible */
2142 )
2143{
2144 int i;
2145 int val1;
2146 int val2;
2147
2148 assert( scip != NULL );
2149 assert( vars1 != NULL );
2150 assert( vars2 != NULL );
2151 assert( nrows > 0 );
2152 assert( feasible != NULL );
2153
2154 *feasible = TRUE;
2155
2156 /* find first non-constant row and check for feasibility */
2157 for (i = 0; i < nrows; ++i)
2158 {
2159 assert( SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, sol, vars1[i])) );
2160 assert( SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, sol, vars2[i])) );
2161
2162 /* get values of i-th row */
2163 val1 = SCIPgetSolVal(scip, sol, vars1[i]) > 0.5 ? 1 : 0;
2164 val2 = SCIPgetSolVal(scip, sol, vars2[i]) > 0.5 ? 1 : 0;
2165
2166 /* if row i is constrant */
2167 if ( val1 == val2 )
2168 continue;
2169 /* row i has type (1,0) -> feasible */
2170 else if ( val1 == 1 )
2171 {
2172 assert( val2 == 0 );
2173 break;
2174 }
2175 else /* infeasible */
2176 {
2177 if ( printreason )
2178 SCIPinfoMessage(scip, NULL, "First non-constant row %d is fixed to (0,1).\n", i);
2179 *feasible = FALSE;
2180 break;
2181 }
2182 }
2183
2184 return SCIP_OKAY;
2185}
2186
2187
2188/** constraint method of constraint handler which returns the variables (if possible) */
2189static
2190SCIP_DECL_CONSGETVARS(consGetVarsOrbisack)
2191{ /*lint --e{715}*/
2192 SCIP_CONSDATA* consdata;
2193
2194 assert( cons != NULL );
2195 assert( success != NULL );
2196 assert( vars != NULL );
2197
2198 consdata = SCIPconsGetData(cons);
2199 assert( consdata != NULL );
2200
2201 if ( varssize < 2 * consdata->nrows )
2202 (*success) = FALSE;
2203 else
2204 {
2205 int cnt = 0;
2206 int i;
2207
2208 for (i = 0; i < consdata->nrows; ++i)
2209 {
2210 vars[cnt++] = consdata->vars1[i];
2211 vars[cnt++] = consdata->vars2[i];
2212 }
2213 (*success) = TRUE;
2214 }
2215
2216 return SCIP_OKAY;
2217}
2218
2219
2220/** constraint method of constraint handler which returns the number of variables (if possible) */
2221static
2222SCIP_DECL_CONSGETNVARS(consGetNVarsOrbisack)
2223{ /*lint --e{715}*/
2224 SCIP_CONSDATA* consdata;
2225
2226 assert( cons != NULL );
2227
2228 consdata = SCIPconsGetData(cons);
2229 assert( consdata != NULL );
2230
2231 (*nvars) = 2 * consdata->nrows;
2232 (*success) = TRUE;
2233
2234 return SCIP_OKAY;
2235}
2236
2237
2238/** creates the handler for orbisack constraints and includes it in SCIP */
2240 SCIP* scip /**< SCIP data structure */
2241 )
2242{
2243 SCIP_CONSHDLRDATA* conshdlrdata = NULL;
2244 SCIP_CONSHDLR* conshdlr;
2245
2246 SCIP_CALL( SCIPallocBlockMemory(scip, &conshdlrdata) );
2247
2248 /* include constraint handler */
2252 consEnfolpOrbisack, consEnfopsOrbisack, consCheckOrbisack, consLockOrbisack,
2253 conshdlrdata) );
2254 assert( conshdlr != NULL );
2255
2256 /* set non-fundamental callbacks via specific setter functions */
2257 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyOrbisack, consCopyOrbisack) );
2258 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxOrbisack) );
2259 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeOrbisack) );
2260 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteOrbisack) );
2261 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsOrbisack) );
2262 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsOrbisack) );
2263 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseOrbisack) );
2265 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintOrbisack) );
2267 SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropOrbisack) );
2268 SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreOrbisack) );
2269 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpOrbisack, consSepasolOrbisack, CONSHDLR_SEPAFREQ, CONSHDLR_SEPAPRIORITY, CONSHDLR_DELAYSEPA) );
2270 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransOrbisack) );
2271 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpOrbisack) );
2272 SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolOrbisack) );
2273
2274 /* separation methods */
2275 SCIP_CALL( SCIPaddBoolParam(scip, "constraints/" CONSHDLR_NAME "/coverseparation",
2276 "Separate cover inequalities for orbisacks?",
2277 &conshdlrdata->coverseparation, TRUE, DEFAULT_COVERSEPARATION, NULL, NULL) );
2278
2279 SCIP_CALL( SCIPaddBoolParam(scip, "constraints/" CONSHDLR_NAME "/orbiSeparation",
2280 "Separate orbisack inequalities?",
2281 &conshdlrdata->orbiseparation, TRUE, DEFAULT_ORBISEPARATION, NULL, NULL) );
2282
2283 SCIP_CALL( SCIPaddRealParam(scip, "constraints/" CONSHDLR_NAME "/coeffbound",
2284 "Maximum size of coefficients for orbisack inequalities",
2285 &conshdlrdata->coeffbound, TRUE, DEFAULT_COEFFBOUND, 0.0, DBL_MAX, NULL, NULL) );
2286
2287 /* whether we allow upgrading to packing/partioning orbisack constraints*/
2288 SCIP_CALL( SCIPaddBoolParam(scip, "constraints/" CONSHDLR_NAME "/checkpporbisack",
2289 "Upgrade orbisack constraints to packing/partioning orbisacks?",
2290 &conshdlrdata->checkpporbisack, TRUE, DEFAULT_PPORBISACK, NULL, NULL) );
2291
2292 SCIP_CALL( SCIPaddBoolParam(scip, "constraints/" CONSHDLR_NAME "/forceconscopy",
2293 "Whether orbisack constraints should be forced to be copied to sub SCIPs.",
2294 &conshdlrdata->forceconscopy, TRUE, DEFAULT_FORCECONSCOPY, NULL, NULL) );
2295
2296 return SCIP_OKAY;
2297}
2298
2299
2300/*
2301 * constraint specific interface methods
2302 */
2303
2304/** creates and captures a orbisack constraint
2305 *
2306 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
2307 */
2309 SCIP* scip, /**< SCIP data structure */
2310 SCIP_CONS** cons, /**< pointer to hold the created constraint */
2311 const char* name, /**< name of constraint */
2312 SCIP_VAR*const* vars1, /**< first column of matrix of variables on which the symmetry acts */
2313 SCIP_VAR*const* vars2, /**< second column of matrix of variables on which the symmetry acts */
2314 int nrows, /**< number of rows in variable matrix */
2315 SCIP_Bool ispporbisack, /**< whether the orbisack is a packing/partitioning orbisack */
2316 SCIP_Bool isparttype, /**< whether the orbisack is a partitioning orbisack */
2317 SCIP_Bool ismodelcons, /**< whether the orbisack is a model constraint */
2318 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
2319 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
2320 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
2321 * Usually set to TRUE. */
2322 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
2323 * TRUE for model constraints, FALSE for additional, redundant constraints. */
2324 SCIP_Bool check, /**< should the constraint be checked for feasibility?
2325 * TRUE for model constraints, FALSE for additional, redundant constraints. */
2326 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
2327 * Usually set to TRUE. */
2328 SCIP_Bool local, /**< is constraint only valid locally?
2329 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
2330 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
2331 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
2332 * adds coefficients to this constraint. */
2333 SCIP_Bool dynamic, /**< is constraint subject to aging?
2334 * Usually set to FALSE. Set to TRUE for own cuts which
2335 * are separated as constraints. */
2336 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
2337 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
2338 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
2339 * if it may be moved to a more global node?
2340 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
2341 )
2342{
2343 SCIP_CONSHDLR* conshdlr;
2344 SCIP_CONSHDLRDATA* conshdlrdata;
2345 SCIP_CONSDATA* consdata;
2346 SCIP_VAR*** vars;
2347 SCIP_Bool success;
2348 SCIP_ORBITOPETYPE orbitopetype;
2349 int i;
2350
2351 /* find the orbisack constraint handler */
2352 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2353 if ( conshdlr == NULL )
2354 {
2355 SCIPerrorMessage("orbisack constraint handler not found\n");
2356 return SCIP_PLUGINNOTFOUND;
2357 }
2358
2359 assert( nrows > 0 );
2360
2361 /* check for upgrade to packing/partitioning orbisacks*/
2362 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2363 if ( ! ispporbisack && conshdlrdata->checkpporbisack )
2364 {
2365 SCIP_CALL( packingUpgrade(scip, vars1, vars2, nrows, &success, &isparttype) );
2366
2367 if ( success )
2368 ispporbisack = TRUE;
2369 }
2370
2371 /* create constraint, if it is a packing/partitioning orbisack, add orbitope constraint
2372 * instead of orbitsack constraint */
2373 if ( ispporbisack )
2374 {
2375 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nrows) );
2376 for (i = 0; i < nrows; ++i)
2377 {
2378 SCIP_CALL( SCIPallocBufferArray(scip, &vars[i], 2) ); /*lint !e866*/
2379 vars[i][0] = vars1[i];
2380 vars[i][1] = vars2[i];
2381 }
2382
2383 if ( isparttype )
2384 orbitopetype = SCIP_ORBITOPETYPE_PARTITIONING;
2385 else
2386 orbitopetype = SCIP_ORBITOPETYPE_PACKING;
2387
2388 SCIP_CALL( SCIPcreateConsOrbitope(scip, cons, "pporbisack", vars, orbitopetype, nrows,
2389 2, TRUE, ismodelcons, FALSE, initial, separate, enforce, check, propagate, local,
2390 modifiable, dynamic, removable, stickingatnode) );
2391
2392 for (i = 0; i < nrows; ++i)
2393 SCIPfreeBufferArray(scip, &vars[i]);
2394 SCIPfreeBufferArray(scip, &vars);
2395 }
2396 else
2397 {
2398 /* create constraint data */
2399 SCIP_CALL( consdataCreate(scip, &consdata, vars1, vars2, nrows, ismodelcons) );
2400
2401 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
2402 local, modifiable, dynamic, removable, stickingatnode) );
2403 }
2404
2405 return SCIP_OKAY;
2406}
2407
2408
2409/** creates and captures an orbisack constraint in its most basic variant
2410 *
2411 * All constraint flags set to their default values, which can be set afterwards using SCIPsetConsFLAGNAME() in scip.h.
2412 *
2413 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
2414 */
2416 SCIP* scip, /**< SCIP data structure */
2417 SCIP_CONS** cons, /**< pointer to hold the created constraint */
2418 const char* name, /**< name of constraint */
2419 SCIP_VAR** vars1, /**< first column of matrix of variables on which the symmetry acts */
2420 SCIP_VAR** vars2, /**< second column of matrix of variables on which the symmetry acts */
2421 int nrows, /**< number of rows in constraint matrix */
2422 SCIP_Bool ispporbisack, /**< whether the orbisack is a packing/partitioning orbisack */
2423 SCIP_Bool isparttype, /**< whether the orbisack is a partitioning orbisack */
2424 SCIP_Bool ismodelcons /**< whether the orbisack is a model constraint */
2425 )
2426{
2427 SCIP_CALL( SCIPcreateConsOrbisack(scip, cons, name, vars1, vars2, nrows, ispporbisack, isparttype, ismodelcons,
2429
2430 return SCIP_OKAY;
2431}
static SCIP_RETCODE initLP(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
#define CONSHDLR_NEEDSCONS
Definition: cons_orbisack.c:89
#define CONSHDLR_SEPAFREQ
Definition: cons_orbisack.c:82
#define FIXED0
static SCIP_DECL_CONSENFOLP(consEnfolpOrbisack)
#define CONSHDLR_CHECKPRIORITY
Definition: cons_orbisack.c:81
static SCIP_DECL_CONSDELETE(consDeleteOrbisack)
#define CONSHDLR_DESC
Definition: cons_orbisack.c:78
static SCIP_DECL_CONSINITLP(consInitlpOrbisack)
#define DEFAULT_ORBISEPARATION
Definition: cons_orbisack.c:95
#define CONSHDLR_PROP_TIMING
Definition: cons_orbisack.c:91
static SCIP_DECL_CONSSEPASOL(consSepasolOrbisack)
#define DEFAULT_FORCECONSCOPY
#define CONSHDLR_MAXPREROUNDS
Definition: cons_orbisack.c:86
static SCIP_DECL_CONSLOCK(consLockOrbisack)
static SCIP_DECL_CONSRESPROP(consRespropOrbisack)
#define CONSHDLR_SEPAPRIORITY
Definition: cons_orbisack.c:79
static SCIP_DECL_CONSPROP(consPropOrbisack)
static SCIP_DECL_CONSPARSE(consParseOrbisack)
static SCIP_DECL_CONSSEPALP(consSepalpOrbisack)
static SCIP_DECL_CONSEXITPRE(consExitpreOrbisack)
static SCIP_RETCODE replaceAggregatedVarsOrbisack(SCIP *scip, SCIP_CONS *cons)
#define UNFIXED
#define DEFAULT_PPORBISACK
static SCIP_DECL_CONSGETNVARS(consGetNVarsOrbisack)
static SCIP_RETCODE separateOrbisackCovers(SCIP *scip, SCIP_CONS *cons, int nrows, SCIP_VAR *const *vars1, SCIP_VAR *const *vars2, SCIP_Real *vals1, SCIP_Real *vals2, int *ngen, SCIP_Bool *infeasible)
#define DEFAULT_COVERSEPARATION
Definition: cons_orbisack.c:96
static SCIP_RETCODE addOrbisackCover(SCIP *scip, SCIP_CONS *cons, int nrows, SCIP_VAR *const *vars1, SCIP_VAR *const *vars2, SCIP_Real *coeffs1, SCIP_Real *coeffs2, SCIP_Real rhs, SCIP_Bool *infeasible)
static SCIP_DECL_CONSTRANS(consTransOrbisack)
static SCIP_RETCODE separateInequalities(SCIP *scip, SCIP_RESULT *result, SCIP_CONS *cons, int nrows, SCIP_VAR *const *vars1, SCIP_VAR *const *vars2, SCIP_Real *vals1, SCIP_Real *vals2)
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyOrbisack)
static SCIP_DECL_CONSCHECK(consCheckOrbisack)
static SCIP_DECL_CONSPRESOL(consPresolOrbisack)
static SCIP_DECL_CONSFREE(consFreeOrbisack)
static SCIP_DECL_CONSCOPY(consCopyOrbisack)
static SCIP_DECL_CONSENFORELAX(consEnforelaxOrbisack)
static SCIP_RETCODE addOrbisackInequality(SCIP *scip, SCIP_CONS *cons, int nrows, SCIP_VAR *const *vars1, SCIP_VAR *const *vars2, SCIP_Real *coeffs1, SCIP_Real *coeffs2, SCIP_Real rhs, SCIP_Bool *infeasible)
#define CONSHDLR_PROPFREQ
Definition: cons_orbisack.c:83
static SCIP_DECL_CONSPRINT(consPrintOrbisack)
static SCIP_DECL_CONSENFOPS(consEnfopsOrbisack)
#define CONSHDLR_PRESOLTIMING
Definition: cons_orbisack.c:92
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
static SCIP_DECL_CONSINITSOL(consInitsolOrbisack)
static SCIP_RETCODE packingUpgrade(SCIP *scip, SCIP_VAR *const *vars1, SCIP_VAR *const *vars2, int nrows, SCIP_Bool *success, SCIP_Bool *isparttype)
#define CONSHDLR_EAGERFREQ
Definition: cons_orbisack.c:84
static SCIP_RETCODE separateOrbisack(SCIP *scip, SCIP_CONS *cons, int nrows, SCIP_VAR *const *vars1, SCIP_VAR *const *vars2, SCIP_Real *vals1, SCIP_Real *vals2, SCIP_Bool coverseparation, SCIP_Real coeffbound, int *ngen, SCIP_Bool *infeasible)
#define CONSHDLR_ENFOPRIORITY
Definition: cons_orbisack.c:80
static SCIP_DECL_CONSGETVARS(consGetVarsOrbisack)
static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, SCIP_VAR *const *vars1, SCIP_VAR *const *vars2, int nrows, SCIP_Bool ismodelcons)
#define FIXED1
#define CONSHDLR_DELAYSEPA
Definition: cons_orbisack.c:87
static SCIP_RETCODE checkFeasible(SCIP *scip, SCIP_VAR **vars1, SCIP_VAR **vars2, int nrows, int start, SCIP_Bool *infeasible, int *infeasiblerow)
#define CONSHDLR_NAME
Definition: cons_orbisack.c:77
#define DEFAULT_COEFFBOUND
Definition: cons_orbisack.c:99
#define CONSHDLR_DELAYPROP
Definition: cons_orbisack.c:88
static SCIP_RETCODE propVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible, SCIP_Bool *found, int *ngen)
constraint handler for orbisack constraints
SCIP_RETCODE SCIPcreateConsOrbitope(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR ***vars, SCIP_ORBITOPETYPE orbitopetype, int nrows, int ncols, SCIP_Bool resolveprop, SCIP_Bool ismodelcons, SCIP_Bool checkpporbitope, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
interface for constraint handlers of type partitioning, packing, and full
Constraint handler for the set partitioning / packing / covering constraints .
#define NULL
Definition: def.h:248
#define SCIP_UNUSED(x)
Definition: def.h:409
#define SCIP_Bool
Definition: def.h:91
#define SCIP_Real
Definition: def.h:156
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIP_CALL(x)
Definition: def.h:355
SCIP_RETCODE SCIPcheckSolutionOrbisack(SCIP *scip, SCIP_SOL *sol, SCIP_VAR **vars1, SCIP_VAR **vars2, int nrows, SCIP_Bool printreason, SCIP_Bool *feasible)
SCIP_RETCODE SCIPcreateConsBasicOrbisack(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR **vars1, SCIP_VAR **vars2, int nrows, SCIP_Bool ispporbisack, SCIP_Bool isparttype, SCIP_Bool ismodelcons)
SCIP_RETCODE SCIPcreateConsOrbisack(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *const *vars1, SCIP_VAR *const *vars2, int nrows, SCIP_Bool ispporbisack, SCIP_Bool isparttype, SCIP_Bool ismodelcons, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPincludeConshdlrOrbisack(SCIP *scip)
SCIP_RETCODE SCIPgetVarCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_VAR *sourcevar, SCIP_VAR **targetvar, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, SCIP_Bool *success)
Definition: scip_copy.c:713
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip_general.c:647
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
#define SCIPdebugMsg
Definition: scip_message.h:78
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 SCIPgetNLPBranchCands(SCIP *scip)
Definition: scip_branch.c:436
SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
SCIP_RETCODE SCIPaddConflictUb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
SCIP_RETCODE SCIPaddConflictBinvar(SCIP *scip, SCIP_VAR *var)
SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip_cons.c:808
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip_cons.c:540
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
Definition: scip_cons.c:831
SCIP_RETCODE SCIPsetConshdlrSepa(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSSEPALP((*conssepalp)), SCIP_DECL_CONSSEPASOL((*conssepasol)), int sepafreq, int sepapriority, SCIP_Bool delaysepa)
Definition: scip_cons.c:235
SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
Definition: scip_cons.c:281
SCIP_RETCODE SCIPincludeConshdlrBasic(SCIP *scip, SCIP_CONSHDLR **conshdlrptr, const char *name, const char *desc, int enfopriority, int chckpriority, int eagerfreq, SCIP_Bool needscons, SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_CONSHDLRDATA *conshdlrdata)
Definition: scip_cons.c:181
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip_cons.c:578
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip_cons.c:372
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
Definition: scip_cons.c:323
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4316
SCIP_RETCODE SCIPsetConshdlrExitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITPRE((*consexitpre)))
Definition: scip_cons.c:516
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip_cons.c:347
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:940
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip_cons.c:624
SCIP_RETCODE SCIPsetConshdlrInitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITSOL((*consinitsol)))
Definition: scip_cons.c:444
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4336
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip_cons.c:601
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
Definition: scip_cons.c:647
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
Definition: scip_cons.c:854
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip_cons.c:785
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:8419
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8648
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8409
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8558
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8588
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8578
SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: scip_cons.c:997
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8608
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8628
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8389
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8638
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:8668
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8568
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8658
SCIP_Bool SCIPisEfficacious(SCIP *scip, SCIP_Real efficacy)
Definition: scip_cut.c:135
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition: scip_cut.c:225
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:139
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:128
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:108
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:111
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:89
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:105
SCIP_RETCODE SCIPcacheRowExtensions(SCIP *scip, SCIP_ROW *row)
Definition: scip_lp.c:1581
SCIP_RETCODE SCIPcreateEmptyRowCons(SCIP *scip, SCIP_ROW **row, SCIP_CONS *cons, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
Definition: scip_lp.c:1398
SCIP_RETCODE SCIPflushRowExtensions(SCIP *scip, SCIP_ROW *row)
Definition: scip_lp.c:1604
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 SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_sol.c:1846
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1765
SCIP_RETCODE SCIPisPackingPartitioningOrbitope(SCIP *scip, SCIP_VAR ***vars, int nrows, int ncols, SCIP_Bool **pprows, int *npprows, SCIP_ORBITOPETYPE *type)
Definition: symmetry.c:1193
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:23642
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:23478
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:23386
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:24268
SCIP_RETCODE SCIPinferVarUbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:7069
SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
Definition: scip_var.c:728
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:5118
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2872
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1887
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:24234
SCIP_RETCODE SCIPmarkDoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:11057
SCIP_RETCODE SCIPinferVarLbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:6964
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2736
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition: scip_var.c:361
SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
Definition: scip_var.c:2236
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:2078
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1853
SCIP_RETCODE SCIPskipSpace(char **s)
Definition: misc.c:10816
memory allocation routines
public methods for managing constraints
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
public methods for problem variables
SCIP callable library.
public methods for branching rule plugins and branching
public methods for conflict handler plugins and conflict analysis
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 solutions
public methods for SCIP variables
static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
Main separation function.
Definition: sepa_flower.c:1221
methods for handling symmetries
@ SCIP_CONFTYPE_PROPAGATION
Definition: type_conflict.h:62
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:64
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:65
@ SCIP_BOUNDTYPE_LOWER
Definition: type_lp.h:57
@ SCIP_DIDNOTRUN
Definition: type_result.h:42
@ SCIP_CUTOFF
Definition: type_result.h:48
@ SCIP_FEASIBLE
Definition: type_result.h:45
@ SCIP_REDUCEDDOM
Definition: type_result.h:51
@ SCIP_DIDNOTFIND
Definition: type_result.h:44
@ SCIP_SEPARATED
Definition: type_result.h:49
@ SCIP_SUCCESS
Definition: type_result.h:58
@ SCIP_INFEASIBLE
Definition: type_result.h:46
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:61
@ SCIP_PLUGINNOTFOUND
Definition: type_retcode.h:54
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_ORBITOPETYPE_PACKING
@ SCIP_ORBITOPETYPE_PARTITIONING
enum SCIP_OrbitopeType SCIP_ORBITOPETYPE
@ SCIP_VARSTATUS_FIXED
Definition: type_var.h:54
@ SCIP_VARSTATUS_MULTAGGR
Definition: type_var.h:56
@ SCIP_VARSTATUS_NEGATED
Definition: type_var.h:57