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