Scippy

SCIP

Solving Constraint Integer Programs

cons_linking.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-2017 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 email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file cons_linking.c
17  * @brief constraint handler for linking constraints
18  * @author Stefan Heinz
19  * @author Jens Schulz
20  *
21  * The constraints handler stores linking constraints between an integer variable and an array of binary variables. Such
22  * a linking constraint has the form:
23  *
24  * intvar = sum_{i=1}^n {vals[i] * binvars[i]}
25  *
26  * with the additional side condition that exactly one binary variable has to be one (set partitioning condition).
27  *
28  * This constraint can be created only with the integer variable. In this case the binary variables are only created on
29  * demand. That is, whenever someone asks for the binary variables. Therefore, such constraints can be used to get a
30  * "binary representation" of the domain of the integer variable which will be dynamically created.
31  *
32  *
33  * @todo add pairwise comparison of constraints in presolving (fast hash table version and complete pairwise comparison)
34  * @todo in case the integer variable is set to lower or upper bound it follows that only the corresponding binary
35  * variable has a positive value which is one, this can be used to fasten the checking routine
36  */
37 
38 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
39 
40 #include <assert.h>
41 #include <string.h>
42 #include <ctype.h>
43 
44 #include "scip/cons_linear.h"
45 #include "scip/cons_linking.h"
46 #include "scip/cons_setppc.h"
47 
48 /* constraint handler properties */
49 #define CONSHDLR_NAME "linking"
50 #define CONSHDLR_DESC "linking constraint x = sum_{i=1}^{n} c_i*y_i, y1+...+yn = 1, x integer, y's binary"
51 
52 #define EVENTHDLR_NAME "linking"
53 #define EVENTHDLR_DESC "event handler for linking constraints"
54 
55 #define CONSHDLR_SEPAPRIORITY 750000 /**< priority of the constraint handler for separation */
56 #define CONSHDLR_ENFOPRIORITY -2050000 /**< priority of the constraint handler for constraint enforcing */
57 #define CONSHDLR_CHECKPRIORITY -750000 /**< priority of the constraint handler for checking feasibility */
58 #define CONSHDLR_SEPAFREQ 1 /**< frequency for separating cuts; zero means to separate only in the root node */
59 #define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
60 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation, propagation and enforcement, -1 for no eager evaluations, 0 for first only */
61 #define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
62 #define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
63 #define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
64 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
65 
66 #define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP /**< propagation timing mask of the constraint handler */
67 #define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_MEDIUM /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
68 
69 
70 #define HASHSIZE_BINVARSCONS 500 /**< minimal size of hash table in linking constraint handler */
71 #define DEFAULT_LINEARIZE FALSE /**< should the linking constraint be linearize after the binary variable are created */
72 
73 /*
74  * Data structures
75  */
76 
77 /** constraint data for linking constraints */
78 struct SCIP_ConsData
79 {
80  SCIP_VAR* intvar; /**< integer variable which is linked */
81  SCIP_VAR** binvars; /**< binary variables */
82  int* vals; /**< coefficients */
83  SCIP_ROW* row1; /**< LP row for the linking itself */
84  SCIP_ROW* row2; /**< LP row ensuring the set partitioning condition of the binary variables */
85  int nbinvars; /**< number of binary variables */
86  int sizebinvars; /**< size of the binary variable array */
87  int nfixedzeros; /**< current number of variables fixed to zero in the constraint */
88  int nfixedones; /**< current number of variables fixed to one in the constraint */
89  int firstnonfixed; /**< index of first locally non-fixed binary variable in binvars array */
90  int lastnonfixed; /**< index of last locally non-fixed binary variable in binvars array */
91  unsigned int cliqueadded:1; /**< was the set partitioning condition already added as clique? */
92  unsigned int sorted:1; /**< are the coefficients of the binary variables are sorted in non-decreasing order */
93 };
94 
95 /** constraint handler data */
96 struct SCIP_ConshdlrData
97 {
98  SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events on binary variables */
99  SCIP_HASHMAP* varmap; /**< hash map mapping an integer variable to its linking constraint */
100  SCIP_Bool linearize; /**< should the linking constraint be linearize after the binary variable are created */
101 };
102 
103 /*
104  * Local methods
105  */
106 
107 /** returns for a given integer variable the corresponding hash map key */
108 static
110  SCIP_VAR* var /**< variable to get the hash map key for */
111  )
112 {
113  /* return the unique variable index + 1 */
114  return (void*)(size_t)(SCIPvarGetIndex(var) + 1); /*lint !e571 !e776*/
115 }
116 
117 /* sort binary variable in non-decreasing order w.r.t. coefficients */
118 static
120  SCIP_CONSDATA* consdata /**< linking constraint data */
121  )
122 {
123  if( consdata->sorted )
124  return;
125 
126  /* sort binary variable in non-decreasing order w.r.t. coefficients */
127  SCIPsortIntPtr(consdata->vals, (void**)consdata->binvars, consdata->nbinvars);
128 
129  consdata->sorted = TRUE;
130 }
131 
132 
133 /** installs rounding locks for the binary variables in the given linking constraint */
134 static
136  SCIP* scip, /**< SCIP data structure */
137  SCIP_CONS* cons, /**< linking constraint */
138  SCIP_VAR** binvars, /**< binary variables */
139  int nbinvars /**< number of binary variables */
140  )
141 {
142  int b;
143 
144  for( b = 0; b < nbinvars; ++b )
145  {
146  SCIP_CALL( SCIPlockVarCons(scip, binvars[b], cons, TRUE, TRUE) );
147  }
148 
149  return SCIP_OKAY;
150 }
151 
152 /** creates constraint handler data for the linking constraint handler */
153 static
155  SCIP* scip, /**< SCIP data structure */
156  SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
157  SCIP_EVENTHDLR* eventhdlr /**< event handler */
158  )
159 {
160  assert(scip != NULL);
161  assert(conshdlrdata != NULL);
162  assert(eventhdlr != NULL);
163 
164  SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
165 
166  /* create hash map */
167  (*conshdlrdata)->varmap = NULL;
168 
169  /* set event handler for bound change events on binary variables */
170  (*conshdlrdata)->eventhdlr = eventhdlr;
171 
172  return SCIP_OKAY;
173 }
174 
175 /** frees constraint handler data for linking constraint handler */
176 static
178  SCIP* scip, /**< SCIP data structure */
179  SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
180  )
181 {
182  assert(conshdlrdata != NULL);
183  assert(*conshdlrdata != NULL);
184 
185  /* free hash map */
186  if( (*conshdlrdata)->varmap != NULL )
187  SCIPhashmapFree(&(*conshdlrdata)->varmap);
188 
189  /* free memory of constraint handler data */
190  SCIPfreeBlockMemory(scip, conshdlrdata);
191 
192  return SCIP_OKAY;
193 }
194 
195 /** prints linking constraint to file stream */
196 static
198  SCIP* scip, /**< SCIP data structure */
199  SCIP_CONSDATA* consdata, /**< linking constraint data */
200  FILE* file /**< output file (or NULL for standard output) */
201  )
202 {
203  SCIP_VAR** binvars;
204  SCIP_VAR* intvar;
205  int nbinvars;
206  int b;
207 
208  assert(scip != NULL);
209  assert(consdata != NULL);
210 
211  intvar = consdata->intvar;
212  binvars = consdata->binvars;
213  nbinvars = consdata->nbinvars;
214 
215  assert(intvar != NULL);
216  assert(binvars != NULL || nbinvars == 0);
217 
218  /* print integer variable */
219  SCIP_CALL( SCIPwriteVarName(scip, file, intvar, FALSE) );
220 
221  SCIPinfoMessage(scip, file, " = ");
222 
223  if( nbinvars == 0 )
224  {
225  SCIPinfoMessage(scip, file, " no binary variables yet");
226  }
227  else
228  {
229  SCIP_Real* vals;
230 
231  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nbinvars) );
232 
233  assert(binvars != NULL);
234 
235  /* convert integer coefficients into SCIP_Real */
236  for( b = 0; b < nbinvars; ++b )
237  {
238  vals[b] = (SCIP_Real)consdata->vals[b];
239  }
240 
241  SCIP_CALL( SCIPwriteVarsLinearsum(scip, file, binvars, vals, nbinvars, FALSE) );
242 
243  SCIPfreeBufferArray(scip, &vals);
244  }
245 
246  return SCIP_OKAY;
247 }
248 
249 /** catches events for variable at given position */
250 static
252  SCIP* scip, /**< SCIP data structure */
253  SCIP_CONSDATA* consdata, /**< linking constraint data */
254  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
255  int pos /**< array position of variable to catch bound change events for */
256  )
257 {
258  SCIP_VAR* var;
259 
260  assert(consdata != NULL);
261  assert(eventhdlr != NULL);
262  assert(0 <= pos && pos < consdata->nbinvars);
263  assert(consdata->binvars != NULL);
264 
265  var = consdata->binvars[pos];
266  assert(var != NULL);
267 
268  /* catch bound change events on variable */
269  /**@todo do we have to add the event SCIP_EVENTTYPE_VARFIXED? */
270  SCIP_CALL( SCIPcatchVarEvent(scip, var, SCIP_EVENTTYPE_BOUNDCHANGED, eventhdlr, (SCIP_EVENTDATA*)consdata, NULL) );
271 
272  /* update the fixed variables counters for this variable */
273  if( SCIPisEQ(scip, SCIPvarGetUbLocal(var), 0.0) )
274  consdata->nfixedzeros++;
275  else if( SCIPisEQ(scip, SCIPvarGetLbLocal(var), 1.0) )
276  consdata->nfixedones++;
277 
278  return SCIP_OKAY;
279 }
280 
281 /** drops events for variable at given position */
282 static
284  SCIP* scip, /**< SCIP data structure */
285  SCIP_CONSDATA* consdata, /**< linking constraint data */
286  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
287  int pos /**< array position of variable to catch bound change events for */
288  )
289 {
290  SCIP_VAR* var;
291 
292  assert(consdata != NULL);
293  assert(eventhdlr != NULL);
294  assert(0 <= pos && pos < consdata->nbinvars);
295  assert(consdata->binvars != NULL);
296 
297  var = consdata->binvars[pos];
298  assert(var != NULL);
299 
300  /* drop events on variable */
301  SCIP_CALL( SCIPdropVarEvent(scip, var, SCIP_EVENTTYPE_BOUNDCHANGED, eventhdlr, (SCIP_EVENTDATA*)consdata, -1) );
302 
303  /* update the fixed variables counters for this variable */
304  if( SCIPisEQ(scip, SCIPvarGetUbLocal(var), 0.0) )
305  consdata->nfixedzeros--;
306  else if( SCIPisEQ(scip, SCIPvarGetLbLocal(var), 1.0) )
307  consdata->nfixedones--;
308 
309  return SCIP_OKAY;
310 }
311 
312 /** catches bound change events for all variables in transformed linking constraint */
313 static
315  SCIP* scip, /**< SCIP data structure */
316  SCIP_CONSDATA* consdata, /**< linking constraint data */
317  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
318  )
319 {
320  int i;
321 
322  assert(consdata != NULL);
323 
324  if( consdata->nbinvars <= 1 )
325  return SCIP_OKAY;
326 
327  /* catch event for every single variable */
328  for( i = 0; i < consdata->nbinvars; ++i )
329  {
330  SCIP_CALL( catchEvent(scip, consdata, eventhdlr, i) );
331  }
332 
333  return SCIP_OKAY;
334 }
335 
336 /** drops bound change events for all variables in transformed linking constraint */
337 static
339  SCIP* scip, /**< SCIP data structure */
340  SCIP_CONSDATA* consdata, /**< linking constraint data */
341  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
342  )
343 {
344  int i;
345 
346  assert(consdata != NULL);
347 
348  if( consdata->nbinvars <= 1 )
349  return SCIP_OKAY;
350 
351  /* drop event of every single variable */
352  for( i = 0; i < consdata->nbinvars; ++i )
353  {
354  SCIP_CALL( dropEvent(scip, consdata, eventhdlr, i) );
355  }
356 
357  return SCIP_OKAY;
358 }
359 
360 /** linearize the given linking constraint into a set partitioning constraint for the binary variables and a linear
361  * constraint for the linking between the integer variable and the binary variables */
362 static
364  SCIP* scip, /**< SCIP data structure */
365  SCIP_CONS* cons, /**< linking constraint */
366  SCIP_CONSDATA* consdata /**< linking constraint data */
367  )
368 {
369  SCIP_CONS* lincons;
370  int b;
371 
372  SCIPdebugMsg(scip, "linearized linking constraint <%s>\n", SCIPconsGetName(cons));
373 
374  /* create set partitioning constraint for the binary variables */
375  SCIP_CALL( SCIPcreateConsSetpart(scip, &lincons, SCIPconsGetName(cons), consdata->nbinvars, consdata->binvars,
379  SCIP_CALL( SCIPaddCons(scip, lincons) );
380  SCIP_CALL( SCIPreleaseCons(scip, &lincons) );
381 
382  /* create linear constraint for the linking between the binary variables and the integer variable */
383  SCIP_CALL( SCIPcreateConsLinear(scip, &lincons, SCIPconsGetName(cons), 0, NULL, NULL, 0.0, 0.0,
387 
388  for( b = 0; b < consdata->nbinvars; ++b )
389  {
390  SCIP_CALL( SCIPaddCoefLinear(scip, lincons, consdata->binvars[b], (SCIP_Real)consdata->vals[b]) );
391  }
392  SCIP_CALL( SCIPaddCoefLinear(scip, lincons, consdata->intvar, -1.0) );
393 
394  SCIP_CALL( SCIPaddCons(scip, lincons) );
395  SCIP_CALL( SCIPreleaseCons(scip, &lincons) );
396 
397  return SCIP_OKAY;
398 }
399 
400 /** creates the binary variables */
401 static
403  SCIP* scip, /**< SCIP data structure */
404  SCIP_CONS* cons, /**< linking constraint */
405  SCIP_CONSDATA* consdata, /**< linking constraint data */
406  SCIP_EVENTHDLR* eventhdlr, /**< event handler for bound change events on binary variables */
407  SCIP_Bool linearize /**< should the linking constraint be linearized */
408  )
409 {
410  SCIP_VAR* intvar;
411  SCIP_VAR* binvar;
412  char name[SCIP_MAXSTRLEN];
413  int nbinvars;
414  int lb;
415  int ub;
416  int b;
417 
418  assert(scip != NULL);
419  assert(consdata != NULL);
420  assert(consdata->nbinvars == 0);
421  assert(consdata->binvars == NULL);
422 
423  SCIPdebugMsg(scip, "create binary variables for integer variable <%s>\n", SCIPvarGetName(consdata->intvar));
424 
425  intvar = consdata->intvar;
426  lb = SCIPconvertRealToInt(scip, SCIPvarGetLbGlobal(intvar));
427  ub = SCIPconvertRealToInt(scip, SCIPvarGetUbGlobal(intvar));
428  nbinvars = ub-lb+1;
429  assert(nbinvars > 0);
430 
431  /* allocate block memory for the binary variables */
432  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->binvars, nbinvars) );
433  consdata->sizebinvars = nbinvars;
434 
435  /* check if the integer variable is fixed */
436  if( nbinvars == 1 )
437  {
438  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s[%d]", SCIPvarGetName(intvar), lb);
439 
440  /* creates and captures a fixed binary variables */
441  SCIP_CALL( SCIPcreateVar(scip, &binvar, name, 1.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
442  FALSE, TRUE, NULL, NULL, NULL, NULL, NULL) );
443  SCIP_CALL( SCIPaddVar(scip, binvar) );
444 
445  consdata->binvars[0] = binvar;
446  consdata->vals[0] = lb;
447  }
448  else
449  {
450  for( b = 0; b < nbinvars; ++b)
451  {
452  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s[%d]", SCIPvarGetName(intvar), lb + b);
453 
454  /* creates and captures variables */
455  SCIP_CALL( SCIPcreateVar(scip, &binvar, name, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
456  TRUE, TRUE, NULL, NULL, NULL, NULL, NULL) );
457 
458  /* add variable to the problem */
459  SCIP_CALL( SCIPaddVar(scip, binvar) );
460  consdata->binvars[b] = binvar;
461  consdata->vals[b] = lb + b;
462  }
463  }
464 
465  consdata->nbinvars = nbinvars;
466 
467  assert(consdata->nfixedzeros == 0);
468  assert(consdata->nfixedones == 0);
469 
470  if( SCIPisTransformed(scip) )
471  {
472  /* (rounding) lock binary variable */
473  SCIP_CALL( lockRounding(scip, cons, consdata->binvars, consdata->nbinvars) );
474 
475  /* catch bound change events of variables */
476  SCIP_CALL( catchAllEvents(scip, consdata, eventhdlr) );
477 
478  if( nbinvars > 1 )
479  {
480  if( linearize )
481  {
482  SCIP_CALL( consdataLinearize(scip, cons, consdata) );
483  }
484  else
485  {
486  /* enable constraint */
487  SCIP_CALL( SCIPenableCons(scip, cons) );
488  }
489  }
490  }
491 
492  return SCIP_OKAY;
493 }
494 
495 /** creates consdata */
496 static
498  SCIP* scip, /**< SCIP data structure */
499  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
500  SCIP_CONSDATA** consdata, /**< pointer to constraint data */
501  SCIP_VAR* intvar, /**< integer variable which is linked */
502  SCIP_VAR** binvars, /**< binary variables */
503  int* vals, /**< coefficients of the binary variables */
504  int nbinvars /**< number of binary starting variables */
505  )
506 {
507  int v;
508 
509  assert(scip!= NULL);
510  assert(consdata != NULL);
511  assert(intvar != NULL);
512  assert(binvars != NULL || nbinvars == 0);
513  assert(SCIPvarGetType(intvar) != SCIP_VARTYPE_CONTINUOUS);
514 
515  /* allocate memory for consdata */
516  SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
517 
518  (*consdata)->intvar = intvar;
519  (*consdata)->nbinvars = nbinvars;
520  (*consdata)->sizebinvars = nbinvars;
521  (*consdata)->row1 = NULL;
522  (*consdata)->row2 = NULL;
523  (*consdata)->cliqueadded = FALSE;
524 
525  /* initialize constraint state */
526  (*consdata)->sorted = FALSE;
527  (*consdata)->firstnonfixed = 0;
528  (*consdata)->lastnonfixed = nbinvars - 1;
529  (*consdata)->nfixedzeros = 0;
530  (*consdata)->nfixedones = 0;
531 
532  if( nbinvars == 0 )
533  {
534  (*consdata)->binvars = NULL;
535  (*consdata)->vals = NULL;
536  }
537  else
538  {
539  /* copy binary variable array */
540  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->binvars, binvars, nbinvars) );
541 
542  /* copy coefficients */
543  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vals, vals, nbinvars) );
544  }
545 
546  /* get transformed variable, if we are in the transformed problem */
547  if( SCIPisTransformed(scip) )
548  {
549  if( nbinvars > 0 )
550  {
551  SCIP_CALL( SCIPgetTransformedVars(scip, nbinvars, (*consdata)->binvars, (*consdata)->binvars) );
552 
553  /* catch bound change events of variables */
554  SCIP_CALL( catchAllEvents(scip, *consdata, eventhdlr) );
555  }
556 
557  SCIP_CALL( SCIPgetTransformedVar(scip, (*consdata)->intvar, &(*consdata)->intvar) );
558  }
559 
560  /* mark integer variable to be not multi-aggregated */
561  SCIP_CALL( SCIPmarkDoNotMultaggrVar(scip, (*consdata)->intvar) );
562 
563  /* capture variables */
564  for( v = 0; v < nbinvars; ++v )
565  {
566  assert((*consdata)->binvars[v] != NULL);
567  SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->binvars[v]) );
568  }
569  SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->intvar) );
570 
571  return SCIP_OKAY;
572 }
573 
574 
575 /** free consdata */
576 static
578  SCIP* scip, /**< SCIP data structure */
579  SCIP_CONSDATA** consdata /**< pointer to consdata */
580  )
581 {
582  int v;
583 
584  assert(consdata != NULL);
585  assert(*consdata != NULL);
586  assert((*consdata)->nbinvars == 0 || (*consdata)->binvars != NULL);
587 
588  /* release the rows */
589  if( (*consdata)->row1 != NULL )
590  {
591  assert((*consdata)->row2 != NULL);
592 
593  SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row1) );
594  SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row2) );
595  }
596 
597  /* capture variables */
598  for( v = 0; v < (*consdata)->nbinvars; ++v )
599  {
600  assert((*consdata)->binvars[v] != NULL);
601  SCIP_CALL( SCIPreleaseVar(scip, &(*consdata)->binvars[v]) );
602  }
603  SCIP_CALL( SCIPreleaseVar(scip, &(*consdata)->intvar) );
604 
605  /* free binary variable array */
606  if( (*consdata)->sizebinvars > 0 )
607  {
608  /* if constraint belongs to transformed problem space, drop bound change events on variables */
609  SCIPfreeBlockMemoryArray(scip, &(*consdata)->vals, (*consdata)->sizebinvars);
610  SCIPfreeBlockMemoryArray(scip, &(*consdata)->binvars, (*consdata)->sizebinvars);
611  }
612 
613  /* check if the fixed counters are reset */
614  assert((*consdata)->nfixedzeros == 0);
615  assert((*consdata)->nfixedones == 0);
616 
617  /* free constraint data */
618  SCIPfreeBlockMemory(scip, consdata);
619 
620  return SCIP_OKAY;
621 }
622 
623 
624 /** analyzes conflicting assignment on given constraint where reason comes from the integer variable lower or upper
625  * bound
626  */
627 static
629  SCIP* scip, /**< SCIP data structure */
630  SCIP_CONS* cons, /**< linking constraint to be processed */
631  SCIP_VAR* intvar, /**< integer variable */
632  SCIP_VAR* binvar, /**< binary variable is the reason */
633  SCIP_Bool lbintvar, /**< lower bound of integer variable is the reason */
634  SCIP_Bool ubintvar /**< upper bound of integer variable is the reason */
635  )
636 {
637  assert(scip != NULL);
638 
639  /* conflict analysis can only be applied in solving stage and if it is turned on */
641  return SCIP_OKAY;
642 
643  /* initialize conflict analysis, and add all variables of infeasible constraint to conflict candidate queue */
645 
646  if( lbintvar )
647  {
648  assert(intvar != NULL);
649  SCIP_CALL( SCIPaddConflictLb(scip, intvar, NULL) );
650  }
651 
652  if( ubintvar )
653  {
654  assert(intvar != NULL);
655  SCIP_CALL( SCIPaddConflictUb(scip, intvar, NULL) );
656  }
657 
658  if( binvar != NULL )
659  {
660  SCIP_CALL( SCIPaddConflictBinvar(scip, binvar) );
661  }
662 
663  /* analyze the conflict */
664  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
665 
666  return SCIP_OKAY;
667 }
668 
669 /** fix integer variable to the value of the binary variable at pos */
670 static
672  SCIP* scip, /**< SCIP data structure */
673  SCIP_CONS* cons, /**< linking constraint to be processed */
674  int pos, /**< position of binary variable */
675  SCIP_Bool* cutoff /**< pointer to store TRUE, if the node can be cut off */
676  )
677 {
678  SCIP_CONSDATA* consdata;
679  SCIP_VAR* intvar;
680  SCIP_Bool infeasible;
681  SCIP_Bool tightened;
682  SCIP_Real coef;
683 
684  consdata = SCIPconsGetData(cons);
685  assert(consdata != NULL);
686 
687  intvar = consdata->intvar;
688  coef = (SCIP_Real)consdata->vals[pos];
689 
690  /* change lower bound of the integer variable */
691  SCIP_CALL( SCIPinferVarLbCons(scip, intvar, coef, cons, pos, TRUE, &infeasible, &tightened) );
692 
693  if( infeasible )
694  {
695  assert(coef > SCIPvarGetUbLocal(intvar));
696  assert(coef >= SCIPvarGetLbLocal(intvar));
697 
698  SCIP_CALL( analyzeConflict(scip, cons, intvar, consdata->binvars[pos], FALSE, TRUE) );
699 
700  *cutoff = TRUE;
701  return SCIP_OKAY;
702  }
703  assert(coef <= SCIPvarGetUbLocal(intvar));
704 
705  /* change upper bound of the integer variable */
706  SCIP_CALL( SCIPinferVarUbCons(scip, intvar, coef, cons, pos, TRUE, &infeasible, &tightened) );
707 
708  if( infeasible )
709  {
710  assert(coef < SCIPvarGetLbLocal(intvar));
711  assert(coef <= SCIPvarGetUbLocal(intvar));
712 
713  SCIP_CALL( analyzeConflict(scip, cons, intvar, consdata->binvars[pos], TRUE, FALSE) );
714 
715  *cutoff = TRUE;
716  return SCIP_OKAY;
717  }
718 
719  assert((int)(SCIPvarGetUbLocal(intvar)+0.5) == (int)(SCIPvarGetLbLocal(intvar)+0.5) );
720 
721  return SCIP_OKAY;
722 }
723 
724 /** checks constraint for violation from the local bound of the integer variable, applies fixings to the binary
725  * variables if possible
726  */
727 static
729  SCIP* scip, /**< SCIP data structure */
730  SCIP_CONS* cons, /**< linking constraint to be processed */
731  SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
732  int* nchgbds, /**< pointer to store the number of changes (foxed) variable bounds */
733  SCIP_Bool* mustcheck /**< pointer to store whether this constraint must be checked for feasibility */
734  )
735 {
736  SCIP_CONSDATA* consdata;
737  SCIP_VAR** binvars;
738  SCIP_VAR* intvar;
739  int* vals;
740  int nbinvars;
741  int lblocal;
742  int ublocal;
743  int b;
744  SCIP_Bool infeasible;
745  SCIP_Bool tightened;
746 
747  assert(cons != NULL);
748  assert(SCIPconsGetHdlr(cons) != NULL);
749  assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
750  assert(cutoff != NULL);
751  assert(nchgbds != NULL);
752  assert(mustcheck != NULL);
753 
754  consdata = SCIPconsGetData(cons);
755  assert(consdata != NULL);
756 
757  /* ensure that the binary variables are sorted in non-decreasing order w.r.t. their coefficients */
758  consdataSort(consdata);
759 
760  nbinvars = consdata->nbinvars;
761 
762  /* in case there is only at most one binary variables, the constraints should already be disabled */
763  assert(nbinvars > 1);
764 
765  /* if more than one binary variable is fixed to one or at least nbinvars minus one variable are fixed to zero */
766  if( consdata->nfixedones > 0 || consdata->nfixedzeros >= nbinvars-1 )
767  return SCIP_OKAY;
768 
769  intvar = consdata->intvar;
770  assert(intvar != NULL);
771 
772  binvars = consdata->binvars;
773  vals = consdata->vals;
774 
775  lblocal = SCIPconvertRealToInt(scip, SCIPvarGetLbLocal(intvar));
776  ublocal = SCIPconvertRealToInt(scip, SCIPvarGetUbLocal(intvar));
777  assert(lblocal <= ublocal);
778 
779 #ifndef NDEBUG
780  /* check that the first variable are locally fixed to zero */
781  for( b = 0; b < consdata->firstnonfixed; ++b )
782  assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
783 
784  /* check that the last variable are locally fixed to zero */
785  for( b = consdata->lastnonfixed + 1; b < nbinvars; ++b )
786  assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
787 #endif
788 
789  for( b = consdata->firstnonfixed; b < nbinvars; ++b )
790  {
791  if( vals[b] < lblocal )
792  {
793  SCIP_VAR* var;
794 
795  var = binvars[b];
796  assert(var != NULL);
797 
798  SCIPdebugMsg(scip, "fix variable <%s> to zero due to the lower bound of the integer variable <%s> [%g,%g]\n",
799  SCIPvarGetName(var), SCIPvarGetName(intvar), SCIPvarGetLbLocal(intvar), SCIPvarGetUbLocal(intvar));
800 
801  SCIP_CALL( SCIPinferBinvarCons(scip, var, FALSE, cons, -2, &infeasible, &tightened) );
802 
803  if( infeasible )
804  {
805  SCIP_CALL( analyzeConflict(scip, cons, intvar, var, TRUE, FALSE) );
806  *cutoff = TRUE;
807  return SCIP_OKAY;
808  }
809 
810  if( tightened )
811  (*nchgbds)++;
812 
813  /* adjust constraint state */
814  consdata->firstnonfixed++;
815  }
816  else
817  break;
818  }
819  assert(consdata->firstnonfixed <= consdata->lastnonfixed);
820 
821  /* fix binary variables to zero if not yet fixed, from local upper bound + 1*/
822  for( b = consdata->lastnonfixed; b >= 0; --b )
823  {
824  if( vals[b] > ublocal )
825  {
826  SCIP_VAR* var;
827 
828  var = binvars[b];
829  assert(var != NULL);
830 
831  SCIPdebugMsg(scip, "fix variable <%s> to zero due to the upper bound of the integer variable <%s> [%g,%g]\n",
832  SCIPvarGetName(var), SCIPvarGetName(intvar), SCIPvarGetLbLocal(intvar), SCIPvarGetUbLocal(intvar));
833 
834  SCIP_CALL( SCIPinferBinvarCons(scip, var, FALSE, cons, -3, &infeasible, &tightened) );
835 
836  if( infeasible )
837  {
838  SCIP_CALL( analyzeConflict(scip, cons, intvar, var, FALSE, TRUE) );
839  *cutoff = TRUE;
840  return SCIP_OKAY;
841  }
842 
843  if( tightened )
844  (*nchgbds)++;
845 
846  /* adjust constraint state */
847  consdata->lastnonfixed--;
848  }
849  else
850  break;
851  }
852 
853  if( consdata->firstnonfixed > consdata->lastnonfixed )
854  {
855  *cutoff = TRUE;
856  return SCIP_OKAY;
857  }
858 
859  *mustcheck = (*nchgbds) == 0;
860 
861  /* if integer variables is fixed, create for the binary variables which have a coefficient equal to the fixed vale a
862  * set partitioning constraint
863  */
864  if( lblocal == ublocal )
865  {
866  if( consdata->firstnonfixed == consdata->lastnonfixed )
867  {
868  SCIP_VAR* var;
869 
870  var = binvars[consdata->firstnonfixed];
871 
872  SCIPdebugMsg(scip, "fix variable <%s> to one due to the fixed integer variable <%s> [%g,%g]\n",
873  SCIPvarGetName(var), SCIPvarGetName(intvar), SCIPvarGetLbLocal(intvar), SCIPvarGetUbLocal(intvar));
874 
875  SCIP_CALL( SCIPinferBinvarCons(scip, var, TRUE, cons, -6, &infeasible, &tightened) );
876 
877  if( infeasible )
878  {
879  SCIP_CALL( analyzeConflict(scip, cons, intvar, var, TRUE, TRUE) );
880  *cutoff = TRUE;
881  return SCIP_OKAY;
882  }
883 
884  if( tightened )
885  (*nchgbds)++;
886 
887  SCIPdebugMsg(scip, " -> disabling linking constraint <%s>\n", SCIPconsGetName(cons));
888  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
889 
890  *mustcheck = FALSE;
891  }
892  else if( SCIPgetDepth(scip) <= 0 )
893  {
894  SCIP_CONS* setppc;
895  SCIP_VAR** vars;
896  int nvars;
897 
898  /* get sub array of variables which have the same coefficient */
899  vars = &consdata->binvars[consdata->firstnonfixed];
900  nvars = consdata->lastnonfixed - consdata->firstnonfixed + 1;
901 
902  SCIP_CALL( SCIPcreateConsSetpart(scip, &setppc, SCIPconsGetName(cons), nvars, vars,
906 
907  SCIP_CALL( SCIPaddCons(scip, setppc) );
908  SCIP_CALL( SCIPreleaseCons(scip, &setppc) );
909 
910  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
911  }
912  }
913 
914  return SCIP_OKAY;
915 }
916 
917 /** deletes coefficient at given position from the binary variable array */
918 static
920  SCIP* scip, /**< SCIP data structure */
921  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
922  SCIP_CONS* cons, /**< linking constraint */
923  int pos /**< position of coefficient to delete */
924  )
925 {
926  SCIP_CONSDATA* consdata;
927  SCIP_VAR* var;
928 
929  assert(scip != NULL);
930  assert(eventhdlr != NULL);
931 
932  consdata = SCIPconsGetData(cons);
933  assert(consdata != NULL);
934  assert(0 <= pos && pos < consdata->nbinvars);
935 
936  var = consdata->binvars[pos];
937  assert(var != NULL);
938  assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
939 
940  /* remove the rounding locks for the deleted variable */
941  SCIP_CALL( SCIPunlockVarCons(scip, var, cons, TRUE, TRUE) );
942 
943  /* if we are in transformed problem, delete the event data of the variable */
944  if( SCIPconsIsTransformed(cons) )
945  {
946  SCIP_CONSHDLR* conshdlr;
947  SCIP_CONSHDLRDATA* conshdlrdata;
948 
949  /* get event handler */
950  conshdlr = SCIPconsGetHdlr(cons);
951  conshdlrdata = SCIPconshdlrGetData(conshdlr);
952  assert(conshdlrdata != NULL);
953  assert(conshdlrdata->eventhdlr != NULL);
954 
955  /* drop bound change events of variable */
956  SCIP_CALL( dropEvent(scip, consdata, conshdlrdata->eventhdlr, pos) );
957  }
958 
959  /* move the last variable to the free slot */
960  if( pos != consdata->nbinvars - 1 )
961  {
962  consdata->binvars[pos] = consdata->binvars[consdata->nbinvars-1];
963  consdata->vals[pos] = consdata->vals[consdata->nbinvars-1];
964  consdata->sorted = FALSE;
965  }
966 
967  consdata->nbinvars--;
968 
969  /* release variable */
970  SCIP_CALL( SCIPreleaseVar(scip, &var) );
971 
972  return SCIP_OKAY;
973 }
974 
975 /** remove the trailing and leeading binary variable which are fixed to zero */
976 static
978  SCIP* scip, /**< SCIP data structure */
979  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
980  SCIP_CONS* cons /**< linking constraint */
981  )
982 {
983  SCIP_CONSDATA* consdata;
984  int nbinvars;
985  int b;
986 
987  consdata = SCIPconsGetData(cons);
988  assert(consdata != NULL);
989  assert(consdata->sorted);
990 
991  assert(SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING || SCIPgetDepth(scip) <= 0);
992  assert(!SCIPinProbing(scip));
993  assert(!SCIPinRepropagation(scip));
994 
995  nbinvars = consdata->nbinvars;
996 
997  for( b = nbinvars - 1; b > consdata->lastnonfixed; --b )
998  {
999  SCIP_CALL( delCoefPos(scip, eventhdlr, cons, b) );
1000  }
1001 
1002  for( b = consdata->firstnonfixed - 1; b >= 0; --b )
1003  {
1004  SCIP_CALL( delCoefPos(scip, eventhdlr, cons, b) );
1005  }
1006 
1007  for( b = consdata->nbinvars - 1; b >= 0; --b )
1008  {
1009  if( SCIPvarGetUbLocal(consdata->binvars[b]) < 0.5 )
1010  {
1011  SCIP_CALL( delCoefPos(scip, eventhdlr, cons, b) );
1012  }
1013  }
1014 
1015  /* set the constraint state */
1016  consdata->firstnonfixed = 0;
1017  consdata->lastnonfixed = consdata->nbinvars - 1;
1018 
1019  return SCIP_OKAY;
1020 }
1021 
1022 /** tightened the integer variable due to binary variables which are fixed to zero */
1023 static
1025  SCIP* scip, /**< SCIP data structure */
1026  SCIP_CONS* cons, /**< linking constraint to be processed */
1027  SCIP_CONSDATA* consdata, /**< linking constraint to be processed */
1028  SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
1029  int* nchgbds /**< pointer to store the number of changed variable bounds */
1030  )
1031 {
1032  SCIP_VAR** binvars;
1033  SCIP_VAR* intvar;
1034  int* vals;
1035 
1036  SCIP_Bool infeasible;
1037  SCIP_Bool tightened;
1038  int nbinvars;
1039  int b;
1040 
1041  /* if more than one binary variable is fixed to one or at least nbinvars minus one variable are fixed to zero return */
1042  if( consdata->nfixedones > 1 || consdata->nfixedzeros >= consdata->nbinvars-1 )
1043  return SCIP_OKAY;
1044 
1045  if( *cutoff )
1046  return SCIP_OKAY;
1047 
1048  assert(consdata->sorted);
1049 
1050  intvar = consdata->intvar;
1051  binvars = consdata->binvars;
1052  vals = consdata->vals;
1053  nbinvars = consdata->nbinvars;
1054 
1055 #ifndef NDEBUG
1056  /* check that the first variable are locally fixed to zero */
1057  for( b = 0; b < consdata->firstnonfixed; ++b )
1058  assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
1059 #endif
1060 
1061  assert(consdata->firstnonfixed < nbinvars);
1062  assert(consdata->lastnonfixed < nbinvars);
1063 
1064  /* find first non fixed binary variable */
1065  for( b = consdata->firstnonfixed; b < nbinvars; ++b )
1066  {
1067  if( SCIPvarGetUbLocal(binvars[b]) > 0.5 )
1068  break;
1069 
1070  consdata->firstnonfixed++;
1071  }
1072 
1073  SCIP_CALL( SCIPinferVarLbCons(scip, intvar, (SCIP_Real)vals[b], cons, -4, TRUE, &infeasible, &tightened) );
1074 
1075  /* start conflict analysis if infeasible */
1076  if( infeasible )
1077  {
1078  /* analyze the cutoff if if SOLVING stage and conflict analysis is turned on */
1080  {
1081  SCIPdebugMsg(scip, "conflict at <%s> due to bounds and fixed binvars: [lb,ub] = [%g,%g]; b= %d; coef = %d \n",
1082  SCIPvarGetName(intvar), SCIPvarGetLbLocal(intvar), SCIPvarGetUbLocal(intvar), b, vals[b]);
1083 
1085 
1086  /* ??????????? use resolve method and only add binvars which are needed to exceed the upper bound */
1087 
1088  /* add conflicting variables */
1089  SCIP_CALL( SCIPaddConflictUb(scip, intvar, NULL) );
1090 
1091  for( b = 0; b < consdata->firstnonfixed; ++b )
1092  {
1093  SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
1094  }
1095 
1096  /* analyze the conflict */
1097  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
1098  }
1099 
1100  *cutoff = TRUE;
1101  return SCIP_OKAY;
1102  }
1103 
1104  if( tightened )
1105  (*nchgbds)++;
1106 
1107 #ifndef NDEBUG
1108  /* check that the last variable are locally fixed to zero */
1109  for( b = consdata->lastnonfixed + 1; b < nbinvars; ++b )
1110  assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
1111 #endif
1112 
1113  /* find last non fixed variable */
1114  for( b = consdata->lastnonfixed; b >= 0; --b )
1115  {
1116  if( SCIPvarGetUbLocal(binvars[b]) > 0.5 )
1117  break;
1118 
1119  consdata->lastnonfixed--;
1120  }
1121 
1122  SCIP_CALL( SCIPinferVarUbCons(scip, intvar, (SCIP_Real)vals[b], cons, -5, TRUE, &infeasible, &tightened) );
1123 
1124  if( infeasible )
1125  {
1126  /* conflict analysis can only be applied in solving stage and if conflict analysis is turned on */
1128  {
1129  SCIPdebugMsg(scip, "conflict at <%s> due to bounds and fixed binvars: [lb,ub] = [%g,%g]; b = %d; coef = %d,\n",
1130  SCIPvarGetName(intvar), SCIPvarGetLbLocal(intvar), SCIPvarGetUbLocal(intvar), b, vals[b]);
1131 
1133 
1134  /* ??????????? use resolve method and only add binvars which are needed to fall below the lower bound */
1135 
1136  /* add conflicting variables */
1137  SCIP_CALL( SCIPaddConflictLb(scip, intvar, NULL) );
1138 
1139  for( b = consdata->lastnonfixed + 1; b < nbinvars; ++b )
1140  {
1141  SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
1142  }
1143 
1144  /* analyze the conflict */
1145  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
1146  }
1147 
1148  *cutoff = TRUE;
1149  return SCIP_OKAY;
1150  }
1151 
1152  if( tightened )
1153  (*nchgbds)++;
1154 
1155  return SCIP_OKAY;
1156 }
1157 
1158 /** checks constraint for violation only looking at the fixed binary variables, applies further fixings if possible */
1159 static
1161  SCIP* scip, /**< SCIP data structure */
1162  SCIP_CONS* cons, /**< linking constraint to be processed */
1163  SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
1164  int* nchgbds, /**< pointer to store the number of changed variable bounds */
1165  SCIP_Bool* addcut, /**< pointer to store whether this constraint must be added as a cut */
1166  SCIP_Bool* mustcheck /**< pointer to store whether this constraint must be checked for feasibility */
1167  )
1168 {
1169  SCIP_CONSDATA* consdata;
1170  SCIP_Bool infeasible;
1171  SCIP_Bool tightened;
1172 
1173  assert(cons != NULL);
1174  assert(SCIPconsGetHdlr(cons) != NULL);
1175  assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
1176  assert(cutoff != NULL);
1177  assert(nchgbds != NULL);
1178  assert(addcut != NULL);
1179  assert(mustcheck != NULL);
1180 
1181  consdata = SCIPconsGetData(cons);
1182  assert(consdata != NULL);
1183  assert(consdata->nbinvars == 0 || consdata->binvars != NULL);
1184  assert(0 <= consdata->nfixedzeros && consdata->nfixedzeros <= consdata->nbinvars);
1185  assert(0 <= consdata->nfixedones && consdata->nfixedones <= consdata->nbinvars);
1186 
1187  /* ensure that the binary variables are sorted in non-decreasing order w.r.t. their coefficients */
1188  consdataSort(consdata);
1189 
1190  /* in case there is only at most one binary variables, the constraints should already be disabled */
1191  assert(consdata->nbinvars > 1);
1192 
1193  if( *cutoff )
1194  return SCIP_OKAY;
1195 
1196  if( consdata->nfixedones == 1 )
1197  {
1198  /* exactly one variable is fixed to 1:
1199  * - all other binary variables in a set partitioning must be zero
1200  * - integer variable are fixed to that binary variable
1201  */
1202  if( consdata->nfixedzeros < consdata->nbinvars - 1 ||
1203  SCIPisLT(scip, SCIPvarGetLbLocal(consdata->intvar), SCIPvarGetUbLocal(consdata->intvar)) )
1204  {
1205  SCIP_VAR** vars;
1206  SCIP_VAR* var;
1207 #ifndef NDEBUG
1208  SCIP_Bool fixedonefound;
1209 #endif
1210  int nvars;
1211  int v;
1212 
1213  SCIPdebugMsg(scip, " -> fixing all other variables to zero due to the set partitioning condition <%s>\n",
1214  SCIPconsGetName(cons));
1215 
1216  /* unfixed variables exist: fix them to zero;
1217  * this could result in additional variables fixed to one due to aggregations; in this case, the
1218  * constraint is infeasible in local bounds
1219  */
1220  vars = consdata->binvars;
1221  nvars = consdata->nbinvars;
1222 #ifndef NDEBUG
1223  fixedonefound = FALSE;
1224 #endif
1225 
1226  for( v = 0; v < nvars && consdata->nfixedones == 1 && !(*cutoff); ++v )
1227  {
1228  var = vars[v];
1229  assert(SCIPvarIsBinary(var));
1230  if( SCIPvarGetLbLocal(var) < 0.5 )
1231  {
1232  SCIP_CALL( SCIPinferBinvarCons(scip, var, FALSE, cons, -1, &infeasible, &tightened) );
1233  assert(!infeasible);
1234  SCIPdebugMsg(scip, " -> fixed <%s> to zero (tightened=%u)\n", SCIPvarGetName(var), tightened);
1235  }
1236  else
1237  {
1238 #ifndef NDEBUG
1239  fixedonefound = TRUE;
1240 #endif
1241  /* fix integer variable */
1242  SCIP_CALL( consFixInteger(scip, cons, v, cutoff) );
1243  }
1244  }
1245  if( !(*cutoff) )
1246  {
1247  /* the fixed to one variable must have been found, and at least one variable must have been fixed */
1248  assert(consdata->nfixedones >= 1 || fixedonefound);
1249 
1250  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1251  (*nchgbds)++;
1252  }
1253  }
1254 
1255  /* now all other variables are fixed to zero:
1256  * the constraint is feasible, and if it's not modifiable, it is redundant
1257  */
1258  if( !SCIPconsIsModifiable(cons) && consdata->nfixedones == 1 )
1259  {
1260  SCIPdebugMsg(scip, " -> disabling set linking constraint <%s>\n", SCIPconsGetName(cons));
1261  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
1262  }
1263  }
1264  else if( consdata->nfixedones >= 2 )
1265  {
1266  /* at least two variables are fixed to 1:
1267  * - the set partitioning condition is violated
1268  */
1269  SCIPdebugMsg(scip, " -> conflict on " CONSHDLR_NAME " constraint <%s> due to the set partitioning condition\n", SCIPconsGetName(cons));
1270 
1271  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1272 
1273  /* conflict analysis can only be applied in solving stage and if it is applicable */
1275  {
1276  SCIP_VAR** vars;
1277  int nvars;
1278  int n;
1279  int v;
1280 
1281  vars = consdata->binvars;
1282  nvars = consdata->nbinvars;
1283 
1284  /* initialize conflict analysis, and add the two variables assigned to one to conflict candidate queue */
1286 
1287  n = 0;
1288 
1289  for( v = 0; v < nvars && n < 2; ++v )
1290  {
1291  if( SCIPvarGetLbLocal(vars[v]) > 0.5 )
1292  {
1293  SCIP_CALL( SCIPaddConflictBinvar(scip, vars[v]) );
1294  n++;
1295  }
1296  }
1297  assert(n == 2);
1298 
1299  /* analyze the conflict */
1300  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
1301  }
1302 
1303  *cutoff = TRUE;
1304  }
1305  else if( consdata->nfixedzeros == consdata->nbinvars )
1306  {
1307  /* all variables are fixed to zero:
1308  * - the set partitioning condition is violated, and if it's unmodifiable, the node
1309  * can be cut off -- otherwise, the constraint must be added as a cut and further pricing must
1310  * be performed
1311  */
1312  assert(consdata->nfixedones == 0);
1313 
1314  SCIPdebugMsg(scip, " -> " CONSHDLR_NAME " constraint <%s> is infeasible due to the set partitioning condition\n",
1315  SCIPconsGetName(cons));
1316 
1317  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1318  if( SCIPconsIsModifiable(cons) )
1319  *addcut = TRUE;
1320  else
1321  {
1322  /* conflict analysis can only be applied in solving stage and if it is applicable */
1324  {
1325  SCIP_VAR** vars;
1326  int nvars;
1327  int v;
1328 
1329  vars = consdata->binvars;
1330  nvars = consdata->nbinvars;
1331 
1332  /* initialize conflict analysis, add all variables of infeasible constraint to conflict candidate queue */
1334 
1335  for( v = 0; v < nvars; ++v )
1336  {
1337  assert(SCIPvarGetUbLocal(vars[v]) < 0.5);
1338  SCIP_CALL( SCIPaddConflictBinvar(scip, vars[v]) );
1339  }
1340 
1341  /* analyze the conflict */
1342  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
1343  }
1344  *cutoff = TRUE;
1345  }
1346  }
1347  else if( consdata->nfixedzeros == consdata->nbinvars - 1 )
1348  {
1349  /* all variables except one are fixed to zero:
1350  * - an unmodifiable set partitioning constraint is feasible and can be disabled after the
1351  * remaining variable is fixed to one
1352  * - a modifiable set partitioning constraint must be checked manually
1353  */
1354  assert(consdata->nfixedones == 0);
1355 
1356  if( !SCIPconsIsModifiable(cons) )
1357  {
1358  SCIP_VAR** vars;
1359  SCIP_VAR* var;
1360  int nvars;
1361  int v;
1362 
1363  /* search the single variable that can be fixed */
1364  vars = consdata->binvars;
1365  nvars = consdata->nbinvars;
1366  for( v = 0; v < nvars && !(*cutoff); ++v )
1367  {
1368  var = vars[v];
1369  assert(SCIPisFeasZero(scip, SCIPvarGetLbLocal(var)));
1370  assert(SCIPisFeasZero(scip, SCIPvarGetUbLocal(var)) || SCIPisFeasEQ(scip, SCIPvarGetUbLocal(var), 1.0));
1371  if( SCIPvarGetUbLocal(var) > 0.5 )
1372  {
1373  assert(SCIPvarGetLbLocal(var) < 0.5);
1374  SCIPdebugMsg(scip, " -> fixing remaining binary variable <%s> to one in " CONSHDLR_NAME " constraint <%s>\n",
1375  SCIPvarGetName(var), SCIPconsGetName(cons));
1376 
1377  SCIP_CALL( SCIPinferBinvarCons(scip, var, TRUE, cons, -1, &infeasible, &tightened) );
1378  assert(!infeasible);
1379  assert(tightened);
1380 
1381  /* fix integer variable */
1382  SCIP_CALL( consFixInteger(scip, cons, v, cutoff) );
1383  break;
1384  }
1385  }
1386  assert(v < nvars);
1387  assert(consdata->nfixedzeros == consdata->nbinvars - 1);
1388  assert(consdata->nfixedones == 1);
1389 
1390  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
1391  (*nchgbds)++;
1392  }
1393  }
1394  else
1395  {
1396  SCIP_CALL( tightenedIntvar(scip, cons, consdata, cutoff, nchgbds) );
1397  }
1398 
1399  *mustcheck = (*nchgbds) == 0;
1400 
1401  assert(consdata->nfixedzeros + consdata->nfixedones <= consdata->nbinvars);
1402 
1403  return SCIP_OKAY;
1404 }
1405 
1406 /** returns whether the given solution is feasible for the given linking constraint */
1407 static
1409  SCIP* scip, /**< SCIP data structure */
1410  SCIP_CONS* cons, /**< linking constraint to be checked */
1411  SCIP_SOL* sol /**< primal solution, or NULL for current LP/pseudo solution */
1412  )
1413 {
1414  SCIP_CONSDATA* consdata;
1415  SCIP_VAR** binvars;
1416  int* vals;
1417  SCIP_Real solval;
1418  SCIP_Real linksum;
1419  SCIP_Real setpartsum;
1420  SCIP_Real setpartsumbound;
1421  int nbinvars;
1422  int b;
1423 
1424  assert(scip != NULL);
1425  assert(cons != NULL);
1426 
1427  SCIPdebugMsg(scip, "checking linking constraint <%s> for feasibility of solution %p\n", SCIPconsGetName(cons), (void*)sol);
1428 
1429  consdata = SCIPconsGetData(cons);
1430  assert(consdata != NULL);
1431  assert(consdata->binvars != NULL || consdata->nbinvars == 0);
1432 
1433  /* in case there is only at most one binary variables, the constraints should already be disabled */
1434  assert(consdata->nbinvars > 1);
1435 
1436  /* calculate the constraint's activity for the linking part and the set partitioning part */
1437  binvars = consdata->binvars;
1438  vals = consdata->vals;
1439  nbinvars = consdata->nbinvars;
1440 
1441  linksum = 0.0;
1442  setpartsum = 0.0;
1443  setpartsumbound = 1.0 + 2*SCIPfeastol(scip);
1444 
1445  for( b = 0; b < nbinvars && setpartsum < setpartsumbound; ++b ) /* if sum >= sumbound, the feasibility is clearly decided */
1446  {
1447  assert(SCIPvarIsBinary(binvars[b]));
1448 
1449  solval = SCIPgetSolVal(scip, sol, binvars[b]);
1450  assert(SCIPisFeasGE(scip, solval, 0.0) && SCIPisFeasLE(scip, solval, 1.0));
1451 
1452  linksum += vals[b] * solval;
1453  setpartsum += solval;
1454  }
1455 
1456  /* check if the fixed binary variable match with the integer variable */
1457  return SCIPisFeasEQ(scip, linksum, SCIPgetSolVal(scip, sol, consdata->intvar)) && SCIPisFeasEQ(scip, setpartsum, 1.0);
1458 }
1459 
1460 #if 0
1461 /** transfer aggregated integer variables to the corresponding binary variables */
1462 static
1464  SCIP* scip, /**< SCIP data structure */
1465  SCIP_HASHMAP* varmap, /**< hash map mapping a integer variables to its linking constraint */
1466  SCIP_CONS** conss, /**< array of linking constraint */
1467  int nconss, /**< number of linking constraints */
1468  int* naggrvars, /**< pointer to store the number of aggregate variables */
1469  SCIP_Bool* cutoff /**< pointer to store if a cutoff was detected */
1470  )
1471 {
1472  SCIP_CONS* aggrcons;
1473  SCIP_CONSDATA* aggrconsdata;
1474  SCIP_CONSDATA* consdata;
1475  SCIP_VAR** binvars;
1476  SCIP_VAR** aggrbinvars;
1477  SCIP_VAR* intvar;
1478  SCIP_VAR* aggrvar;
1479  SCIP_Real aggrconst;
1480  SCIP_Real aggrscalar;
1481  SCIP_Bool infeasible;
1482  SCIP_Bool redundant;
1483  SCIP_Bool aggregated;
1484  int offset;
1485  int aggroffset;
1486  int nbinvars;
1487  int shift;
1488  int b;
1489  int c;
1490 
1491  assert(varmap != NULL);
1492 
1493  for( c = 0; c < nconss; ++c )
1494  {
1495  consdata = SCIPconsGetData(conss[c]);
1496  assert(consdata != NULL);
1497 
1498  intvar = consdata->intvar;
1499  assert(intvar != NULL);
1500 
1502  {
1503  aggrvar = SCIPvarGetAggrVar(intvar);
1504  aggrcons = (SCIP_CONS*) SCIPhashmapGetImage(varmap, getHashmapKey(aggrvar));
1505 
1506  /* check if the aggregate variable belongs to a linking constraint */
1507  if( aggrcons != NULL )
1508  {
1509  aggrconsdata = SCIPconsGetData(aggrcons);
1510  assert(aggrconsdata != NULL);
1511 
1512  aggrconst = SCIPvarGetAggrConstant(intvar);
1513  aggrscalar = SCIPvarGetAggrScalar(intvar);
1514 
1515  /**@todo extend the aggregation for those cases were the aggrscalar is not equal to 1.0 */
1516  if( SCIPisEQ(scip, aggrscalar, 1.0 ) )
1517  {
1518  /* since both variables are integer variable and the aggrscalar is 1.0 the aggrconst should
1519  * integral
1520  */
1521  assert(SCIPisIntegral(scip, aggrconst));
1522  shift = SCIPconvertRealToInt(scip, aggrconst);
1523 
1524  offset = consdata->offset;
1525  binvars = consdata->binvars;
1526  aggroffset = aggrconsdata->offset;
1527  aggrbinvars = aggrconsdata->binvars;
1528 
1529  nbinvars = MIN(consdata->nbinvars + offset, aggrconsdata->nbinvars + shift + aggroffset);
1530 
1531  for( b = MAX(offset, aggroffset-shift); b < nbinvars; ++b )
1532  {
1533  assert(b - offset >= 0);
1534  assert(b + shift - aggroffset >= 0);
1535  assert(b < consdata->nbinvars);
1536  assert(b < aggrconsdata->nbinvars - shift);
1537 
1538  /* add aggregation x - y = 0.0 */
1539  SCIP_CALL( SCIPaggregateVars(scip, binvars[b-offset], aggrbinvars[b+shift-aggroffset], 1.0, -1.0, 0.0,
1540  &infeasible, &redundant, &aggregated) );
1541 
1542  if( infeasible )
1543  {
1544  (*cutoff) = TRUE;
1545  return SCIP_OKAY;
1546  }
1547 
1548  if( aggregated )
1549  (*naggrvars)++;
1550  }
1551  }
1552  }
1553  }
1554  }
1555  return SCIP_OKAY;
1556 }
1557 #endif
1558 
1559 /** create two rows for the linking constraint
1560  *
1561  * - row1: {sum_{b=1}^n-1 vals[b] * binvars[b]} - intvar = 0
1562  * - row2: {sum_{b=0}^n-1 binvars[b]} = 1.0
1563  */
1564 static
1566  SCIP* scip, /**< SCIP data structure */
1567  SCIP_CONS* cons /**< linking constraint */
1568  )
1569 {
1570  SCIP_CONSDATA* consdata;
1571  char rowname[SCIP_MAXSTRLEN];
1572  int b;
1573 
1574  assert( cons != NULL);
1575 
1576  /* get constraint data */
1577  consdata = SCIPconsGetData(cons);
1578  assert(consdata != NULL);
1579  assert(consdata->row1 == NULL);
1580  assert(consdata->row2 == NULL);
1581  assert(consdata->nbinvars > 1);
1582 
1583  /* create the LP row which captures the linking between the integer and binary variables */
1584  (void)SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s[link]", SCIPconsGetName(cons));
1585 
1586  SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row1, SCIPconsGetHdlr(cons), rowname, 0.0, 0.0,
1588 
1589  /* add integer variable to the row */
1590  assert(consdata->intvar != NULL);
1591  SCIP_CALL( SCIPaddVarToRow(scip, consdata->row1, consdata->intvar, -1.0) );
1592 
1593  /* adding all except the first binary variable to the row */
1594  assert(consdata->binvars != NULL);
1595  for( b = 0; b < consdata->nbinvars; ++b )
1596  {
1597  SCIP_CALL( SCIPaddVarToRow(scip, consdata->row1, consdata->binvars[b], (SCIP_Real)consdata->vals[b]) );
1598  }
1599 
1600  /* create the LP row which captures the set partitioning condition of the binary variables */
1601  (void)SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s[setppc]", SCIPconsGetName(cons));
1602  assert( consdata->nbinvars > 0 );
1603 
1604  SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row2, SCIPconsGetHdlr(cons), rowname, 1.0, 1.0,
1606 
1607  SCIP_CALL( SCIPaddVarsToRowSameCoef(scip, consdata->row2, consdata->nbinvars, consdata->binvars, 1.0) );
1608 
1609  return SCIP_OKAY;
1610 }
1611 
1612 
1613 /** adds linking constraint as cut to the LP */
1614 static
1616  SCIP* scip, /**< SCIP data structure */
1617  SCIP_CONS* cons, /**< linking constraint */
1618  SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
1619  SCIP_Bool* cutoff /**< whether a cutoff has been detected */
1620  )
1621 {
1622  SCIP_CONSDATA* consdata;
1623 
1624  assert( cutoff != NULL );
1625  *cutoff = FALSE;
1626 
1627  consdata = SCIPconsGetData(cons);
1628  assert(consdata != NULL);
1629 
1630  /* in case there is only at most one binary variables, the constraints should already be disabled */
1631  assert(consdata->nbinvars > 1);
1632 
1633  if( consdata->row1 == NULL )
1634  {
1635  assert(consdata->row2 == NULL);
1636 
1637  /* convert linking data into LP rows */
1638  SCIP_CALL( createRows(scip, cons) );
1639  }
1640  assert(consdata->row1 != NULL);
1641  assert(consdata->row2 != NULL);
1642 
1643  /* insert LP linking row as cut */
1644  if( !SCIProwIsInLP(consdata->row1) )
1645  {
1646  SCIPdebugMsg(scip, "adding linking row of constraint <%s> as cut to the LP\n", SCIPconsGetName(cons));
1647  SCIP_CALL( SCIPaddCut(scip, sol, consdata->row1, TRUE/*FALSE*/, cutoff) );
1648  }
1649 
1650  /* insert LP set partitioning row as cut */
1651  if( !SCIProwIsInLP(consdata->row2) )
1652  {
1653  SCIPdebugMsg(scip, "adding set partitioning row of constraint <%s> as cut to the LP\n", SCIPconsGetName(cons));
1654  SCIP_CALL( SCIPaddCut(scip, sol, consdata->row2, TRUE/*FALSE*/, cutoff) );
1655  }
1656 
1657  return SCIP_OKAY;
1658 }
1659 
1660 
1661 /** checks constraint for violation, and adds it as a cuts if possible */
1662 static
1664  SCIP* scip, /**< SCIP data structure */
1665  SCIP_CONS* cons, /**< linking constraint to be separated */
1666  SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
1667  SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
1668  SCIP_Bool* separated, /**< pointer to store TRUE, if a cut was found */
1669  int* nchgbds /**< pointer to store the number of changed variables bounds */
1670  )
1671 {
1672  SCIP_CONSDATA* consdata;
1673  SCIP_Bool addcut;
1674  SCIP_Bool mustcheck;
1675 
1676  assert(cons != NULL);
1677  assert(SCIPconsGetHdlr(cons) != NULL);
1678  assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
1679  assert(cutoff != NULL);
1680  assert(separated != NULL);
1681  assert(nchgbds != NULL);
1682 
1683  consdata = SCIPconsGetData(cons);
1684  assert(consdata != NULL);
1685 
1686  /* in case there is only at most one binary variables, the constraints should already be disabled */
1687  assert(consdata->nbinvars > 1);
1688 
1689  SCIPdebugMsg(scip, "separating constraint <%s>\n", SCIPconsGetName(cons));
1690 
1691  *cutoff = FALSE;
1692  addcut = FALSE;
1693  mustcheck = TRUE;
1694 
1695  /* check constraint for violation only looking at the fixed variables, apply further fixings if possible */
1696  if( sol == NULL )
1697  {
1698  SCIP_CALL( processIntegerBoundChg(scip, cons, cutoff, nchgbds, &mustcheck) );
1699  }
1700 
1701  if( mustcheck && !(*cutoff) )
1702  {
1703  /* variable's fixings didn't give us any information -> we have to check the constraint */
1704  if( sol == NULL && consdata->row1 != NULL )
1705  {
1706  SCIP_Real feasibility;
1707  SCIP_Real tmp;
1708 
1709  assert(consdata->row2 != NULL);
1710 
1711  /* skip constraints already in the LP */
1712  if( SCIProwIsInLP(consdata->row1) && SCIProwIsInLP(consdata->row2))
1713  return SCIP_OKAY;
1714 
1715  feasibility = 1.0;
1716 
1717  /* check first row (linking) for feasibility */
1718  if( !SCIProwIsInLP(consdata->row1) )
1719  {
1720  tmp = SCIPgetRowLPFeasibility(scip, consdata->row1);
1721  feasibility = MIN(feasibility, tmp);
1722  }
1723 
1724  /* check second row (setppc) for feasibility */
1725  if( !SCIProwIsInLP(consdata->row2) )
1726  {
1727  tmp = SCIPgetRowLPFeasibility(scip, consdata->row2);
1728  feasibility = MIN(feasibility, tmp);
1729  }
1730  addcut = SCIPisFeasNegative(scip, feasibility);
1731  }
1732  else
1733  addcut = !checkCons(scip, cons, sol);
1734 
1735 
1736  if( !addcut )
1737  {
1738  /* constraint was feasible -> increase age */
1739  SCIP_CALL( SCIPincConsAge(scip, cons) );
1740  }
1741  }
1742 
1743  if( addcut )
1744  {
1745  /* insert LP row as cut */
1746  assert(!(*cutoff));
1747  SCIP_CALL( addCuts(scip, cons, sol, cutoff) );
1748  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1749  *separated = TRUE;
1750  }
1751 
1752  return SCIP_OKAY;
1753 }
1754 
1755 /** enforces the pseudo solution on the given constraint */
1756 static
1758  SCIP* scip, /**< SCIP data structure */
1759  SCIP_CONS* cons, /**< linking constraint to be separated */
1760  SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
1761  SCIP_Bool* infeasible, /**< pointer to store TRUE, if the constraint was infeasible */
1762  int* nchgbds, /**< pointer to store the number of changed variable bounds */
1763  SCIP_Bool* solvelp /**< pointer to store TRUE, if the LP has to be solved */
1764  )
1765 {
1766  SCIP_Bool addcut;
1767  SCIP_Bool mustcheck;
1768 
1769  assert(!SCIPhasCurrentNodeLP(scip));
1770  assert(cons != NULL);
1771  assert(SCIPconsGetHdlr(cons) != NULL);
1772  assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
1773  assert(cutoff != NULL);
1774  assert(infeasible != NULL);
1775  assert(nchgbds != NULL);
1776  assert(solvelp != NULL);
1777 
1778  addcut = FALSE;
1779  mustcheck = TRUE;
1780 
1781  /* check constraint for violation only looking at the fixed variables, apply further fixings if possible */
1782  SCIP_CALL( processIntegerBoundChg(scip, cons, cutoff, nchgbds, &mustcheck) );
1783  SCIP_CALL( processBinvarFixings(scip, cons, cutoff, nchgbds, &addcut, &mustcheck) );
1784 
1785  if( mustcheck )
1786  {
1787  assert(!addcut);
1788 
1789  if( checkCons(scip, cons, NULL) )
1790  {
1791  /* constraint was feasible -> increase age */
1792  SCIP_CALL( SCIPincConsAge(scip, cons) );
1793  }
1794  else
1795  {
1796  /* constraint was infeasible -> reset age */
1797  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1798  *infeasible = TRUE;
1799  }
1800  }
1801 
1802  if( addcut )
1803  {
1804  assert(!(*cutoff));
1805  /* a cut must be added to the LP -> we have to solve the LP immediately */
1806  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1807  *solvelp = TRUE;
1808  }
1809 
1810  return SCIP_OKAY;
1811 }
1812 
1813 /** helper function to enforce constraints */
1814 static
1816  SCIP* scip, /**< SCIP data structure */
1817  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1818  SCIP_CONS** conss, /**< constraints to process */
1819  int nconss, /**< number of constraints */
1820  int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
1821  SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
1822  SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
1823  )
1824 {
1825  SCIP_Bool cutoff;
1826  SCIP_Bool separated;
1827  int nchgbds;
1828  int c;
1829 
1830  assert(conshdlr != NULL);
1831  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
1832  assert(nconss == 0 || conss != NULL);
1833  assert(result != NULL);
1834 
1835  SCIPdebugMsg(scip, "Enforcing %d linking constraints for %s solution\n", nconss, sol == NULL ? "LP" : "relaxation");
1836 
1837  cutoff = FALSE;
1838  separated = FALSE;
1839  nchgbds = 0;
1840 
1841  /* check all useful linking constraints for feasibility */
1842  for( c = 0; c < nusefulconss && !cutoff && nchgbds == 0; ++c )
1843  {
1844  SCIP_CALL( separateCons(scip, conss[c], sol, &cutoff, &separated, &nchgbds) );
1845  }
1846 
1847  /* check all obsolete linking constraints for feasibility */
1848  for( c = nusefulconss; c < nconss && !cutoff && !separated && nchgbds == 0; ++c )
1849  {
1850  SCIP_CALL( separateCons(scip, conss[c], sol, &cutoff, &separated, &nchgbds) );
1851  }
1852 
1853  /* return the correct result */
1854  if( cutoff )
1855  *result = SCIP_CUTOFF;
1856  else if( nchgbds > 0 )
1857  *result = SCIP_REDUCEDDOM;
1858  else if( separated )
1859  *result = SCIP_SEPARATED;
1860  else
1861  *result = SCIP_FEASIBLE;
1862 
1863  return SCIP_OKAY;
1864 }
1865 
1866 
1867 /*
1868  * Callback methods of constraint handler
1869  */
1870 
1871 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
1872 static
1873 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinking)
1874 { /*lint --e{715}*/
1875  assert(scip != NULL);
1876  assert(conshdlr != NULL);
1877  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
1878 
1879  /* call inclusion method of constraint handler */
1881 
1882  *valid = TRUE;
1883 
1884  return SCIP_OKAY;
1885 }
1886 
1887 /** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
1888 static
1889 SCIP_DECL_CONSFREE(consFreeLinking)
1890 {
1891  SCIP_CONSHDLRDATA* conshdlrdata;
1892 
1893  assert(conshdlr != NULL);
1894  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
1895  assert(scip != NULL);
1896 
1897  /* free constraint handler data */
1898  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1899  assert(conshdlrdata != NULL);
1900 
1901  SCIP_CALL( conshdlrdataFree(scip, &conshdlrdata) );
1902 
1903  return SCIP_OKAY;
1904 }
1905 
1906 
1907 /** presolving initialization method of constraint handler (called when presolving is about to begin) */
1908 static
1909 SCIP_DECL_CONSINITPRE(consInitpreLinking)
1910 { /*lint --e{715}*/
1911  SCIP_CONSHDLRDATA* conshdlrdata;
1912  SCIP_CONSDATA* consdata;
1913  int c;
1914 
1915  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1916  assert(conshdlrdata != NULL);
1917 
1918  /* disable all linking constraints which contain at most one binary variable */
1919  for( c = 0; c < nconss; ++c )
1920  {
1921  consdata = SCIPconsGetData(conss[c]);
1922  assert(consdata != NULL);
1923 
1924  /* skip constraints which are not added */
1925  if( !SCIPconsIsAdded(conss[c]) )
1926  continue;
1927 
1928  if( consdata->nbinvars <= 1 )
1929  {
1930  SCIP_CALL( SCIPdisableCons(scip, conss[c]) );
1931  assert(consdata->nbinvars == 0 || SCIPvarGetLbGlobal(consdata->binvars[0]) > 0.5);
1932  }
1933  else if( conshdlrdata->linearize )
1934  {
1935  SCIP_CALL( consdataLinearize(scip, conss[c], consdata) );
1936  SCIP_CALL( SCIPdelCons(scip, conss[c]) );
1937  }
1938  }
1939 
1940  return SCIP_OKAY;
1941 }
1942 
1943 
1944 /** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
1945 static
1946 SCIP_DECL_CONSEXITSOL(consExitsolLinking)
1947 { /*lint --e{715}*/
1948  SCIP_CONSDATA* consdata;
1949  int c;
1950 
1951  for( c = 0; c < nconss; ++c )
1952  {
1953  consdata = SCIPconsGetData(conss[c]);
1954  assert(consdata != NULL);
1955 
1956  /* release the rows of all constraints */
1957  if( consdata->row1 != NULL )
1958  {
1959  assert(consdata->row2 != NULL);
1960 
1961  SCIP_CALL( SCIPreleaseRow(scip, &consdata->row1) );
1962  SCIP_CALL( SCIPreleaseRow(scip, &consdata->row2) );
1963  }
1964  }
1965 
1966  return SCIP_OKAY;
1967 }
1968 
1969 
1970 /** frees specific constraint data */
1971 static
1972 SCIP_DECL_CONSDELETE(consDeleteLinking)
1973 { /*lint --e{715}*/
1974  SCIP_CONSHDLRDATA* conshdlrdata;
1975 
1976  assert(conshdlr != NULL);
1977  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
1978  assert(consdata != NULL);
1979  assert(*consdata != NULL);
1980 
1981  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1982  assert(conshdlrdata != NULL);
1983  assert(conshdlrdata->eventhdlr != NULL);
1984 
1985  /* remove linking constraint form variable hash map */
1986  assert(conshdlrdata->varmap != NULL);
1987  assert(SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey((*consdata)->intvar)));
1988  SCIP_CALL( SCIPhashmapRemove(conshdlrdata->varmap, getHashmapKey((*consdata)->intvar)) );
1989 
1990  if( (*consdata)->nbinvars > 0 && SCIPisTransformed(scip) )
1991  {
1992  SCIP_CALL( dropAllEvents(scip, *consdata, conshdlrdata->eventhdlr) );
1993  }
1994 
1995  /* free consdata */
1996  SCIP_CALL( consdataFree(scip, consdata) );
1997 
1998  return SCIP_OKAY;
1999 }
2000 
2001 
2002 /** transforms constraint data into data belonging to the transformed problem */
2003 static
2004 SCIP_DECL_CONSTRANS(consTransLinking)
2005 { /*lint --e{715}*/
2006  SCIP_CONSDATA* sourcedata;
2007  SCIP_CONSDATA* targetdata;
2008  SCIP_CONSHDLRDATA* conshdlrdata;
2009 
2010  assert(conshdlr != NULL);
2011  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2012  assert(SCIPgetStage(scip) == SCIP_STAGE_TRANSFORMING);
2013  assert(sourcecons != NULL);
2014  assert(targetcons != NULL);
2015 
2016  /* free constraint handler data */
2017  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2018  assert(conshdlrdata != NULL);
2019  assert(conshdlrdata->eventhdlr != NULL);
2020 
2021  sourcedata = SCIPconsGetData(sourcecons);
2022  assert(sourcedata != NULL);
2023  assert(sourcedata->row1 == NULL); /* in original problem, there cannot be LP rows */
2024  assert(sourcedata->row2 == NULL); /* in original problem, there cannot be LP rows */
2025 
2026  SCIPdebugMsg(scip, "transform linking constraint for variable <%s>\n", SCIPvarGetName(sourcedata->intvar));
2027 
2028  /* create constraint data for target constraint */
2029  SCIP_CALL( consdataCreate(scip, conshdlrdata->eventhdlr, &targetdata,
2030  sourcedata->intvar, sourcedata->binvars, sourcedata->vals, sourcedata->nbinvars) );
2031 
2032  /* create target constraint */
2033  SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
2034  SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
2035  SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
2036  SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
2037  SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
2038 
2039  /* insert (transformed) linking constraint into the hash map */
2040  assert(conshdlrdata->varmap != NULL);
2041  SCIP_CALL( SCIPhashmapInsert(conshdlrdata->varmap, getHashmapKey(targetdata->intvar), *targetcons) );
2042 
2043  return SCIP_OKAY;
2044 }
2045 
2046 /** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
2047 static
2048 SCIP_DECL_CONSINITLP(consInitlpLinking)
2049 { /*lint --e{715}*/
2050  SCIP_CONSDATA* consdata;
2051  int c;
2052 
2053  *infeasible = FALSE;
2054 
2055  for( c = 0; c < nconss && !(*infeasible); ++c )
2056  {
2057  assert(SCIPconsIsInitial(conss[c]));
2058 
2059  consdata = SCIPconsGetData(conss[c]);
2060  assert(consdata != NULL);
2061 
2062  if( consdata->nbinvars <= 1 )
2063  continue;
2064 
2065  SCIP_CALL( addCuts(scip, conss[c], NULL, infeasible) );
2066  }
2067 
2068  return SCIP_OKAY;
2069 }
2070 
2071 
2072 /** separation method of constraint handler for LP solutions */
2073 static
2074 SCIP_DECL_CONSSEPALP(consSepalpLinking)
2075 { /*lint --e{715}*/
2076  SCIP_Bool cutoff;
2077  SCIP_Bool separated;
2078  int nchgbds;
2079  int c;
2080 
2081  assert(conshdlr != NULL);
2082  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2083  assert(nconss == 0 || conss != NULL);
2084  assert(result != NULL);
2085 
2086  SCIPdebugMsg(scip, "separating %d/%d linking constraints\n", nusefulconss, nconss);
2087 
2088  cutoff = FALSE;
2089  separated = FALSE;
2090  nchgbds = 0;
2091 
2092  /* check all useful linking constraints for feasibility */
2093  for( c = 0; c < nusefulconss && !cutoff; ++c )
2094  {
2095  SCIP_CALL( separateCons(scip, conss[c], NULL, &cutoff, &separated, &nchgbds) );
2096  }
2097 
2098  /* return the correct result */
2099  if( cutoff )
2100  *result = SCIP_CUTOFF;
2101  else if( nchgbds > 0 )
2102  *result = SCIP_REDUCEDDOM;
2103  else if( separated )
2104  *result = SCIP_SEPARATED;
2105  else
2106  *result = SCIP_DIDNOTFIND;
2107 
2108  return SCIP_OKAY;
2109 }
2110 
2111 
2112 /** separation method of constraint handler for arbitrary primal solutions */
2113 static
2114 SCIP_DECL_CONSSEPASOL(consSepasolLinking)
2115 { /*lint --e{715}*/
2116  SCIP_Bool cutoff;
2117  SCIP_Bool separated;
2118  int nchgbds;
2119  int c;
2120 
2121  assert(conshdlr != NULL);
2122  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2123  assert(nconss == 0 || conss != NULL);
2124  assert(result != NULL);
2125 
2126  SCIPdebugMsg(scip, "separating %d/%d " CONSHDLR_NAME " constraints\n", nusefulconss, nconss);
2127 
2128  cutoff = FALSE;
2129  separated = FALSE;
2130  nchgbds = 0;
2131 
2132  /* check all useful set partitioning / packing / covering constraints for feasibility */
2133  for( c = 0; c < nusefulconss && !cutoff; ++c )
2134  {
2135  SCIP_CALL( separateCons(scip, conss[c], sol, &cutoff, &separated, &nchgbds) );
2136  }
2137 
2138  /* return the correct result */
2139  if( cutoff )
2140  *result = SCIP_CUTOFF;
2141  else if( nchgbds > 0 )
2142  *result = SCIP_REDUCEDDOM;
2143  else if( separated )
2144  *result = SCIP_SEPARATED;
2145  else
2146  *result = SCIP_DIDNOTFIND;
2147 
2148  return SCIP_OKAY;
2149 }
2150 
2151 
2152 /** constraint enforcing method of constraint handler for LP solutions */
2153 static
2154 SCIP_DECL_CONSENFOLP(consEnfolpLinking)
2155 { /*lint --e{715}*/
2156  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, result) );
2157 
2158  return SCIP_OKAY;
2159 }
2160 
2161 
2162 /** constraint enforcing method of constraint handler for relaxation solutions */
2163 static
2164 SCIP_DECL_CONSENFORELAX(consEnforelaxLinking)
2165 { /*lint --e{715}*/
2166  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
2167 
2168  return SCIP_OKAY;
2169 }
2170 
2171 
2172 /** constraint enforcing method of constraint handler for pseudo solutions */
2173 static
2174 SCIP_DECL_CONSENFOPS(consEnfopsLinking)
2175 { /*lint --e{715}*/
2176  SCIP_Bool cutoff;
2177  SCIP_Bool infeasible;
2178  int nchgbds;
2179  SCIP_Bool solvelp;
2180  int c;
2181 
2182  assert(conshdlr != NULL);
2183  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2184  assert(nconss == 0 || conss != NULL);
2185  assert(result != NULL);
2186 
2187  SCIPdebugMsg(scip, "pseudo enforcing %d " CONSHDLR_NAME " constraints\n", nconss);
2188 
2189  if( objinfeasible )
2190  {
2191  *result = SCIP_DIDNOTRUN;
2192  return SCIP_OKAY;
2193  }
2194 
2195  cutoff = FALSE;
2196  infeasible = FALSE;
2197  nchgbds = 0;
2198  solvelp = FALSE;
2199 
2200  /* check all linking constraint for domain reductions and feasibility */
2201  for( c = 0; c < nconss && !cutoff && !solvelp; ++c )
2202  {
2203  SCIP_CALL( enforcePseudo(scip, conss[c], &cutoff, &infeasible, &nchgbds, &solvelp) );
2204  }
2205 
2206  if( cutoff )
2207  *result = SCIP_CUTOFF;
2208  else if( nchgbds > 0 )
2209  *result = SCIP_REDUCEDDOM;
2210  else if( solvelp )
2211  *result = SCIP_SOLVELP;
2212  else if( infeasible )
2213  *result = SCIP_INFEASIBLE;
2214  else
2215  *result = SCIP_FEASIBLE;
2216 
2217  return SCIP_OKAY;
2218 }
2219 
2220 
2221 /** feasibility check method of constraint handler for integral solutions */
2222 static
2223 SCIP_DECL_CONSCHECK(consCheckLinking)
2224 { /*lint --e{715}*/
2225  SCIP_CONS* cons;
2226  SCIP_CONSDATA* consdata;
2227  int c;
2228 
2229  assert(conshdlr != NULL);
2230  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2231  assert(nconss == 0 || conss != NULL);
2232  assert(result != NULL);
2233 
2234  *result = SCIP_FEASIBLE;
2235 
2236  /* check all linking constraints for feasibility */
2237  for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
2238  {
2239  cons = conss[c];
2240  consdata = SCIPconsGetData(cons);
2241  assert(consdata != NULL);
2242 
2243  if( consdata->nbinvars > 1 && (checklprows || consdata->row1 == NULL || !SCIProwIsInLP(consdata->row1)) )
2244  {
2245  if( !checkCons(scip, cons, sol) )
2246  {
2247  /* constraint is violated */
2248  *result = SCIP_INFEASIBLE;
2249 
2250  if( printreason )
2251  {
2252  int pos;
2253  int b;
2254 
2255  pos = -1;
2256 
2257 #ifndef NDEBUG
2258  for( b = 0; b < consdata->nbinvars; ++b )
2259  {
2260  assert(consdata->binvars[b] != NULL);
2261  assert(SCIPvarIsBinary(consdata->binvars[b]));
2262  }
2263 #endif
2264 
2265  SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
2266  SCIPinfoMessage(scip, NULL, ";\n");
2267 
2268  /* check that at most one binary variable is fixed */
2269  for( b = 0; b < consdata->nbinvars; ++b )
2270  {
2271  assert( SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, sol, consdata->binvars[b])) );
2272 
2273  /* check if binary variable is fixed */
2274  if( SCIPgetSolVal(scip, sol, consdata->binvars[b]) > 0.5 )
2275  {
2276  if( pos != -1 )
2277  {
2278  SCIPinfoMessage(scip, NULL, "violation: more than one binary variable is set to one");
2279  break;
2280  }
2281  pos = b ;
2282  }
2283  }
2284 
2285  /* check that at least one binary variable is fixed */
2286  if( pos == -1 )
2287  {
2288  SCIPinfoMessage(scip, NULL, "violation: none of the binary variables is set to one");
2289  }
2290  else if( !SCIPisFeasEQ(scip, (SCIP_Real) (consdata->vals[pos]), SCIPgetSolVal(scip, sol, consdata->intvar)) )
2291  {
2292  /* check if the fixed binary variable match with the integer variable */
2293  SCIPinfoMessage(scip, NULL, "violation: <%s> = <%g> and <%s> is one\n",
2294  SCIPvarGetName(consdata->intvar), SCIPgetSolVal(scip, sol, consdata->intvar),
2295  SCIPvarGetName(consdata->binvars[pos]) );
2296  }
2297  }
2298  }
2299  }
2300  }
2301 
2302  return SCIP_OKAY;
2303 }
2304 
2305 /** domain propagation method of constraint handler */
2306 static
2307 SCIP_DECL_CONSPROP(consPropLinking)
2308 { /*lint --e{715}*/
2309  SCIP_Bool cutoff;
2310  SCIP_Bool addcut;
2311  SCIP_Bool mustcheck;
2312  int nchgbds;
2313  int c;
2314 
2315  assert(conshdlr != NULL);
2316  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2317  assert(nconss == 0 || conss != NULL);
2318  assert(result != NULL);
2319 
2320  SCIPdebugMsg(scip, "propagating %d/%d " CONSHDLR_NAME " constraints\n", nusefulconss, nconss);
2321 
2322  cutoff = FALSE;
2323  nchgbds = 0;
2324  addcut = FALSE;
2325  mustcheck = TRUE;
2326 
2327  /* propagate all useful set partitioning / packing / covering constraints */
2328  for( c = 0; c < nusefulconss && !cutoff; ++c )
2329  {
2330  SCIP_CALL( processIntegerBoundChg(scip, conss[c], &cutoff, &nchgbds, &mustcheck) );
2331  SCIP_CALL( processBinvarFixings(scip, conss[c], &cutoff, &nchgbds, &addcut, &mustcheck) );
2332  }
2333 
2334  /* return the correct result */
2335  if( cutoff )
2336  *result = SCIP_CUTOFF;
2337  else if( nchgbds > 0 )
2338  *result = SCIP_REDUCEDDOM;
2339  else
2340  *result = SCIP_DIDNOTFIND;
2341 
2342  return SCIP_OKAY;
2343 }
2344 
2345 
2346 /** presolving method of constraint handler */
2347 static
2348 SCIP_DECL_CONSPRESOL(consPresolLinking)
2349 { /*lint --e{715}*/
2350  SCIP_CONSHDLRDATA* conshdlrdata;
2351  int oldnfixedvars;
2352  int oldnchgbds;
2353  int oldnaggrvars;
2354  int oldndelconss;
2355  int firstchange;
2356  int firstclique;
2357  int lastclique;
2358  int c;
2359  SCIP_Bool fixed;
2360  SCIP_Bool cutoff;
2361  SCIP_Bool infeasible;
2362  SCIP_Bool mustcheck;
2363 
2364  assert(conshdlr != NULL);
2365  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2366  assert(scip != NULL);
2367  assert(result != NULL);
2368 
2369  SCIPdebugMsg(scip, "presolve %d linking constraints\n", nconss);
2370 
2371  (*result) = SCIP_DIDNOTFIND;
2372 
2373  oldnchgbds = *nchgbds;
2374  oldnaggrvars = *naggrvars;
2375  oldnfixedvars = *nfixedvars;
2376  oldndelconss = *ndelconss;
2377  cutoff = FALSE;
2378 
2379  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2380  assert(conshdlrdata != NULL);
2381 
2382  /* process constraints */
2383  firstchange = INT_MAX;
2384  firstclique = INT_MAX;
2385  lastclique = -1;
2386 
2387  /* check for each linking constraint the set partitioning condition */
2388  for( c = 0; c < nconss && !SCIPisStopped(scip); ++c )
2389  {
2390  SCIP_CONS* cons;
2391  SCIP_CONSDATA* consdata;
2392 
2393  assert(*result != SCIP_CUTOFF);
2394 
2395  cons = conss[c];
2396  assert(cons != NULL);
2397  assert(!SCIPconsIsModifiable(cons));
2398 
2399  SCIPdebugMsg(scip, "presolve linking constraints <%s>\n", SCIPconsGetName(cons));
2400 
2401  consdata = SCIPconsGetData(cons);
2402  assert(consdata != NULL);
2403 
2404  if( !SCIPconsIsEnabled(cons) /* || consdata->nbinvars <= 1 */ )
2405  continue;
2406 
2407  /* in case there is only at most one binary variables, the constraints should already be disabled */
2408  assert(consdata->nbinvars > 1);
2409 
2410  /*SCIPdebugMsg(scip, "presolving set partitioning / packing / covering constraint <%s>\n", SCIPconsGetName(cons));*/
2411  if( consdata->nfixedones >= 2 )
2412  {
2413  /* at least two variables are fixed to 1:
2414  * - a linking constraint is infeasible due to the set partitioning condition
2415  */
2416  SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> is infeasible\n", SCIPconsGetName(cons));
2417  *result = SCIP_CUTOFF;
2418  return SCIP_OKAY;
2419  }
2420 
2421  if( consdata->nfixedones == 1 )
2422  {
2423  /* exactly one variable is fixed to 1:
2424  * - all other binary variables must be zero due to the set partitioning condition
2425  * - integer variable has to be fixed to corresponding binary variable which is fixed to one
2426  * - if constraint is not modifiable it can be removed
2427  */
2428  SCIP_VAR* var;
2429  int v;
2430 
2431  SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> has a binary variable fixed to 1.0\n", SCIPconsGetName(cons));
2432 
2433  for( v = 0; v < consdata->nbinvars; ++v )
2434  {
2435  var = consdata->binvars[v];
2436  assert(var != NULL);
2437 
2438  if( SCIPvarGetLbGlobal(var) < 0.5 && SCIPvarGetUbGlobal(var) > 0.5 )
2439  {
2440  SCIP_CALL( SCIPfixVar(scip, var, 0.0, &infeasible, &fixed) );
2441 
2442  if( infeasible )
2443  {
2444  SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == 0\n",
2445  SCIPconsGetName(cons), SCIPvarGetName(var));
2446 
2447  *result = SCIP_CUTOFF;
2448  return SCIP_OKAY;
2449  }
2450  assert(fixed);
2451  (*nfixedvars)++;
2452  }
2453  else if( SCIPvarGetLbGlobal(var) > 0.5 )
2454  {
2455  /* fix integer variable */
2456  SCIP_CALL( SCIPfixVar(scip, consdata->intvar, (SCIP_Real)(consdata->vals[v]), &infeasible, &fixed) );
2457 
2458  if( infeasible )
2459  {
2460  SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == %d\n",
2461  SCIPconsGetName(cons), SCIPvarGetName(consdata->intvar), consdata->vals[v]);
2462 
2463  *result = SCIP_CUTOFF;
2464  return SCIP_OKAY;
2465  }
2466 
2467  if( fixed )
2468  (*nfixedvars)++;
2469  }
2470  }
2471 
2472  /* now all other variables are fixed to zero:
2473  * the constraint is feasible, and if it's not modifiable, it is redundant
2474  */
2475  SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> is redundant\n", SCIPconsGetName(cons));
2476  SCIP_CALL( SCIPdelCons(scip, cons) );
2477  (*ndelconss)++;
2478  continue;
2479  }
2480 
2481  if( consdata->nfixedzeros == consdata->nbinvars )
2482  {
2483  /* all variables are fixed to zero:
2484  * - a linking constraint is infeasible due the set partitioning condition
2485  */
2486  assert(consdata->nfixedones == 0);
2487 
2488  SCIPdebugMsg(scip, "linking constraint <%s> is infeasible due to set partitioning condition\n", SCIPconsGetName(cons));
2489  *result = SCIP_CUTOFF;
2490  return SCIP_OKAY;
2491  }
2492 
2493  if( consdata->nfixedzeros == consdata->nbinvars - 1 )
2494  {
2495  /* all variables except one are fixed to zero:
2496  * - a linking constraint is feasible due the set partitioning condition
2497  * - the remaining binary variable can be fixed to one
2498  * - integer variable has to be fixed to corresponding binary variable which is fixed to one
2499  * - constraint can be deleted since it is not modifiable
2500  */
2501  SCIP_VAR* var;
2502  SCIP_Bool found;
2503  int v;
2504 
2505  assert(consdata->nfixedones == 0);
2506 
2507  SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> has only one binary variable not fixed to zero\n",
2508  SCIPconsGetName(cons));
2509 
2510  /* search unfixed variable */
2511  found = FALSE;
2512  var = NULL;
2513  for( v = 0; v < consdata->nbinvars && !found; ++v )
2514  {
2515  var = consdata->binvars[v];
2516  found = SCIPvarGetUbGlobal(var) > 0.5;
2517  }
2518  assert(found);
2519 
2520  /* fix remaining binary variable */
2521  SCIP_CALL( SCIPfixVar(scip, var, 1.0, &infeasible, &fixed) );
2522  if( infeasible )
2523  {
2524  SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == 1\n",
2525  SCIPconsGetName(cons), SCIPvarGetName(var));
2526  *result = SCIP_CUTOFF;
2527  return SCIP_OKAY;
2528  }
2529  assert(fixed);
2530  (*nfixedvars)++;
2531 
2532  /* fix integer variable */
2533  SCIP_CALL( SCIPfixVar(scip, consdata->intvar, (SCIP_Real)(consdata->vals[v]), &infeasible, &fixed) );
2534  if( infeasible )
2535  {
2536  SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == %d\n",
2537  SCIPconsGetName(cons), SCIPvarGetName(consdata->intvar), consdata->vals[v]);
2538 
2539  *result = SCIP_CUTOFF;
2540  return SCIP_OKAY;
2541  }
2542  assert(fixed);
2543  (*nfixedvars)++;
2544 
2545  /* delete constraint from problem */
2546  SCIP_CALL( SCIPdelCons(scip, cons) );
2547  (*ndelconss)++;
2548  continue;
2549  }
2550 
2551  if( consdata->nfixedzeros == consdata->nbinvars - 2 ) /*lint !e641*/
2552  {
2553  SCIP_VAR* var;
2554  SCIP_VAR* var1;
2555  SCIP_VAR* var2;
2556  SCIP_Bool redundant;
2557  SCIP_Bool aggregated;
2558  int v;
2559 
2560  /* aggregate variable, if set partitioning condition consists only of two
2561  * non-fixed variables
2562  */
2563 
2564  /* search unfixed variable */
2565  var1 = NULL;
2566  var2 = NULL;
2567  for( v = 0; v < consdata->nbinvars && var2 == NULL; ++v )
2568  {
2569  var = consdata->binvars[v];
2570  if( SCIPvarGetUbGlobal(var) > 0.5 )
2571  {
2572  if( var1 == NULL )
2573  var1 = var;
2574  else
2575  var2 = var;
2576  }
2577  }
2578  assert(var1 != NULL && var2 != NULL);
2579 
2580  /* aggregate binary equality var1 + var2 == 1 */
2581  SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: aggregate <%s> + <%s> == 1\n",
2582  SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
2583  SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, 1.0, 1.0, &infeasible, &redundant, &aggregated) );
2584 
2585  /* evaluate aggregation result */
2586  if( infeasible )
2587  {
2588  SCIPdebugMsg(scip, "linking constraint <%s>: infeasible aggregation <%s> + <%s> == 1\n",
2589  SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
2590  *result = SCIP_CUTOFF;
2591  return SCIP_OKAY;
2592  }
2593  if( aggregated )
2594  (*naggrvars)++;
2595  }
2596 
2597  /* apply integer bound to binary variables */
2598  SCIP_CALL( processIntegerBoundChg(scip, cons, &cutoff, nchgbds, &mustcheck) );
2599 
2600  /* tightened integer variable */
2601  SCIP_CALL( tightenedIntvar(scip, cons, consdata, &cutoff, nchgbds) );
2602 
2603  /* remove the trailing and leeading binary variable which are fixed to zero */
2604  SCIP_CALL( removeFixedBinvars(scip, conshdlrdata->eventhdlr, cons) );
2605 
2606  if( cutoff )
2607  {
2608  *result = SCIP_CUTOFF;
2609  return SCIP_OKAY;
2610  }
2611 
2612  /* remember the first changed constraint to begin the next redundancy round with */
2613  if( firstchange == INT_MAX )
2614  firstchange = c;
2615 
2616  /* remember the first and last constraints for which we have to add the clique information */
2617  if( !consdata->cliqueadded && consdata->nbinvars >= 2 )
2618  {
2619  if( firstclique == INT_MAX )
2620  firstclique = c;
2621  lastclique = c;
2622  }
2623  }
2624 
2625  /* add clique and implication information */
2626  for( c = firstclique; c < lastclique && !SCIPisStopped(scip); ++c )
2627  {
2628  SCIP_CONS* cons;
2629  SCIP_CONSDATA* consdata;
2630 
2631  assert(*result != SCIP_CUTOFF);
2632 
2633  cons = conss[c];
2634  assert(cons != NULL);
2635 
2636  /* ignore deleted constraints */
2637  if( !SCIPconsIsActive(cons) )
2638  continue;
2639 
2640  consdata = SCIPconsGetData(cons);
2641  assert(consdata != NULL);
2642 
2643  if( !consdata->cliqueadded && consdata->nbinvars >= 3 )
2644  {
2645  /* add set partitioning condition as clique */
2646  int ncliquebdchgs;
2647 
2648  SCIP_CALL( SCIPaddClique(scip, consdata->binvars, NULL, consdata->nbinvars, TRUE, &infeasible, &ncliquebdchgs) );
2649  *nchgbds += ncliquebdchgs;
2650 
2651  if( infeasible )
2652  {
2653  *result = SCIP_CUTOFF;
2654  return SCIP_OKAY;
2655  }
2656 
2657  consdata->cliqueadded = TRUE;
2658  }
2659  }
2660 
2661 #if 0
2662  /* transfer aggregated integer variables to the corresponding binary variables */
2663  assert(conshdlrdata->varmap != NULL);
2664  SCIP_CALL( aggregateVariables(scip, conshdlrdata->varmap, conss, nconss, naggrvars, &cutoff) );
2665 #endif
2666 
2667  if( cutoff )
2668  *result = SCIP_CUTOFF;
2669  else if( oldndelconss < *ndelconss || oldnfixedvars < *nfixedvars || oldnchgbds < *nchgbds || oldnaggrvars < *naggrvars)
2670  *result = SCIP_SUCCESS;
2671 
2672  return SCIP_OKAY;
2673 }
2674 
2675 
2676 /** propagation conflict resolving method of constraint handler */
2677 static
2678 SCIP_DECL_CONSRESPROP(consRespropLinking)
2679 { /*lint --e{715}*/
2680 
2681  SCIP_CONSDATA* consdata;
2682  SCIP_VAR* intvar;
2683  int v;
2684 
2685  SCIPdebugMsg(scip, "conflict resolving method of " CONSHDLR_NAME " constraint handler\n");
2686 
2687  consdata = SCIPconsGetData(cons);
2688  assert(consdata != NULL);
2689 
2690  intvar = consdata->intvar;
2691  assert( intvar != NULL);
2692 
2693  *result = SCIP_DIDNOTFIND;
2694 
2695  if( inferinfo == -1 )
2696  {
2697  /* we have to resolve a fixing of a binary variable which was done due to fixed binary variables */
2698  assert(SCIPvarIsBinary(infervar));
2699  assert(SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, intvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, intvar, bdchgidx, FALSE)));
2700  assert(SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, intvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, intvar, bdchgidx, FALSE)));
2701 
2702  if( boundtype == SCIP_BOUNDTYPE_UPPER )
2703  {
2704  /* we fixed the binary variable to zero since one of the other binary variable was fixed to one (set
2705  * partitioning condition)
2706  */
2707  assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
2708 
2709  for( v = 0; v < consdata->nbinvars; ++v )
2710  {
2711  if( SCIPgetVarLbAtIndex(scip, consdata->binvars[v], bdchgidx, FALSE) > 0.5 )
2712  {
2713  SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->binvars[v]) );
2714  break;
2715  }
2716  }
2717  assert(v < consdata->nbinvars);
2718  }
2719  else
2720  {
2721  /* we fixed the binary variable to one since all other binary variable were fixed to zero */
2722  assert(boundtype == SCIP_BOUNDTYPE_LOWER);
2723  assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) > 0.5);
2724 
2725  for( v = 0; v < consdata->nbinvars; ++v )
2726  {
2727  if( consdata->binvars[v] != infervar )
2728  {
2729  /* the reason variable must be assigned to zero */
2730  assert(SCIPgetVarUbAtIndex(scip, consdata->binvars[v], bdchgidx, FALSE) < 0.5);
2731  SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->binvars[v]) );
2732  }
2733  }
2734  }
2735  }
2736  else if( inferinfo == -2 )
2737  {
2738  /* we have to resolve a fixing of a binary variable which was done due to the integer variable lower bound */
2739  assert(SCIPvarIsBinary(infervar));
2740  assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
2741  assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5); /*@repair: neu*/
2742  assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, FALSE) > 0.5); /*@repair: neu*/
2743  assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, intvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, intvar, bdchgidx, FALSE)) );
2744  assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, intvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, intvar, bdchgidx, FALSE)) );
2745 
2746 
2747  SCIP_CALL( SCIPaddConflictLb( scip, intvar, bdchgidx) );
2748  }
2749  else if( inferinfo == -3 )
2750  {
2751  /* we have to resolve a fixing of a binary variable which was done due to the integer variable upper bound */
2752  assert(SCIPvarIsBinary(infervar));
2753  assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
2754  assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
2755  assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, FALSE) > 0.5);
2756  assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, intvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, intvar, bdchgidx, FALSE)) );
2757  assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, intvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, intvar, bdchgidx, FALSE)) );
2758 
2759  SCIP_CALL( SCIPaddConflictUb( scip, intvar, bdchgidx) );
2760  }
2761  else if( inferinfo == -4 )
2762  {
2763  SCIP_VAR** binvars;
2764  int* vals;
2765  int nbinvars;
2766  int lb;
2767  int b;
2768 
2769  /* we tightened the lower bound of the integer variable due the fixing of the corresponding binary variable to zero */
2770  assert(infervar == intvar);
2771  assert(boundtype == SCIP_BOUNDTYPE_LOWER);
2772 
2773  binvars = consdata->binvars;
2774  nbinvars = consdata->nbinvars;
2775  vals = consdata->vals;
2776 
2777  /* get propagated lower bound */
2778  lb = SCIPconvertRealToInt(scip, SCIPgetVarLbAtIndex(scip, intvar, bdchgidx, TRUE));
2779 
2780  for( b = 0; b < nbinvars; ++b )
2781  {
2782  if( vals[b] >= lb )
2783  break;
2784 
2785  assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
2786  SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
2787  }
2788  }
2789  else if( inferinfo == -5 )
2790  {
2791  SCIP_VAR** binvars;
2792  int* vals;
2793  int nbinvars;
2794  int ub;
2795  int b;
2796 
2797  /* we tightened the upper bound of the integer variable due the fixing of the corresponding binary variable two zero */
2798 
2799  assert(infervar == intvar);
2800  assert(boundtype == SCIP_BOUNDTYPE_UPPER);
2801 
2802  binvars = consdata->binvars;
2803  nbinvars = consdata->nbinvars;
2804  vals = consdata->vals;
2805 
2806  /* get old and new upper bound */
2807  ub = SCIPconvertRealToInt(scip, SCIPgetVarUbAtIndex(scip, intvar, bdchgidx, TRUE));
2808 
2809  /* resolve tightening of upper bound of the integer variable by binary variables */
2810  for( b = nbinvars - 1; b >= 0; --b )
2811  {
2812  if( vals[b] <= ub )
2813  break;
2814 
2815  assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
2816  SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
2817  }
2818  }
2819  else if( inferinfo == -6 )
2820  {
2821  /* we fixed a binary variable to one since the integer variable was fixed */
2822  assert(SCIPvarIsBinary(infervar));
2823  assert(boundtype == SCIP_BOUNDTYPE_LOWER);
2824  assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, intvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, intvar, bdchgidx, FALSE)) );
2825  assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, intvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, intvar, bdchgidx, FALSE)) );
2826  assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, intvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, intvar, bdchgidx, FALSE)) );
2827  assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, intvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, intvar, bdchgidx, FALSE)) );
2828 
2829  assert( !SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, FALSE)) );
2830 
2831  SCIP_CALL( SCIPaddConflictLb( scip, intvar, bdchgidx) );
2832  SCIP_CALL( SCIPaddConflictUb( scip, intvar, bdchgidx) );
2833  }
2834  else
2835  {
2836  /* we fixed the integer variable to (vals[inferinfo]) since the corresponding binary variable was fixed to one */
2837  assert(infervar == intvar);
2838  assert(inferinfo >= 0);
2839  assert(inferinfo < consdata->nbinvars);
2840  assert(consdata->vals[inferinfo] == SCIPconvertRealToInt(scip, SCIPgetVarUbAtIndex(scip, consdata->intvar, bdchgidx, TRUE))
2841  || consdata->vals[inferinfo] == SCIPconvertRealToInt(scip, SCIPgetVarLbAtIndex(scip, consdata->intvar, bdchgidx, TRUE)));
2842 
2843  assert(SCIPgetVarLbAtIndex(scip, consdata->binvars[inferinfo], bdchgidx, FALSE) > 0.5);
2844  SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->binvars[inferinfo]) );
2845  }
2846 
2847  *result = SCIP_SUCCESS;
2848 
2849  return SCIP_OKAY;
2850 }
2851 
2852 /** variable rounding lock method of constraint handler */
2853 static
2854 SCIP_DECL_CONSLOCK(consLockLinking)
2855 { /*lint --e{715}*/
2856  SCIP_CONSDATA* consdata;
2857  int b;
2858 
2859  consdata = SCIPconsGetData(cons);
2860  assert(consdata != NULL);
2861 
2862  /* look integer variable in both directions */
2863  SCIP_CALL( SCIPaddVarLocks(scip, consdata->intvar, nlockspos + nlocksneg, nlockspos + nlocksneg) );
2864 
2865  /* look binary variables in both directions */
2866  for( b = 0; b < consdata->nbinvars; ++b )
2867  {
2868  SCIP_CALL( SCIPaddVarLocks(scip, consdata->binvars[b], nlockspos + nlocksneg, nlockspos + nlocksneg) );
2869  }
2870 
2871  return SCIP_OKAY;
2872 }
2873 
2874 /** constraint enabling notification method of constraint handler */
2875 static
2876 SCIP_DECL_CONSENABLE(consEnableLinking)
2877 { /*lint --e{715}*/
2878 #if 0
2879  SCIP_CONSHDLRDATA* conshdlrdata;
2880  SCIP_CONSDATA* consdata;
2881 
2882  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2883  assert(conshdlrdata != NULL);
2884 
2885  consdata = SCIPconsGetData(cons);
2886  assert(consdata != NULL);
2887 
2888  if( consdata->nbinvars <= 1 )
2889  {
2890  SCIP_CALL( SCIPdisableCons(scip, cons) );
2891  assert(consdata->nbinvars == 0 || SCIPvarGetLbGlobal(consdata->binvars[0]) > 0.5);
2892  }
2893  else if( conshdlrdata->linearize )
2894  {
2895  SCIP_CALL( consdataLinearize(scip, cons, consdata) );
2896  SCIP_CALL( SCIPdelCons(scip, cons) );
2897  }
2898 #endif
2899  return SCIP_OKAY;
2900 }
2901 
2902 /** constraint display method of constraint handler */
2903 static
2904 SCIP_DECL_CONSPRINT(consPrintLinking)
2905 { /*lint --e{715}*/
2906  assert(scip != NULL);
2907  assert(conshdlr != NULL);
2908  assert(cons != NULL);
2909 
2910  SCIP_CALL( consdataPrint(scip, SCIPconsGetData(cons), file) );
2911 
2912  return SCIP_OKAY;
2913 }
2914 
2915 
2916 /** constraint copying method of constraint handler */
2917 static
2918 SCIP_DECL_CONSCOPY(consCopyLinking)
2919 { /*lint --e{715}*/
2920  SCIP_CONSDATA* sourceconsdata;
2921  SCIP_VAR** binvars;
2922  SCIP_VAR* intvar;
2923  int* vals;
2924  const char* consname;
2925  int nbinvars;
2926  int v;
2927 
2928  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(sourcecons)), CONSHDLR_NAME) != 0 )
2929  {
2930  SCIPerrorMessage("constraint is not a linking constraint\n");
2931  SCIPABORT();
2932  return SCIP_INVALIDDATA; /*lint !e527*/
2933  }
2934 
2935  (*valid) = TRUE;
2936 
2937  sourceconsdata = SCIPconsGetData(sourcecons);
2938  assert(sourceconsdata != NULL);
2939 
2940  /* get number of binary variables, integer variables */
2941  nbinvars = sourceconsdata->nbinvars;
2942  intvar = sourceconsdata->intvar;
2943 
2944  /* duplicate variable array */
2945  if( nbinvars > 0 )
2946  {
2947  SCIP_CALL( SCIPduplicateBufferArray(scip, &binvars, sourceconsdata->binvars, nbinvars) );
2948  SCIP_CALL( SCIPduplicateBufferArray(scip, &vals, sourceconsdata->vals, nbinvars) );
2949  }
2950  else
2951  {
2952  binvars = NULL;
2953  vals = NULL;
2954  }
2955 
2956  /* get copy for the binary variables */
2957  for( v = 0; v < nbinvars && *valid; ++v )
2958  {
2959  assert(binvars != NULL); /* for flexelint */
2960  SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, binvars[v], &binvars[v], varmap, consmap, global, valid) );
2961  assert(!(*valid) || binvars[v] != NULL);
2962  }
2963 
2964  /* copy the integer variable */
2965  if( *valid )
2966  {
2967  SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, intvar, &intvar, varmap, consmap, global, valid) );
2968  assert(!(*valid) || intvar != NULL);
2969  }
2970 
2971  /* only create the target constraint, if all variables could be copied */
2972  if( *valid )
2973  {
2974  if( name != NULL )
2975  consname = name;
2976  else
2977  consname = SCIPconsGetName(sourcecons);
2978 
2979  SCIP_CALL( SCIPcreateConsLinking(scip, cons, consname, intvar, binvars, vals, nbinvars,
2980  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
2981  }
2982 
2983  /* free buffer array */
2984  if( nbinvars > 0 )
2985  {
2986  SCIPfreeBufferArrayNull(scip, &vals);
2987  SCIPfreeBufferArrayNull(scip, &binvars);
2988  }
2989 
2990  return SCIP_OKAY;
2991 }
2992 
2993 /** constraint parsing method of constraint handler */
2994 static
2995 SCIP_DECL_CONSPARSE(consParseLinking)
2996 { /*lint --e{715}*/
2997  SCIP_VAR** binvars;
2998  SCIP_VAR* intvar;
2999  int* intvals;
3000  char* endptr;
3001  int varssize;
3002  int nbinvars;
3003 
3004  assert(scip != NULL);
3005  assert(success != NULL);
3006  assert(str != NULL);
3007  assert(name != NULL);
3008  assert(cons != NULL);
3009 
3010  *success = TRUE;
3011 
3012  /* parse integer variables */
3013  SCIP_CALL( SCIPparseVarName(scip, str, &intvar, &endptr) );
3014 
3015  if( intvar == NULL )
3016  {
3017  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "unknown variable name at '%s'\n", str);
3018  *success = FALSE;
3019  return SCIP_OKAY;
3020  }
3021  str = endptr;
3022 
3023  nbinvars = 0;
3024  varssize = 16;
3025 
3026  SCIP_CALL( SCIPallocBufferArray(scip, &binvars, varssize) );
3027  SCIP_CALL( SCIPallocBufferArray(scip, &intvals, varssize) );
3028 
3029  while( *str != '=' )
3030  ++str;
3031 
3032  /* skip '=' */
3033  ++str;
3034 
3035  /* skip whitespace */
3036  while( isspace((int)*str) )
3037  ++str;
3038 
3039  /* check for the string "no binary variables yet" */
3040  if( strncmp(str, "no binary variables yet", 24) != 0 )
3041  {
3042  SCIP_Real* vals;
3043  int requsize;
3044  int v;
3045 
3046  SCIP_CALL( SCIPallocBufferArray(scip, &vals, varssize) );
3047 
3048  /* parse linear sum to get variables and coefficients */
3049  SCIP_CALL( SCIPparseVarsLinearsum(scip, str, binvars, vals, &nbinvars, varssize, &requsize, &endptr, success) );
3050 
3051  if( *success && requsize > varssize )
3052  {
3053  /* realloc buffers and try again */
3054  varssize = requsize;
3055  SCIP_CALL( SCIPreallocBufferArray(scip, &binvars, varssize) );
3056  SCIP_CALL( SCIPreallocBufferArray(scip, &intvals, varssize) );
3057  SCIP_CALL( SCIPreallocBufferArray(scip, &vals, varssize) );
3058 
3059  SCIP_CALL( SCIPparseVarsLinearsum(scip, str, binvars, vals, &nbinvars, varssize, &requsize, &endptr, success) );
3060  assert(!*success || requsize <= varssize); /* if successful, then should have had enough space now */
3061  }
3062 
3063  /* check coefficients */
3064  if( *success )
3065  {
3066  /* convert SCIP_Real to integer */
3067  for( v = 0; v < nbinvars; ++v )
3068  {
3069  assert(SCIPisIntegral(scip, vals[v]));
3070 
3071  /* check that the coefficients is integral */
3072  *success = *success && SCIPisIntegral(scip, vals[v]);
3073 
3074  intvals[v] = SCIPconvertRealToInt(scip, vals[v]);
3075  }
3076  }
3077 
3078  SCIPfreeBufferArray(scip, &vals);
3079  }
3080 
3081  if( *success )
3082  {
3083  SCIP_CALL( SCIPcreateConsLinking(scip, cons, name, intvar, binvars, intvals, nbinvars,
3084  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3085  }
3086 
3087  SCIPfreeBufferArray(scip, &intvals);
3088  SCIPfreeBufferArray(scip, &binvars);
3089 
3090  return SCIP_OKAY;
3091 }
3092 
3093 /** constraint method of constraint handler which returns the variables (if possible) */
3094 static
3095 SCIP_DECL_CONSGETVARS(consGetVarsLinking)
3096 { /*lint --e{715}*/
3097  SCIP_CONSDATA* consdata;
3098 
3099  consdata = SCIPconsGetData(cons);
3100  assert(consdata != NULL);
3101 
3102  if( varssize < consdata->nbinvars + 1)
3103  (*success) = FALSE;
3104  else
3105  {
3106  assert(vars != NULL);
3107 
3108  BMScopyMemoryArray(vars, consdata->binvars, consdata->nbinvars);
3109  vars[consdata->nbinvars] = consdata->intvar;
3110  (*success) = TRUE;
3111  }
3112 
3113  return SCIP_OKAY;
3114 }
3115 
3116 /** constraint method of constraint handler which returns the number of variables (if possible) */
3117 static
3118 SCIP_DECL_CONSGETNVARS(consGetNVarsLinking)
3119 { /*lint --e{715}*/
3120  SCIP_CONSDATA* consdata;
3121 
3122  consdata = SCIPconsGetData(cons);
3123  assert(consdata != NULL);
3124 
3125  (*nvars) = consdata->nbinvars + 1;
3126  (*success) = TRUE;
3127 
3128  return SCIP_OKAY;
3129 }
3130 
3131 /*
3132  * Callback methods of event handler
3133  */
3134 
3135 /** execution method of event handler */
3136 static
3137 SCIP_DECL_EVENTEXEC(eventExecBinvar)
3138 { /*lint --e{715}*/
3139  SCIP_CONSDATA* consdata;
3140  SCIP_EVENTTYPE eventtype;
3141 
3142  assert(eventhdlr != NULL);
3143  assert(eventdata != NULL);
3144  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
3145  assert(event != NULL);
3146 
3147  consdata = (SCIP_CONSDATA*)eventdata;
3148  assert(consdata != NULL);
3149 
3150  eventtype = SCIPeventGetType(event);
3151  switch( eventtype )
3152  {
3154  consdata->nfixedones++;
3155  break;
3157  consdata->nfixedones--;
3158  consdata->firstnonfixed = 0;
3159  consdata->lastnonfixed = consdata->nbinvars - 1;
3160  break;
3162  consdata->nfixedzeros++;
3163  break;
3165  consdata->firstnonfixed = 0;
3166  consdata->lastnonfixed = consdata->nbinvars - 1;
3167  consdata->nfixedzeros--;
3168  break;
3169  default:
3170  SCIPerrorMessage("invalid event type\n");
3171  return SCIP_INVALIDDATA;
3172  }
3173  assert(0 <= consdata->nfixedzeros && consdata->nfixedzeros <= consdata->nbinvars);
3174  assert(0 <= consdata->nfixedones && consdata->nfixedones <= consdata->nbinvars);
3175 
3176  /*debugMsg(scip, " -> constraint has %d zero-fixed and %d one-fixed of %d variables\n",
3177  consdata->nfixedzeros, consdata->nfixedones, consdata->nvars);*/
3178 
3179  return SCIP_OKAY;
3180 }
3181 
3182 /*
3183  * constraint specific interface methods
3184  */
3185 
3186 /** creates the handler for linking constraints and includes it in SCIP */
3188  SCIP* scip /**< SCIP data structure */
3189  )
3190 {
3191  SCIP_CONSHDLRDATA* conshdlrdata;
3192  SCIP_CONSHDLR* conshdlr;
3193  SCIP_EVENTHDLR* eventhdlr;
3194 
3195  /* create event handler for bound change events */
3197  eventExecBinvar, NULL) );
3198 
3199  /* create linking constraint handler data */
3200  SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
3201 
3202  /* include constraint handler */
3205  consEnfolpLinking, consEnfopsLinking, consCheckLinking, consLockLinking,
3206  conshdlrdata) );
3207 
3208  assert(conshdlr != NULL);
3209 
3210  /* set non-fundamental callbacks via specific setter functions */
3211  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyLinking, consCopyLinking) );
3212  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteLinking) );
3213  SCIP_CALL( SCIPsetConshdlrEnable(scip, conshdlr, consEnableLinking) );
3214  SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolLinking) );
3215  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeLinking) );
3216  SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsLinking) );
3217  SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsLinking) );
3218  SCIP_CALL( SCIPsetConshdlrInitpre(scip, conshdlr, consInitpreLinking) );
3219  SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpLinking) );
3220  SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseLinking) );
3221  SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolLinking, CONSHDLR_MAXPREROUNDS, CONSHDLR_PRESOLTIMING) );
3222  SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintLinking) );
3223  SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropLinking, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
3225  SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropLinking) );
3226  SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpLinking, consSepasolLinking, CONSHDLR_SEPAFREQ,
3228  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransLinking) );
3229  SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxLinking) );
3230 
3231  /* include the linear constraint to linking constraint upgrade in the linear constraint handler */
3232  /* SCIP_CALL( SCIPincludeLinconsUpgrade(scip, linconsUpgdLinking, LINCONSUPGD_PRIORITY, CONSHDLR_NAME) ); */
3233 
3234  /* add linking constraint handler parameters */
3236  "constraints/" CONSHDLR_NAME "/linearize", "this constraint will not propagate or separate, linear and setppc are used?",
3237  &conshdlrdata->linearize, FALSE, DEFAULT_LINEARIZE, NULL, NULL) );
3238 
3239  return SCIP_OKAY;
3240 }
3241 
3242 /** creates and captures a linking constraint
3243  *
3244  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
3245  */
3247  SCIP* scip, /**< SCIP data structure */
3248  SCIP_CONS** cons, /**< pointer to hold the created constraint */
3249  const char* name, /**< name of constraint */
3250  SCIP_VAR* intvar, /**< integer variable which should be linked */
3251  SCIP_VAR** binvars, /**< binary variables, or NULL */
3252  int* vals, /**< coefficients of the binary variables */
3253  int nbinvars, /**< number of binary variables */
3254  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
3255  * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
3256  SCIP_Bool separate, /**< should the constraint be separated during LP processing?
3257  * Usually set to TRUE. */
3258  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
3259  * TRUE for model constraints, FALSE for additional, redundant constraints. */
3260  SCIP_Bool check, /**< should the constraint be checked for feasibility?
3261  * TRUE for model constraints, FALSE for additional, redundant constraints. */
3262  SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
3263  * Usually set to TRUE. */
3264  SCIP_Bool local, /**< is constraint only valid locally?
3265  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
3266  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
3267  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
3268  * adds coefficients to this constraint. */
3269  SCIP_Bool dynamic, /**< is constraint subject to aging?
3270  * Usually set to FALSE. Set to TRUE for own cuts which
3271  * are separated as constraints. */
3272  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
3273  * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
3274  SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
3275  * if it may be moved to a more global node?
3276  * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
3277  )
3278 {
3279  SCIP_CONSHDLR* conshdlr;
3280  SCIP_CONSDATA* consdata;
3281  SCIP_CONSHDLRDATA* conshdlrdata;
3282 
3283  assert(scip != NULL);
3284  assert(!SCIPisInfinity(scip, -SCIPvarGetLbGlobal(intvar)));
3285  assert(!SCIPisInfinity(scip, SCIPvarGetUbGlobal(intvar)));
3286 
3287  /* find the linking constraint handler */
3288  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
3289  if( conshdlr == NULL )
3290  {
3291  SCIPerrorMessage("linking constraint handler not found\n");
3292  return SCIP_PLUGINNOTFOUND;
3293  }
3294 
3295  SCIPdebugMsg(scip, "create linking constraint for variable <%s> with %d binary variable (SCIP stage %d)\n",
3296  SCIPvarGetName(intvar), nbinvars, SCIPgetStage(scip));
3297 
3298  /* get constraint handler data */
3299  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3300  assert(conshdlrdata != NULL);
3301 
3302  if( conshdlrdata->varmap == NULL )
3303  {
3304  SCIP_CALL( SCIPhashmapCreate(&conshdlrdata->varmap, SCIPblkmem(scip), HASHSIZE_BINVARSCONS) );
3305  }
3306  assert(conshdlrdata->varmap != NULL);
3307 
3308  /* check if the linking for the requests integer variable already exists */
3309  assert(!SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey(intvar)));
3310 
3311  /* create the constraint specific data */
3312  SCIP_CALL( consdataCreate(scip, conshdlrdata->eventhdlr, &consdata, intvar, binvars, vals, nbinvars) );
3313 
3314  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata,
3315  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3316 
3317  /* insert linking constraint into the hash map */
3318  SCIP_CALL( SCIPhashmapInsert(conshdlrdata->varmap, getHashmapKey(intvar), *cons) );
3319  assert(SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey(intvar)));
3320 
3321  return SCIP_OKAY;
3322 }
3323 
3324 /** creates and captures a linking constraint
3325  * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
3326  * method SCIPcreateConsLinking(); all flags can be set via SCIPsetCons<Flagname>-methods in scip.h
3327  *
3328  * @see SCIPcreateConsLinking() for information about the basic constraint flag configuration
3329  *
3330  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
3331  */
3333  SCIP* scip, /**< SCIP data structure */
3334  SCIP_CONS** cons, /**< pointer to hold the created constraint */
3335  const char* name, /**< name of constraint */
3336  SCIP_VAR* intvar, /**< integer variable which should be linked */
3337  SCIP_VAR** binvars, /**< binary variables, or NULL */
3338  int* vals, /**< coefficients of the binary variables */
3339  int nbinvars /**< number of binary variables */
3340  )
3341 {
3342  assert(scip != NULL);
3343 
3344  SCIP_CALL( SCIPcreateConsLinking(scip, cons, name, intvar, binvars, vals, nbinvars,
3345  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
3346 
3347  return SCIP_OKAY;
3348 }
3349 
3350 /** checks if for the given integer variable a linking constraint exists */
3352  SCIP* scip, /**< SCIP data structure */
3353  SCIP_VAR* intvar /**< integer variable which should be linked */
3354  )
3355 {
3356  SCIP_CONSHDLR* conshdlr;
3357  SCIP_CONSHDLRDATA* conshdlrdata;
3358 
3359  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
3360  assert(conshdlr != NULL);
3361 
3362  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3363  assert(conshdlrdata != NULL);
3364 
3365  return (conshdlrdata->varmap != NULL) && SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey(intvar));
3366 }
3367 
3368 /** returns the linking constraint belonging to the given integer variable or NULL if it does not exist yet */
3370  SCIP* scip, /**< SCIP data structure */
3371  SCIP_VAR* intvar /**< integer variable which should be linked */
3372  )
3373 {
3374  SCIP_CONSHDLR* conshdlr;
3375  SCIP_CONSHDLRDATA* conshdlrdata;
3376 
3377  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
3378  assert(conshdlr != NULL);
3379 
3380  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3381  assert(conshdlrdata != NULL);
3382 
3383  if( conshdlrdata->varmap != NULL )
3384  return (SCIP_CONS*) SCIPhashmapGetImage(conshdlrdata->varmap, getHashmapKey(intvar));
3385  else
3386  return NULL;
3387 }
3388 
3389 /** returns the integer variable of the linking constraint */
3391  SCIP* scip, /**< SCIP data structure */
3392  SCIP_CONS* cons /**< linking constraint */
3393  )
3394 {
3395  SCIP_CONSDATA* consdata;
3396 
3397  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
3398  {
3399  SCIPerrorMessage("constraint is not a " CONSHDLR_NAME " constraint\n");
3400  SCIPABORT();
3401  return NULL; /*lint !e527*/
3402  }
3403 
3404  consdata = SCIPconsGetData(cons);
3405  assert(consdata != NULL);
3406 
3407  return consdata->intvar;
3408 
3409 }
3410 
3411 /** returns the binary variables of the linking constraint */
3413  SCIP* scip, /**< SCIP data structure */
3414  SCIP_CONS* cons, /**< linking constraint */
3415  SCIP_VAR*** binvars, /**< pointer to store the binary variables array pointer */
3416  int* nbinvars /**< pointer to store the number of returned binary variables */
3417  )
3418 {
3419  SCIP_CONSDATA* consdata;
3420 
3421  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
3422  {
3423  SCIPerrorMessage("constraint is not a " CONSHDLR_NAME " constraint\n");
3424  SCIPABORT();
3425  return SCIP_INVALIDDATA; /*lint !e527*/
3426  }
3427 
3428  consdata = SCIPconsGetData(cons);
3429  assert(consdata != NULL);
3430 
3431  if( consdata->binvars == NULL )
3432  {
3433  SCIP_CONSHDLR* conshdlr;
3434  SCIP_CONSHDLRDATA* conshdlrdata;
3435 
3436  conshdlr = SCIPconsGetHdlr(cons);
3437  assert(conshdlr != NULL);
3438 
3439  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3440  assert(conshdlrdata != NULL);
3441 
3442  SCIP_CALL( consdataCreateBinvars(scip, cons, consdata, conshdlrdata->eventhdlr, conshdlrdata->linearize) );
3443  }
3444 
3445  assert(consdata->binvars != NULL);
3446 
3447  if( binvars != NULL )
3448  (*binvars) = consdata->binvars;
3449  if( nbinvars != NULL )
3450  (*nbinvars) = consdata->nbinvars;
3451 
3452  return SCIP_OKAY;
3453 }
3454 
3455 /** returns the number of binary variables of the linking constraint */
3457  SCIP* scip, /**< SCIP data structure */
3458  SCIP_CONS* cons /**< linking constraint */
3459  )
3460 {
3461  SCIP_CONSDATA* consdata;
3462 
3463  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
3464  {
3465  SCIPerrorMessage("constraint is not a " CONSHDLR_NAME " constraint\n");
3466  SCIPABORT();
3467  return -1; /*lint !e527*/
3468  }
3469 
3470  consdata = SCIPconsGetData(cons);
3471  assert(consdata != NULL);
3472 
3473  return consdata->nbinvars;
3474 }
3475 
3476 /** returns the coefficients of the binary variables */
3478  SCIP* scip, /**< SCIP data structure */
3479  SCIP_CONS* cons /**< linking constraint */
3480  )
3481 {
3482  SCIP_CONSDATA* consdata;
3483 
3484  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
3485  {
3486  SCIPerrorMessage("constraint is not a " CONSHDLR_NAME " constraint\n");
3487  SCIPABORT();
3488  return NULL; /*lint !e527*/
3489  }
3490 
3491  consdata = SCIPconsGetData(cons);
3492  assert(consdata != NULL);
3493  assert(consdata->sorted);
3494 
3495  return consdata->vals;
3496 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip.h:21909
SCIP_RETCODE SCIPaddVarsToRowSameCoef(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real val)
Definition: scip.c:30360
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:46151
SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:27934
SCIP_RETCODE SCIPincludeConshdlrLinking(SCIP *scip)
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip.c:6228
SCIP_Bool SCIPinRepropagation(SCIP *scip)
Definition: scip.c:40508
SCIP_Real SCIPfeastol(SCIP *scip)
Definition: scip.c:45274
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:7978
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip.h:21892
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip.c:19263
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46086
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip.c:814
#define CONSHDLR_DELAYPROP
Definition: cons_linking.c:63
static SCIP_DECL_EVENTEXEC(eventExecBinvar)
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8140
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip.c:6251
static SCIP_RETCODE consFixInteger(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff)
Definition: cons_linking.c:671
static SCIP_DECL_CONSTRANS(consTransLinking)
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip.c:19123
static SCIP_RETCODE consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file)
Definition: cons_linking.c:197
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip.c:40275
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:6541
#define CONSHDLR_ENFOPRIORITY
Definition: cons_linking.c:56
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17166
static SCIP_RETCODE removeFixedBinvars(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_CONS *cons)
Definition: cons_linking.c:977
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
Definition: scip.c:6481
#define SCIP_MAXSTRLEN
Definition: def.h:215
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
Definition: scip.c:5973
SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:27962
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:12481
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition: scip.c:30288
#define DEFAULT_LINEARIZE
Definition: cons_linking.c:71
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17222
static SCIP_DECL_CONSENFORELAX(consEnforelaxLinking)
SCIP_RETCODE SCIPaddConflictBinvar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:26950
static SCIP_DECL_CONSPRINT(consPrintLinking)
int * SCIPgetValsLinking(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPconsIsAdded(SCIP_CONS *cons)
Definition: cons.c:8250
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: scip.c:8526
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip.c:18575
SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
Definition: scip.c:17656
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip.c:18384
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:16732
static SCIP_RETCODE analyzeConflict(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *intvar, SCIP_VAR *binvar, SCIP_Bool lbintvar, SCIP_Bool ubintvar)
Definition: cons_linking.c:628
SCIP_RETCODE SCIPsetConshdlrInitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITPRE((*consinitpre)))
Definition: scip.c:6142
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
Definition: scip.c:46175
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46138
#define CONSHDLR_EAGERFREQ
Definition: cons_linking.c:60
#define CONSHDLR_NEEDSCONS
Definition: cons_linking.c:64
static SCIP_RETCODE createRows(SCIP *scip, SCIP_CONS *cons)
#define FALSE
Definition: def.h:64
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:2765
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:278
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.c:5831
static SCIP_DECL_CONSSEPASOL(consSepasolLinking)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:9340
#define TRUE
Definition: def.h:63
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_RETCODE SCIPaddConflictUb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
Definition: scip.c:26813
SCIP_Bool SCIPexistsConsLinking(SCIP *scip, SCIP_VAR *intvar)
SCIP_RETCODE SCIPaddVarLocks(SCIP *scip, SCIP_VAR *var, int nlocksdown, int nlocksup)
Definition: scip.c:21255
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:8160
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
Definition: cons_linking.c:577
#define CONSHDLR_NAME
Definition: cons_linking.c:49
SCIP_Real SCIPvarGetAggrScalar(SCIP_VAR *var)
Definition: var.c:16912
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8190
static SCIP_Bool checkCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
Definition: scip.c:26717
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip.h:21907
#define CONSHDLR_PROP_TIMING
Definition: cons_linking.c:66
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.c:5885
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip.h:21933
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:2903
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45751
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:21937
static SCIP_RETCODE dropAllEvents(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linking.c:338
Constraint handler for the set partitioning / packing / covering constraints .
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip.h:21890
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip.c:1010
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8150
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition: type_event.h:108
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip.c:6274
int SCIPgetNBinvarsLinking(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_CONSDATA **consdata, SCIP_VAR *intvar, SCIP_VAR **binvars, int *vals, int nbinvars)
Definition: cons_linking.c:497
static SCIP_RETCODE separateCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool *cutoff, SCIP_Bool *separated, int *nchgbds)
#define SCIPdebugMsg
Definition: scip.h:451
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip.c:18616
static SCIP_DECL_CONSINITLP(consInitlpLinking)
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip.c:6458
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:7942
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1336
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.c:27146
SCIP_RETCODE SCIPparseVarsLinearsum(SCIP *scip, const char *str, SCIP_VAR **vars, SCIP_Real *vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
Definition: scip.c:17832
SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
Definition: scip.c:26746
static void * getHashmapKey(SCIP_VAR *var)
Definition: cons_linking.c:109
static SCIP_RETCODE addCuts(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool *cutoff)
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:16522
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:2997
#define SCIP_EVENTTYPE_LBRELAXED
Definition: type_event.h:64
void SCIPsortIntPtr(int *intarray, void **ptrarray, int len)
SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
Definition: scip.c:26695
SCIP_RETCODE SCIPenableCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:27987
SCIP_RETCODE SCIPaddClique(SCIP *scip, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip.c:23815
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17176
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip.h:21904
static SCIP_DECL_CONSENFOLP(consEnfolpLinking)
static SCIP_DECL_CONSGETVARS(consGetVarsLinking)
static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **binvars, int nbinvars)
Definition: cons_linking.c:135
static SCIP_DECL_CONSLOCK(consLockLinking)
SCIP_VAR * SCIPgetIntvarLinking(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip.c:5997
#define CONSHDLR_DELAYSEPA
Definition: cons_linking.c:62
#define EVENTHDLR_DESC
Definition: cons_linking.c:53
#define SCIPerrorMessage
Definition: pub_message.h:45
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4113
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:12410
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45764
static SCIP_DECL_CONSPARSE(consParseLinking)
static SCIP_RETCODE tightenedIntvar(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, SCIP_Bool *cutoff, int *nchgbds)
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:13111
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinking)
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip.h:21938
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip.c:45519
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip.c:21383
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:7881
SCIP_RETCODE SCIPmarkDoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:25494
SCIP_Real SCIPvarGetAggrConstant(SCIP_VAR *var)
Definition: var.c:16923
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8100
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:155
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16552
SCIP_RETCODE SCIPcreateConsSetpart(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, 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_setppc.c:8976
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip.c:6022
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:2798
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4133
#define NULL
Definition: lpi_spx1.cpp:137
#define CONSHDLR_PROPFREQ
Definition: cons_linking.c:59
#define SCIP_EVENTTYPE_UBRELAXED
Definition: type_event.h:66
#define SCIP_CALL(x)
Definition: def.h:306
#define SCIP_EVENTTYPE_LBTIGHTENED
Definition: type_event.h:63
static SCIP_RETCODE consdataLinearize(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata)
Definition: cons_linking.c:363
static SCIP_RETCODE catchEvent(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_linking.c:251
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46112
SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
Definition: scip.c:27097
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip.c:1353
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8120
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
Definition: scip.c:6297
SCIP_RETCODE SCIPaddCut(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition: scip.c:33869
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:50
SCIP_RETCODE SCIPdisableCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:28021
static SCIP_RETCODE catchAllEvents(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linking.c:314
#define HASHSIZE_BINVARSCONS
Definition: cons_linking.c:70
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip.c:28769
static SCIP_DECL_CONSRESPROP(consRespropLinking)
static SCIP_DECL_CONSDELETE(consDeleteLinking)
static SCIP_DECL_CONSINITPRE(consInitpreLinking)
constraint handler for linking binary variables to an integer variable
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:21925
#define SCIP_Bool
Definition: def.h:61
static SCIP_DECL_CONSPRESOL(consPresolLinking)
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:959
static SCIP_DECL_CONSCHECK(consCheckLinking)
static SCIP_RETCODE processIntegerBoundChg(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool *mustcheck)
Definition: cons_linking.c:728
SCIP_RETCODE SCIPcreateEmptyRowCons(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.c:30022
int SCIPgetDepth(SCIP *scip)
Definition: scip.c:42094
#define EVENTHDLR_NAME
Definition: cons_linking.c:52
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip.c:28652
#define MAX(x, y)
Definition: tclique_def.h:75
static SCIP_DECL_CONSPROP(consPropLinking)
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:7901
#define CONSHDLR_DESC
Definition: cons_linking.c:50
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8080
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8050
static SCIP_DECL_CONSFREE(consFreeLinking)
SCIP_RETCODE SCIPdropVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip.c:40321
SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
Definition: var.c:16901
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip.c:17237
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip.c:25141
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:89
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip.c:21309
static SCIP_DECL_CONSENFOPS(consEnfopsLinking)
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip.c:6435
#define SCIP_EVENTTYPE_UBTIGHTENED
Definition: type_event.h:65
Constraint handler for linear constraints in their most general form, .
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
Definition: scip.c:45827
int SCIPconvertRealToInt(SCIP *scip, SCIP_Real real)
Definition: scip.c:46594
SCIP_RETCODE SCIPinferVarLbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:22414
SCIP_RETCODE SCIPsetConshdlrEnable(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENABLE((*consenable)))
Definition: scip.c:6366
static SCIP_RETCODE aggregateVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars, int *ndelconss)
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip.c:35033
#define CONSHDLR_CHECKPRIORITY
Definition: cons_linking.c:57
static void consdataSort(SCIP_CONSDATA *consdata)
Definition: cons_linking.c:119
SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
Definition: scip.c:17466
static SCIP_DECL_CONSGETNVARS(consGetNVarsLinking)
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip.c:30160
static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_CONS *cons, int pos)
Definition: cons_linking.c:919
SCIP_RETCODE SCIPhashmapRemove(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3013
SCIP_RETCODE SCIPcreateConsLinking(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *intvar, SCIP_VAR **binvars, int *vals, int nbinvars, 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_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:45900
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.c:1911
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:11311
static SCIP_DECL_CONSENABLE(consEnableLinking)
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:7911
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.c:22527
SCIP_RETCODE SCIPgetBinvarsLinking(SCIP *scip, SCIP_CONS *cons, SCIP_VAR ***binvars, int *nbinvars)
static SCIP_DECL_CONSEXITSOL(consExitsolLinking)
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip.c:27323
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip.c:6190
static SCIP_RETCODE processBinvarFixings(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool *addcut, SCIP_Bool *mustcheck)
SCIP_Real SCIPgetRowLPFeasibility(SCIP *scip, SCIP_ROW *row)
Definition: scip.c:30579
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16671
SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
Definition: scip.c:25250
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:18350
#define SCIP_Real
Definition: def.h:135
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8130
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1138
#define MIN(x, y)
Definition: memory.c:75
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
Definition: scip.c:6504
static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linking.c:154
#define CONSHDLR_PRESOLTIMING
Definition: cons_linking.c:67
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8070
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8060
static SCIP_DECL_CONSSEPALP(consSepalpLinking)
#define CONSHDLR_SEPAFREQ
Definition: cons_linking.c:58
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:16849
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:16717
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:49
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17232
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:46187
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:16694
static SCIP_DECL_CONSCOPY(consCopyLinking)
SCIP_CONS * SCIPgetConsLinking(SCIP *scip, SCIP_VAR *intvar)
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:2846
static SCIP_RETCODE enforcePseudo(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, SCIP_Bool *infeasible, int *nchgbds, SCIP_Bool *solvelp)
static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int nusefulconss, SCIP_SOL *sol, SCIP_RESULT *result)
SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITSOL((*consexitsol)))
Definition: scip.c:6118
#define SCIPABORT()
Definition: def.h:278
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition: scip.c:17353
#define CONSHDLR_SEPAPRIORITY
Definition: cons_linking.c:55
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip.c:38007
SCIP_RETCODE SCIPcreateConsBasicLinking(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *intvar, SCIP_VAR **binvars, int *vals, int nbinvars)
SCIP_RETCODE SCIPinferBinvarCons(SCIP *scip, SCIP_VAR *var, SCIP_Bool fixedval, SCIP_CONS *infercons, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:22634
#define CONSHDLR_MAXPREROUNDS
Definition: cons_linking.c:61
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.c:4176
static SCIP_RETCODE dropEvent(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_linking.c:283
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:134
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:21929
SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
Definition: scip.c:5931
static SCIP_RETCODE conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
Definition: cons_linking.c:177
static SCIP_RETCODE consdataCreateBinvars(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, SCIP_Bool linearize)
Definition: cons_linking.c:402