SCIP Doxygen Documentation
Loading...
Searching...
No Matches
cons_lop.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/* uncomment for debug output: */
26/* #define SCIP_DEBUG */
27
28/**@file cons_lop.c
29 * @brief constraint handler for linear ordering constraints
30 * @author Marc Pfetsch
31 *
32 * We handle the following system of linear constraints:
33 * - \f$ x_{ij} + x_{ji} = 1 \f$ for \f$i < j\f$ (symmetry equations - added initially)
34 * - \f$ x_{ij} + x_{jk} + x_{ki} \leq 2 \f$ for \f$i < j, i < k, j \neq k\f$ (triangle inequalities - separated)
35 */
36
37/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
38
39#include "cons_lop.h"
40
41
42/* constraint handler properties */
43#define CONSHDLR_NAME "lop"
44#define CONSHDLR_DESC "linear ordering constraint handler"
45#define CONSHDLR_SEPAPRIORITY 100 /**< priority of the constraint handler for separation */
46#define CONSHDLR_ENFOPRIORITY -100 /**< priority of the constraint handler for constraint enforcing */
47#define CONSHDLR_CHECKPRIORITY -100 /**< priority of the constraint handler for checking feasibility */
48#define CONSHDLR_SEPAFREQ 1 /**< frequency for separating cuts; zero means to separate only in the root node */
49#define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
50#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
51 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
52#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
53#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
54#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
55
56#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
57
58
59/** constraint data for linear ordering constraints */
60struct SCIP_ConsData
61{
62 int n; /**< number of elements */
63 SCIP_VAR*** vars; /**< variables */
64};
65
66
67/** separate symmetry equations and triangle inequalities */
68static
70 SCIP* scip, /**< SCIP pointer */
71 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
72 int n, /**< number of elements */
73 SCIP_VAR*** vars, /**< n x n matrix of variables */
74 SCIP_SOL* sol, /**< solution to be separated */
75 int* ngen, /**< output: pointer to store number of added rows */
76 SCIP_Bool* cutoff /**< output: pointer to store whether we detected a cutoff */
77 )
78{
79 char s[SCIP_MAXSTRLEN];
80 int i;
81 int j;
82 int k;
83
84 assert( scip != NULL );
85 assert( vars != NULL );
86 assert( ngen != NULL );
87 assert( cutoff != NULL );
88
89 /* Consider all (i,j,k) with i < j, i < k, j != k; since the inequalities are symmetric under cyclic shifts, we can
90 * assume i to be the smallest index. */
91 *cutoff = FALSE;
92 for (i = 0; i < n && ! (*cutoff); ++i)
93 {
94 for (j = i+1; j < n && ! (*cutoff); ++j)
95 {
96 SCIP_Real valIJ;
97
98 valIJ = SCIPgetSolVal(scip, sol, vars[i][j]);
99
100 /* if symmetry equations are violated - should not be the case, if they are added in the beginning */
101 if ( ! SCIPisFeasEQ(scip, valIJ + SCIPgetSolVal(scip, sol, vars[j][i]), 1.0) )
102 {
103 SCIP_ROW *row;
104
105 (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "sym#%d#%d", i, j);
106
107 SCIP_CALL( SCIPcreateEmptyRowConshdlr(scip, &row, conshdlr, s, 1.0, 1.0, FALSE, FALSE, TRUE) );
109 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[i][j], 1.0) );
110 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[j][i], 1.0) );
112#ifdef SCIP_DEBUG
114#endif
117 ++(*ngen);
118
119 if ( *cutoff )
120 break;
121 }
122
123 /* check triangle inequalities */
124 for (k = i+1; k < n; ++k)
125 {
126 SCIP_Real sum;
127
128 if ( k == j )
129 continue;
130
131 sum = valIJ + SCIPgetSolVal(scip, sol, vars[j][k]) + SCIPgetSolVal(scip, sol, vars[k][i]);
132
133 /* if sum - 2.0 > 0, i.e., the cut is violated */
134 if ( SCIPisEfficacious(scip, sum - 2.0) )
135 {
136 SCIP_ROW *row;
137
138 (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "triangle#%d#%d#%d", i, j, k);
139
140 SCIP_CALL( SCIPcreateEmptyRowConshdlr(scip, &row, conshdlr, s, -SCIPinfinity(scip), 2.0, FALSE, FALSE, TRUE) );
142 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[i][j], 1.0) );
143 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[j][k], 1.0) );
144 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[k][i], 1.0) );
146#ifdef SCIP_DEBUG
148#endif
151 ++(*ngen);
152
153 if ( *cutoff )
154 break;
155 }
156 }
157 }
158 }
159
160 return SCIP_OKAY;
161}
162
163
164/** copy method for constraint handler plugins (called when SCIP copies plugins) */
165static
167{ /*lint --e{715}*/
168 assert( scip != NULL );
169 assert( conshdlr != NULL );
170 assert( valid != NULL );
171
173
174 /* call inclusion method of constraint handler */
176
177 *valid = TRUE;
178
179 return SCIP_OKAY;
180}
181
182/** frees specific constraint data */
183static
185{ /*lint --e{715}*/
186 int i;
187 int n;
188
189 assert( scip != NULL );
190 assert( conshdlr != NULL );
191 assert( cons != NULL );
192 assert( consdata != NULL);
193 assert( *consdata != NULL);
194 assert( (*consdata)->vars != NULL );
195
197
198 SCIPdebugMsg(scip, "deleting linear ordering constraint <%s>.\n", SCIPconsGetName(cons));
199
200 n = (*consdata)->n;
201 for (i = 0; i < n; ++i)
202 SCIPfreeBlockMemoryArray(scip, &((*consdata)->vars[i]), n); /*lint !e866*/
203 SCIPfreeBlockMemoryArray(scip, &((*consdata)->vars), n);
204 SCIPfreeBlockMemory(scip, consdata);
205
206 return SCIP_OKAY;
207}
208
209/** deinitialization method of constraint handler (called before transformed problem is freed)
210 *
211 * We output the final linear ordering.
212 */
213static
215{ /*lint --e{715}*/
216 SCIP_SOL* sol;
217 int c;
218 int i;
219 int j;
220 int n;
221
222 assert( scip != NULL );
223 assert( conshdlr != NULL );
224
226
227 SCIPdebugMsg(scip, "exiting linear ordering constraint handler <%s>.\n", SCIPconshdlrGetName(conshdlr));
228
229 /* avoid output for subscips */
230 if ( SCIPgetSubscipDepth(scip) > 0 )
231 return SCIP_OKAY;
232
233 /* get best solution */
235 if ( sol == NULL )
236 return SCIP_OKAY;
237
238 /* loop through all constraints */
239 for (c = 0; c < nconss; ++c)
240 {
241 SCIP_CONSDATA* consdata;
242 SCIP_VAR*** vars;
243 int* outdeg;
244 int* indices;
245
246 assert( conss != NULL );
247 assert( conss[c] != NULL );
248 SCIPdebugMsg(scip, "solution for for linear ordering constraint <%s>.\n", SCIPconsGetName(conss[c]));
249
250 consdata = SCIPconsGetData(conss[c]);
251 assert( consdata != NULL );
252 assert( consdata->vars != NULL );
253 n = consdata->n;
254 vars = consdata->vars;
255
256 SCIP_CALL( SCIPallocBufferArray(scip, &outdeg, n) );
257 SCIP_CALL( SCIPallocBufferArray(scip, &indices, n) );
258
259 /* compute out-degree */
260 for (i = 0; i < n; ++i)
261 {
262 int deg = 0;
263 for (j = 0; j < n; ++j)
264 {
265 SCIP_Real val;
266
267 if (j == i)
268 continue;
269
270 val = SCIPgetSolVal(scip, sol, vars[i][j]);
272 if ( val < 0.5 )
273 ++deg;
274 }
275 outdeg[i] = deg;
276 indices[i] = i;
277 }
278
279 /* sort such that degrees are non-decreasing */
280 SCIPsortIntInt(outdeg, indices, n);
281
282 /* output */
283 SCIPinfoMessage(scip, NULL, "\nFinal order of linear ordering constraint <%s>:\n", SCIPconsGetName(conss[c]));
284 for (i = 0; i < n; ++i)
285 SCIPinfoMessage(scip, NULL, "%d ", indices[i]);
286 SCIPinfoMessage(scip, NULL, "\n");
287
288 SCIPfreeBufferArray(scip, &indices);
289 SCIPfreeBufferArray(scip, &outdeg);
290 }
291
292 return SCIP_OKAY;
293}
294
295/** transforms constraint data into data belonging to the transformed problem */
296static
298{ /*lint --e{715}*/
299 SCIP_CONSDATA* consdata;
300 SCIP_CONSDATA* sourcedata;
301 int i;
302 int j;
303 int n;
304 char s[SCIP_MAXSTRLEN];
305
306 assert( scip != NULL );
307 assert( conshdlr != NULL );
308 assert( sourcecons != NULL );
309 assert( targetcons != NULL );
310
312
313 SCIPdebugMsg(scip, "transforming linear ordering constraint <%s>.\n", SCIPconsGetName(sourcecons) );
314
315 /* get data of original constraint */
316 sourcedata = SCIPconsGetData(sourcecons);
317 assert( sourcedata != NULL);
318
319 /* create constraint data */
320 SCIP_CALL( SCIPallocBlockMemory(scip, &consdata) );
321
322 n = sourcedata->n;
323 consdata->n = n;
324
325 /* transform variables */
326 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->vars, n) );
327 for (i = 0; i < n; ++i)
328 {
329 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(consdata->vars[i]), n) ); /*lint !e866*/
330 for (j = 0; j < n; ++j)
331 {
332 if (j != i)
333 {
334 assert( sourcedata->vars[i][j] != NULL );
335 SCIP_CALL( SCIPgetTransformedVar(scip, sourcedata->vars[i][j], &(consdata->vars[i][j])) );
336 }
337 }
338 }
339
340 /* create constraint */
341 (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "t_%s", SCIPconsGetName(sourcecons));
342
343 SCIP_CALL( SCIPcreateCons(scip, targetcons, s, conshdlr, consdata,
344 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons),
345 SCIPconsIsEnforced(sourcecons), SCIPconsIsChecked(sourcecons),
346 SCIPconsIsPropagated(sourcecons), SCIPconsIsLocal(sourcecons),
347 SCIPconsIsModifiable(sourcecons), SCIPconsIsDynamic(sourcecons),
348 SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
349
350 return SCIP_OKAY;
351}
352
353/** LP initialization method of constraint handler */
354static
356{ /*lint --e{715}*/
357 char s[SCIP_MAXSTRLEN];
358 int c;
359 int ngen = 0;
360
361 assert( scip != NULL );
362 assert( conshdlr != NULL );
363 assert( infeasible != NULL );
364
366
367 *infeasible = FALSE;
368
369 /* loop through all constraints */
370 for (c = 0; c < nconss; ++c)
371 {
372 SCIP_CONSDATA* consdata;
373 SCIP_VAR*** vars;
374 int i;
375 int j;
376 int n;
377
378 assert( conss != NULL );
379 assert( conss[c] != NULL );
380 SCIPdebugMsg(scip, "adding initial rows for linear ordering constraint <%s>.\n", SCIPconsGetName(conss[c]));
381
382 consdata = SCIPconsGetData(conss[c]);
383 assert( consdata != NULL );
384 assert( consdata->vars != NULL );
385 n = consdata->n;
386 vars = consdata->vars;
387
388 /* add symmetry equation */
389 for (i = 0; i < n; ++i)
390 {
391 for (j = i+1; j < n; ++j)
392 {
393 SCIP_ROW* row;
394
395 (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "sym#%d#%d", i, j);
396 SCIP_CALL( SCIPcreateEmptyRowConshdlr(scip, &row, conshdlr, s, 1.0, 1.0, FALSE, FALSE, FALSE) );
398 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[i][j], 1.0) );
399 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[j][i], 1.0) );
401#ifdef SCIP_DEBUG
403#endif
404 SCIP_CALL( SCIPaddRow(scip, row, FALSE, infeasible) );
406 ++ngen;
407
408 /* cannot handle infeasible case here - just exit */
409 if ( *infeasible )
410 return SCIP_OKAY;
411 }
412 }
413 }
414 SCIPdebugMsg(scip, "added %d equations.\n", ngen);
415
416 return SCIP_OKAY;
417}
418
419/** separation method of constraint handler for LP solutions */
420static
422{ /*lint --e{715}*/
423 int ngen = 0;
424 int c;
425
426 assert( scip != NULL );
427 assert( conshdlr != NULL );
428 assert( conss != NULL );
429 assert( result != NULL );
430
432
434
435 /* loop through all constraints */
436 for (c = 0; c < nconss; ++c)
437 {
438 SCIP_CONSDATA* consdata;
439 SCIP_CONS* cons;
441
442 cons = conss[c];
443 assert( cons != NULL );
444 SCIPdebugMsg(scip, "separating LP solution for linear ordering constraint <%s>.\n", SCIPconsGetName(cons));
445
446 consdata = SCIPconsGetData(cons);
447 assert( consdata != NULL );
448
450 SCIP_CALL( LOPseparate(scip, conshdlr, consdata->n, consdata->vars, NULL, &ngen, &cutoff) );
451 if ( cutoff )
452 {
454 return SCIP_OKAY;
455 }
456 }
457 if ( ngen > 0 )
459 SCIPdebugMsg(scip, "separated %d cuts.\n", ngen);
460
461 return SCIP_OKAY;
462}
463
464/** separation method of constraint handler for arbitrary primal solutions */
465static
467{ /*lint --e{715}*/
468 int ngen = 0;
469 int c;
470
471 assert( scip != NULL );
472 assert( conshdlr != NULL );
473 assert( conss != NULL );
474 assert( result != NULL );
475
477
479
480 /* loop through all constraints */
481 for (c = 0; c < nconss; ++c)
482 {
483 SCIP_CONSDATA* consdata;
484 SCIP_CONS* cons;
486
487 cons = conss[c];
488 assert( cons != NULL );
489 SCIPdebugMsg(scip, "separating solution for linear ordering constraint <%s>.\n", SCIPconsGetName(cons));
490
491 consdata = SCIPconsGetData(cons);
492 assert( consdata != NULL );
493
495 SCIP_CALL( LOPseparate(scip, conshdlr, consdata->n, consdata->vars, sol, &ngen, &cutoff) );
496 if ( cutoff )
497 {
499 return SCIP_OKAY;
500 }
501 }
502 if ( ngen > 0 )
504
505 return SCIP_OKAY;
506}
507
508/** constraint enforcing method of constraint handler for LP solutions */
509static
511{ /*lint --e{715}*/
512 char s[SCIP_MAXSTRLEN];
513 int ngen = 0;
514 int c;
515
516 assert( scip != NULL );
517 assert( conshdlr != NULL );
518 assert( conss != NULL );
519 assert( result != NULL );
520
522
524
525 /* loop through all constraints */
526 for (c = 0; c < nconss; ++c)
527 {
528 SCIP_CONSDATA* consdata;
529 SCIP_CONS* cons;
530 SCIP_VAR*** vars;
531 int i;
532 int j;
533 int k;
534 int n;
535
536 cons = conss[c];
537 assert( cons != NULL );
538 SCIPdebugMsg(scip, "enforcing lp solution for linear ordering constraint <%s>.\n", SCIPconsGetName(cons));
539
540 consdata = SCIPconsGetData(cons);
541 assert( consdata != NULL );
542
543 n = consdata->n;
544 vars = consdata->vars;
545 assert( vars != NULL );
546
547 for (i = 0; i < n; ++i)
548 {
549 for (j = i + 1; j < n; ++j)
550 {
551 SCIP_Real valIJ;
552
553 valIJ = SCIPgetSolVal(scip, NULL, vars[i][j]);
554
555 /* if symmetry equations are violated - should not be the case, if they are added in the beginning */
556 if ( ! SCIPisFeasEQ(scip, 1.0 - valIJ, SCIPgetSolVal(scip, NULL, vars[j][i])) )
557 {
558 SCIP_ROW *row;
559 SCIP_Bool infeasible;
560
561 (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "sym#%d#%d", i, j);
562
563 SCIP_CALL( SCIPcreateEmptyRowConshdlr(scip, &row, conshdlr, s, 1.0, 1.0, FALSE, FALSE, TRUE) );
565 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[i][j], 1.0) );
566 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[j][i], 1.0) );
568#ifdef SCIP_DEBUG
570#endif
571 SCIP_CALL( SCIPaddRow(scip, row, FALSE, &infeasible) );
573 ++ngen;
574
575 if ( infeasible )
576 {
578 return SCIP_OKAY;
579 }
580 }
581
582 /* enforce triangle inequalities */
583 for (k = i + 1; k < n; ++k)
584 {
585 SCIP_Real sum;
586
587 if ( k == j )
588 continue;
589
590 sum = valIJ + SCIPgetSolVal(scip, NULL, vars[j][k]) + SCIPgetSolVal(scip, NULL, vars[k][i]);
591
592 /* if sum > 2.0, i.e., the cut is violated */
593 if ( SCIPisFeasGT(scip, sum, 2.0) ) /* this is the only difference to the separation call */
594 {
595 SCIP_ROW *row;
596 SCIP_Bool infeasible;
597
598 (void) SCIPsnprintf(s, SCIP_MAXSTRLEN, "triangle#%d#%d#%d", i, j, k);
599
600 SCIP_CALL( SCIPcreateEmptyRowConshdlr(scip, &row, conshdlr, s, -SCIPinfinity(scip), 2.0, FALSE, FALSE, TRUE) );
602 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[i][j], 1.0) );
603 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[j][k], 1.0) );
604 SCIP_CALL( SCIPaddVarToRow(scip, row, vars[k][i], 1.0) );
606#ifdef SCIP_DEBUG
608#endif
609 SCIP_CALL( SCIPaddRow(scip, row, FALSE, &infeasible) );
611 ++ngen;
612
613 if ( infeasible )
614 {
616 return SCIP_OKAY;
617 }
618 }
619 }
620 }
621 }
622
623 if ( ngen > 0 )
624 {
626 return SCIP_OKAY;
627 }
628
629 }
630 SCIPdebugMsg(scip, "all linear ordering constraints are feasible.\n");
632
633 return SCIP_OKAY;
634}
635
636/** constraint enforcing method of constraint handler for pseudo solutions */
637static
639{ /*lint --e{715}*/
640 int c;
641
642 assert( scip != NULL );
643 assert( conshdlr != NULL );
644 assert( conss != NULL );
645 assert( result != NULL );
646
648
649 /* loop through all constraints */
650 for (c = 0; c < nconss; ++c)
651 {
652 SCIP_CONSDATA* consdata;
653 SCIP_CONS* cons;
654 SCIP_VAR*** vars;
655 int i;
656 int j;
657 int k;
658 int n;
659
660 cons = conss[c];
661 assert( cons != NULL );
662 SCIPdebugMsg(scip, "enforcing pseudo solution for linear ordering constraint <%s>.\n", SCIPconsGetName(cons));
663
664 consdata = SCIPconsGetData(cons);
665 assert( consdata != NULL );
666 assert( consdata->vars != NULL );
667 vars = consdata->vars;
668 n = consdata->n;
669
670 /* check triangle inequalities */
671 for (i = 0; i < n; ++i)
672 {
673 for (j = i + 1; j < n; ++j)
674 {
675 SCIP_Bool oneIJ;
676 SCIP_Bool oneJI;
677
678 /* the priorities should ensure that the solution is integral */
681
682 oneIJ = SCIPgetSolVal(scip, NULL, vars[i][j]) > 0.5 ? TRUE : FALSE;
683 oneJI = SCIPgetSolVal(scip, NULL, vars[j][i]) > 0.5 ? TRUE : FALSE;
684
685 if ( oneIJ == oneJI )
686 {
687 SCIPdebugMsg(scip, "constraint <%s> infeasible (violated equation).\n", SCIPconsGetName(cons));
689 return SCIP_OKAY;
690 }
691
692 for (k = i + 1; k < n; ++k)
693 {
694 SCIP_Bool oneJK;
695 SCIP_Bool oneKI;
696
697 if ( k == j )
698 continue;
699
702
703 oneJK = SCIPgetSolVal(scip, NULL, vars[j][k]) > 0.5 ? TRUE : FALSE;
704 oneKI = SCIPgetSolVal(scip, NULL, vars[k][i]) > 0.5 ? TRUE : FALSE;
705
706 /* if triangle inequality is violated */
707 if ( oneIJ && oneJK && oneKI )
708 {
709 SCIPdebugMsg(scip, "constraint <%s> infeasible (violated triangle ineq.).\n", SCIPconsGetName(cons));
711 return SCIP_OKAY;
712 }
713 }
714 }
715 }
716 }
717 SCIPdebugMsg(scip, "all linear ordering constraints are feasible.\n");
719
720 return SCIP_OKAY;
721}
722
723/** feasibility check method of constraint handler for integral solutions */
724static
726{ /*lint --e{715}*/
727 int c;
728
729 assert( scip != NULL );
730 assert( conshdlr != NULL );
731 assert( conss != NULL );
732 assert( result != NULL );
733
735
736 /* loop through all constraints */
737 for (c = 0; c < nconss; ++c)
738 {
739 SCIP_CONSDATA* consdata;
740 SCIP_CONS* cons;
741 SCIP_VAR*** vars;
742 int i;
743 int j;
744 int k;
745 int n;
746
747 cons = conss[c];
748 assert( cons != NULL );
749 SCIPdebugMsg(scip, "checking linear ordering constraint <%s>.\n", SCIPconsGetName(cons));
750
751 consdata = SCIPconsGetData(cons);
752 assert( consdata != NULL );
753 assert( consdata->vars != NULL );
754 vars = consdata->vars;
755 n = consdata->n;
756
757 /* check triangle inequalities and symmetry equations */
758 for (i = 0; i < n; ++i)
759 {
760 for (j = i + 1; j < n; ++j)
761 {
762 SCIP_Bool oneIJ;
763 SCIP_Bool oneJI;
764
765 /* the priorities should ensure that the solution is integral */
768
769 oneIJ = SCIPgetSolVal(scip, sol, vars[i][j]) > 0.5 ? TRUE : FALSE;
770 oneJI = SCIPgetSolVal(scip, sol, vars[j][i]) > 0.5 ? TRUE : FALSE;
771
772 /* check symmetry equations */
773 if ( oneIJ == oneJI )
774 {
775 SCIPdebugMsg(scip, "constraint <%s> infeasible (violated equation).\n", SCIPconsGetName(cons));
777 if( printreason )
778 {
779 SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
780 SCIPinfoMessage(scip, NULL, "violation: symmetry equation violated <%s> = %.15g and <%s> = %.15g\n",
783 }
784 return SCIP_OKAY;
785 }
786
787 for (k = i + 1; k < n; ++k)
788 {
789 SCIP_Bool oneJK;
790 SCIP_Bool oneKI;
791
792 if ( k == j )
793 continue;
794
797
798 oneJK = SCIPisGT(scip, SCIPgetSolVal(scip, sol, vars[j][k]), 0.5);
799 oneKI = SCIPisGT(scip, SCIPgetSolVal(scip, sol, vars[k][i]), 0.5);
800
801 /* if triangle inequality is violated */
802 if ( oneIJ && oneJK && oneKI )
803 {
804 SCIPdebugMsg(scip, "constraint <%s> infeasible (violated triangle ineq.).\n", SCIPconsGetName(cons));
806 if( printreason )
807 {
808 SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
810 "violation: triangle inequality violated <%s> = %.15g, <%s> = %.15g, <%s> = %.15g\n",
812 SCIPvarGetName(vars[j][k]), SCIPgetSolVal(scip, sol, vars[j][k]),
814 }
815 return SCIP_OKAY;
816 }
817 }
818 }
819 }
820 }
821 SCIPdebugMsg(scip, "all linear ordering constraints are feasible.\n");
823
824 return SCIP_OKAY;
825}
826
827/** domain propagation method of constraint handler */
828static
830{ /*lint --e{715}*/
831 int c;
832 int ngen = 0;
833
834 assert( scip != NULL );
835 assert( conshdlr != NULL );
836 assert( conss != NULL );
837 assert( result != NULL );
838
840
842
843 /* loop through all constraints */
844 for (c = 0; c < nconss; ++c)
845 {
846 SCIP_CONSDATA* consdata;
847 SCIP_CONS* cons;
848 SCIP_VAR*** vars;
849 int i;
850 int j;
851 int k;
852 int n;
853
854 cons = conss[c];
855 assert( cons != NULL );
856 SCIPdebugMsg(scip, "propagating linear ordering constraint <%s>.\n", SCIPconsGetName(cons));
857
859
860 consdata = SCIPconsGetData(cons);
861 assert( consdata != NULL );
862 assert( consdata->vars != NULL );
863
864 vars = consdata->vars;
865 n = consdata->n;
866
867 /* check triangle inequalities */
868 for (i = 0; i < n; ++i)
869 {
870 for (j = i + 1; j < n; ++j)
871 {
872 SCIP_Bool infeasible;
873 SCIP_Bool tightened;
874
875 /* for consistency make sure that the complementarity constraints are satisfied */
876
877 /* if x[i][j] == 1 then x[j][i] = 0 */
878 if ( SCIPvarGetLbLocal(vars[i][j]) > 0.5 )
879 {
880 SCIP_CALL( SCIPinferBinvarCons(scip, vars[j][i], FALSE, cons, i*n + j, &infeasible, &tightened) );
881 if ( infeasible )
882 {
883 SCIPdebugMsg(scip, " -> node infeasible.\n");
889 return SCIP_OKAY;
890 }
891 if ( tightened )
892 ++ngen;
893 }
894
895 /* if x[i][j] == 0 then x[j][i] = 1 */
896 if ( SCIPvarGetUbLocal(vars[i][j]) < 0.5 )
897 {
898 SCIP_CALL( SCIPinferBinvarCons(scip, vars[j][i], TRUE, cons, i*n + j, &infeasible, &tightened) );
899 if ( infeasible )
900 {
901 SCIPdebugMsg(scip, " -> node infeasible.\n");
907 return SCIP_OKAY;
908 }
909 if ( tightened )
910 ++ngen;
911 }
912
913 /* check whether triangle inequality allows to fix variables */
914 for (k = i + 1; k < n; ++k)
915 {
916 if ( k == j )
917 continue;
918
919 if ( SCIPvarGetLbLocal(vars[i][j]) > 0.5 )
920 {
921 if ( SCIPvarGetLbLocal(vars[j][k]) > 0.5 )
922 {
923 /* if x[i][j] == 1 and x[j][k] == 1 then x[k][i] = 0 */
924 SCIP_CALL( SCIPinferBinvarCons(scip, vars[k][i], FALSE, cons, n*n + i*n*n + j*n + k, &infeasible, &tightened) );
925 if ( infeasible )
926 {
927 SCIPdebugMsg(scip, " -> node infeasible.\n");
934 return SCIP_OKAY;
935 }
936 if ( tightened )
937 ++ngen;
938 }
939
940 if ( SCIPvarGetLbLocal(vars[k][i]) > 0.5 )
941 {
942 /* if x[k][i] == 1 and x[i][j] = 1 then x[j][k] = 0 */
943 SCIP_CALL( SCIPinferBinvarCons(scip, vars[j][k], FALSE, cons, n*n + i*n*n + j*n + k, &infeasible, &tightened) );
944 if ( infeasible )
945 {
946 SCIPdebugMsg(scip, " -> node infeasible.\n");
953 return SCIP_OKAY;
954 }
955 if ( tightened )
956 ++ngen;
957 }
958 }
959
960 /* if x[j][k] == 1 and x[k][i] == 1 then x[i][j] = 0 */
961 if ( SCIPvarGetLbLocal(vars[j][k]) > 0.5 && SCIPvarGetLbLocal(vars[k][i]) > 0.5 )
962 {
963 SCIP_CALL( SCIPinferBinvarCons(scip, vars[i][j], FALSE, cons, n*n + i*n*n + j*n + k, &infeasible, &tightened) );
964 if ( infeasible )
965 {
966 SCIPdebugMsg(scip, " -> node infeasible.\n");
973 return SCIP_OKAY;
974 }
975 if ( tightened )
976 ++ngen;
977 }
978
979 /* all other implications occur with other indices i, j, k */
980 }
981 }
982 }
983 }
984 SCIPdebugMsg(scip, "propagated %d domains.\n", ngen);
985 if ( ngen > 0 )
987
988 return SCIP_OKAY;
989}
990
991/** propagation conflict resolving method of constraint handler */
992static
994{ /*lint --e{715}*/
995 SCIP_CONSDATA* consdata;
996 SCIP_VAR*** vars;
997 int n;
998 int nsqrd;
999
1000 assert( scip != NULL );
1001 assert( conshdlr != NULL );
1002 assert( cons != NULL );
1003 assert( infervar != NULL );
1004 assert( bdchgidx != NULL );
1005 assert( result != NULL );
1006
1008
1009 SCIPdebugMsg(scip, "Propagation resolution of constraint <%s>.\n", SCIPconsGetName(cons));
1011
1012 consdata = SCIPconsGetData(cons);
1013 assert( consdata != NULL);
1014 assert( consdata->vars != NULL );
1015
1016 n = consdata->n;
1017 nsqrd = n * n;
1018 vars = consdata->vars;
1019
1020 assert( 0 <= inferinfo && inferinfo < n*n + n*n*n );
1021
1022 /* if the conflict came from an equation */
1023 if ( inferinfo < nsqrd )
1024 {
1025 int index1;
1026 int index2;
1027
1028 index1 = inferinfo/n;
1029 index2 = inferinfo % n;
1030 assert( 0 <= index1 && index1 < n );
1031 assert( 0 <= index2 && index2 < n );
1032 assert( vars[index2][index1] == infervar );
1033
1034 /* if the variable was fixed to 0 */
1035 if ( SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, FALSE) > 0.5 && SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5 )
1036 {
1037 SCIPdebugMsg(scip, " -> reason for x[%d][%d] == 0 was x[%d][%d] = 1.\n", index2, index1, index1, index2);
1038 /* the reason was that x[i][j] was fixed to 1 */
1039 SCIP_CALL( SCIPaddConflictLb(scip, vars[index1][index2], bdchgidx) );
1041 return SCIP_OKAY;
1042 }
1043
1044 /* if the variable was fixed to 1 */
1045 if ( SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, FALSE) < 0.5 && SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) > 0.5 )
1046 {
1047 SCIPdebugMsg(scip, " -> reason for x[%d][%d] == 1 was x[%d][%d] = 0.\n", index2, index1, index1, index2);
1048 /* the reason was that x[i][j] was fixed to 0 */
1049 SCIP_CALL( SCIPaddConflictUb(scip, vars[index1][index2], bdchgidx) );
1051 return SCIP_OKAY;
1052 }
1053 }
1054 else
1055 {
1056 /* otherwise the conflict came from a triangle inequality */
1057 int index1;
1058 int index2;
1059 int index3;
1060
1061 index1 = (inferinfo - nsqrd) / nsqrd;
1062 index2 = (inferinfo - nsqrd - index1 * nsqrd) / n;
1063 index3 = (inferinfo - nsqrd) % n;
1064
1065 assert( 0 <= index1 && index1 < n );
1066 assert( 0 <= index2 && index2 < n );
1067 assert( 0 <= index3 && index3 < n );
1068 assert( index1 < index2 );
1069 assert( index1 < index3 );
1070 assert( index2 != index3 );
1071
1072 if ( vars[index3][index1] == infervar )
1073 {
1074 /* the variable should have been fixed to 0 */
1075 assert( SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, FALSE) > 0.5 && SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5 );
1076
1077 /* the reason was that x[index1][index2] and x[index2][index3] were fixed to 1 */
1078 SCIPdebugMsg(scip, " -> reason for x[%d][%d] == 0 was x[%d][%d] = x[%d][%d] = 1.\n", index3, index1, index1, index2, index2, index3);
1079 SCIP_CALL( SCIPaddConflictLb(scip, vars[index1][index2], bdchgidx) );
1080 SCIP_CALL( SCIPaddConflictLb(scip, vars[index2][index3], bdchgidx) );
1082 }
1083 else if ( vars[index2][index3] == infervar )
1084 {
1085 /* the variable should have been fixed to 0 */
1086 assert( SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, FALSE) > 0.5 && SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5 );
1087
1088 /* the reason was that x[index1][index2] and x[index3][index1] were fixed to 1 */
1089 SCIPdebugMsg(scip, " -> reason for x[%d][%d] == 0 was x[%d][%d] = x[%d][%d] = 1.\n", index2, index3, index1, index2, index3, index1);
1090 SCIP_CALL( SCIPaddConflictLb(scip, vars[index1][index2], bdchgidx) );
1091 SCIP_CALL( SCIPaddConflictLb(scip, vars[index3][index1], bdchgidx) );
1093 }
1094 else if ( vars[index1][index2] == infervar )
1095 {
1096 /* the variable should have been fixed to 0 */
1097 assert( SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, FALSE) > 0.5 && SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5 );
1098
1099 /* the reason was that x[index2][index3] and x[index3][index1] were fixed to 1 */
1100 SCIPdebugMsg(scip, " -> reason for x[%d][%d] == 0 was x[%d][%d] = x[%d][%d] = 1.\n", index1, index2, index2, index3, index3, index1);
1101 SCIP_CALL( SCIPaddConflictLb(scip, vars[index2][index3], bdchgidx) );
1102 SCIP_CALL( SCIPaddConflictLb(scip, vars[index3][index1], bdchgidx) );
1104 }
1105 else
1106 {
1107 /* should not happen */
1108 SCIPABORT();
1109 }
1110 }
1111
1112 return SCIP_OKAY;
1113}
1114
1115/** variable rounding lock method of constraint handler */
1116static
1118{ /*lint --e{715}*/
1119 int i;
1120 int j;
1121 SCIP_CONSDATA* consdata;
1122 SCIP_VAR*** vars;
1123 int n;
1124
1125 assert( scip != NULL );
1126 assert( conshdlr != NULL );
1127 assert( cons != NULL );
1128
1130
1131 SCIPdebugMsg(scip, "Locking linear ordering constraint <%s>.\n", SCIPconsGetName(cons));
1132
1133 /* get data of constraint */
1134 consdata = SCIPconsGetData(cons);
1135 assert( consdata != NULL);
1136 assert( consdata->vars != NULL );
1137 n = consdata->n;
1138 vars = consdata->vars;
1139
1140 for (i = 0; i < n; ++i)
1141 {
1142 for (j = 0; j < n; ++j)
1143 {
1144 if ( i != j )
1145 {
1146 /* the constraint may be violated in any way */
1147 SCIP_CALL( SCIPaddVarLocksType(scip, vars[i][j], SCIP_LOCKTYPE_MODEL, nlockspos + nlocksneg, nlockspos + nlocksneg) );
1148 }
1149 }
1150 }
1151
1152 return SCIP_OKAY;
1153}
1154
1155/** constraint display method of constraint handler */
1156static
1158{ /*lint --e{715}*/
1159 SCIP_CONSDATA* consdata;
1160 SCIP_VAR*** vars;
1161 int i;
1162 int j;
1163 int n;
1164
1165 assert( scip != NULL );
1166 assert( conshdlr != NULL );
1167 assert( cons != NULL );
1168
1170
1171 consdata = SCIPconsGetData(cons);
1172 assert( consdata != NULL );
1173 assert( consdata->vars != NULL );
1174 n = consdata->n;
1175 vars = consdata->vars;
1176
1177 SCIPinfoMessage(scip, file, "LOP[");
1178 for (i = 0; i < n; ++i)
1179 {
1180 if ( i > 0 )
1181 SCIPinfoMessage(scip, file, ", ");
1182 SCIPinfoMessage(scip, file, "(");
1183 for (j = 0; j < n; ++j)
1184 {
1185 if ( j != i )
1186 {
1187 if ( j > 0 && (i > 0 || j > 1) )
1188 SCIPinfoMessage(scip, file, ",");
1189 SCIPinfoMessage(scip, file, "%s", SCIPvarGetName(vars[i][j]));
1190 }
1191 }
1192 SCIPinfoMessage(scip, file, ")");
1193 }
1194 SCIPinfoMessage(scip, file, "]\n");
1195
1196 return SCIP_OKAY;
1197}
1198
1199/** constraint copying method of constraint handler */
1200static
1202{ /*lint --e{715}*/
1203 SCIP_CONSDATA* sourcedata;
1204 SCIP_VAR*** sourcevars;
1205 SCIP_VAR*** vars;
1206 int i;
1207 int j;
1208 int n;
1209
1210 assert( scip != NULL );
1211 assert( sourceconshdlr != NULL );
1212 assert( cons != NULL );
1213 assert( sourcescip != NULL );
1214 assert( sourcecons != NULL );
1215 assert( varmap != NULL );
1216 assert( valid != NULL );
1217
1219
1220 *valid = TRUE;
1221
1222 SCIPdebugMsg(scip, "Copying method for linear ordering constraint handler.\n");
1223
1224 sourcedata = SCIPconsGetData(sourcecons);
1225 assert( sourcedata != NULL );
1226
1227 n = sourcedata->n;
1228 sourcevars = sourcedata->vars;
1229 assert( sourcevars != NULL );
1230
1233
1234 for (i = 0; i < n; ++i)
1235 {
1236 SCIP_CALL( SCIPallocBufferArray(scip, &(vars[i]), n) ); /*lint !e866*/
1237
1238 for (j = 0; j < n && *valid; ++j)
1239 {
1240 if ( i != j )
1241 {
1242 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcevars[i][j], &vars[i][j], varmap, consmap, global, valid) );
1243 assert( !(*valid) || vars[i][j] != NULL );
1244 }
1245 }
1246 }
1247
1248 if ( *valid )
1249 {
1250 /* create copied constraint */
1251 if ( name == 0 )
1252 name = SCIPconsGetName(sourcecons);
1253
1254 SCIP_CALL( SCIPcreateConsLOP(scip, cons, name, n, vars,
1255 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
1256 }
1257
1258 /* free memory in reverse order */
1259 for (i = n-1; i >= 0; --i)
1262
1263 return SCIP_OKAY;
1264}
1265
1266/** creates the handler for linear ordering constraints and includes it in SCIP */
1268 SCIP* scip /**< SCIP data structure */
1269 )
1270{
1271 SCIP_CONSHDLR* conshdlr = NULL;
1272
1273 /* include constraint handler */
1276 consEnfolpLOP, consEnfopsLOP, consCheckLOP, consLockLOP, NULL) );
1277 assert( conshdlr != NULL );
1278
1279 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteLOP) );
1280 SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitLOP) );
1281 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyLOP, consCopyLOP) );
1282 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransLOP) );
1283 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpLOP) );
1284 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpLOP, consSepasolLOP,
1286 SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropLOP, CONSHDLR_PROPFREQ,
1288 SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropLOP) );
1289 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintLOP) );
1290
1291 return SCIP_OKAY;
1292}
1293
1294/** creates and captures a linear ordering constraint */
1296 SCIP* scip, /**< SCIP data structure */
1297 SCIP_CONS** cons, /**< pointer to hold the created constraint */
1298 const char* name, /**< name of constraint */
1299 int n, /**< number of elements */
1300 SCIP_VAR*** vars, /**< n x n matrix of binary variables */
1301 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? */
1302 SCIP_Bool separate, /**< should the constraint be separated during LP processing? */
1303 SCIP_Bool enforce, /**< should the constraint be enforced during node processing? */
1304 SCIP_Bool check, /**< should the constraint be checked for feasibility? */
1305 SCIP_Bool propagate, /**< should the constraint be propagated during node processing? */
1306 SCIP_Bool local, /**< is constraint only valid locally? */
1307 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? */
1308 SCIP_Bool dynamic, /**< is constraint subject to aging? */
1309 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
1310 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
1311 * if it may be moved to a more global node? */
1312 )
1313{
1314 SCIP_CONSHDLR* conshdlr;
1315 SCIP_CONSDATA* consdata;
1316 int i;
1317 int j;
1318
1319 /* find the linear ordering constraint handler */
1320 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
1321 if (conshdlr == NULL)
1322 {
1323 SCIPerrorMessage("linear ordering constraint handler not found\n");
1324 return SCIP_PLUGINNOTFOUND;
1325 }
1326
1327 /* create constraint data */
1328 SCIP_CALL( SCIPallocBlockMemory(scip, &consdata) );
1329
1330 consdata->n = n;
1331 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->vars, n) );
1332 for (i = 0; i < n; ++i)
1333 {
1334 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(consdata->vars[i]), n) ); /*lint !e866*/
1335 for (j = 0; j < n; ++j)
1336 {
1337 if ( j != i )
1338 {
1339 assert( vars[i][j] != NULL );
1340 consdata->vars[i][j] = vars[i][j];
1341 }
1342 }
1343 }
1344
1345 /* create constraint */
1346 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
1347 local, modifiable, dynamic, removable, stickingatnode) );
1348
1349 return SCIP_OKAY;
1350}
#define CONSHDLR_NEEDSCONS
Definition cons_and.c:96
#define CONSHDLR_SEPAFREQ
Definition cons_and.c:89
#define CONSHDLR_CHECKPRIORITY
Definition cons_and.c:88
#define CONSHDLR_DESC
Definition cons_and.c:85
#define CONSHDLR_PROP_TIMING
Definition cons_and.c:99
#define CONSHDLR_SEPAPRIORITY
Definition cons_and.c:86
#define CONSHDLR_PROPFREQ
Definition cons_and.c:90
#define CONSHDLR_EAGERFREQ
Definition cons_and.c:91
#define CONSHDLR_ENFOPRIORITY
Definition cons_and.c:87
#define CONSHDLR_DELAYSEPA
Definition cons_and.c:94
#define CONSHDLR_NAME
Definition cons_and.c:84
#define CONSHDLR_DELAYPROP
Definition cons_and.c:95
SCIP_RETCODE SCIPincludeConshdlrLOP(SCIP *scip)
Definition cons_lop.c:1267
SCIP_RETCODE SCIPcreateConsLOP(SCIP *scip, SCIP_CONS **cons, const char *name, int n, SCIP_VAR ***vars, 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 cons_lop.c:1295
static SCIP_RETCODE LOPseparate(SCIP *scip, SCIP_CONSHDLR *conshdlr, int n, SCIP_VAR ***vars, SCIP_SOL *sol, int *ngen, SCIP_Bool *cutoff)
Definition cons_lop.c:69
constraint handler for linear ordering constraints
#define NULL
Definition def.h:257
#define SCIP_MAXSTRLEN
Definition def.h:278
#define SCIP_Bool
Definition def.h:100
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define SCIPABORT()
Definition def.h:336
#define SCIP_CALL(x)
Definition def.h:364
int SCIPgetSubscipDepth(SCIP *scip)
Definition scip_copy.c:2589
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
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
#define SCIPdebugMsg
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_RETCODE SCIPaddConflictBinvar(SCIP *scip, SCIP_VAR *var)
SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
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 SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:785
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4320
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)),)
Definition scip_cons.c:347
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition scip_cons.c:940
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:578
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:601
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:647
SCIP_RETCODE SCIPsetConshdlrExit(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:420
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:624
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition cons.c:8423
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition cons.c:8652
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition cons.c:8562
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition scip_cons.c:2536
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition cons.c:8592
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition cons.c:8582
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:8612
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition cons.c:8632
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition cons.c:8393
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition cons.c:8642
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition cons.c:8672
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition cons.c:8572
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition cons.c:8662
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
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:110
#define SCIPallocBufferArray(scip, ptr, num)
Definition scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition scip_mem.h:136
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:93
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition scip_mem.h:137
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_RETCODE SCIPcacheRowExtensions(SCIP *scip, SCIP_ROW *row)
Definition scip_lp.c:1581
SCIP_RETCODE SCIPflushRowExtensions(SCIP *scip, SCIP_ROW *row)
Definition scip_lp.c:1604
SCIP_RETCODE SCIPcreateEmptyRowConshdlr(SCIP *scip, SCIP_ROW **row, SCIP_CONSHDLR *conshdlr, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
Definition scip_lp.c:1367
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_SOL * SCIPgetBestSol(SCIP *scip)
Definition scip_sol.c:2986
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1763
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:24300
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
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23299
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:24266
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition scip_var.c:2736
SCIP_RETCODE SCIPinferBinvarCons(SCIP *scip, SCIP_VAR *var, SCIP_Bool fixedval, SCIP_CONS *infercons, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition scip_var.c:7412
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition scip_var.c:2078
void SCIPsortIntInt(int *intarray1, int *intarray2, int len)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10827
return SCIP_OKAY
int c
SCIP_Bool cutoff
static SCIP_SOL * sol
assert(minobj< SCIPgetCutoffbound(scip))
static SCIP_Bool propagate
static SCIP_VAR ** vars
#define BMSclearMemoryArray(ptr, num)
Definition memory.h:130
#define SCIPerrorMessage
Definition pub_message.h:64
#define SCIPdebug(x)
Definition pub_message.h:93
static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
Main separation function.
@ SCIP_CONFTYPE_PROPAGATION
#define SCIP_DECL_CONSENFOLP(x)
Definition type_cons.h:363
#define SCIP_DECL_CONSDELETE(x)
Definition type_cons.h:229
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
#define SCIP_DECL_CONSEXIT(x)
Definition type_cons.h:136
#define SCIP_DECL_CONSPRINT(x)
Definition type_cons.h:769
#define SCIP_DECL_CONSSEPALP(x)
Definition type_cons.h:288
#define SCIP_DECL_CONSPROP(x)
Definition type_cons.h:506
#define SCIP_DECL_CONSRESPROP(x)
Definition type_cons.h:612
#define SCIP_DECL_CONSENFOPS(x)
Definition type_cons.h:431
#define SCIP_DECL_CONSTRANS(x)
Definition type_cons.h:239
#define SCIP_DECL_CONSINITLP(x)
Definition type_cons.h:259
#define SCIP_DECL_CONSLOCK(x)
Definition type_cons.h:676
struct SCIP_Conshdlr SCIP_CONSHDLR
Definition type_cons.h:62
#define SCIP_DECL_CONSCOPY(x)
Definition type_cons.h:810
struct SCIP_ConsData SCIP_CONSDATA
Definition type_cons.h:65
#define SCIP_DECL_CONSCHECK(x)
Definition type_cons.h:474
#define SCIP_DECL_CONSHDLRCOPY(x)
Definition type_cons.h:108
#define SCIP_DECL_CONSSEPASOL(x)
Definition type_cons.h:320
struct SCIP_Row SCIP_ROW
Definition type_lp.h:105
@ 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
@ SCIP_PLUGINNOTFOUND
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_LOCKTYPE_MODEL
Definition type_var.h:141