Scippy

SCIP

Solving Constraint Integer Programs

presol_gateextraction.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-2016 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 presol_gateextraction.c
17  * @brief gateextraction presolver
18  * @author Michael Winkler
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #include <assert.h>
24 #include <string.h>
25 
27 #include "scip/cons_setppc.h"
28 #include "scip/cons_logicor.h"
29 #include "scip/cons_and.h"
30 
31 
32 #define PRESOL_NAME "gateextraction"
33 #define PRESOL_DESC "presolver extracting gate(and)-constraints"
34 #define PRESOL_PRIORITY 1000000 /**< priority of the presolver (>= 0: before, < 0: after constraint handlers); combined with propagators */
35 #define PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
36 #define PRESOL_TIMING SCIP_PRESOLTIMING_EXHAUSTIVE /* timing of the presolver (fast, medium, or exhaustive) */
37 
38 #define HASHSIZE_LOGICORCONS 131101 /**< minimal size of hash table in logicor constraint tables */
39 #define HASHSIZE_SETPPCCONS 131101 /**< minimal size of hash table in setppc constraint tables */
40 
41 #define DEFAULT_ONLYSETPART FALSE /**< should only set-partitioning constraints be extracted and no and-constraints */
42 #define DEFAULT_SEARCHEQUATIONS TRUE /**< should we try to extract set-partitioning constraint out of one logicor
43  * and one corresponding set-packing constraint
44  */
45 #define DEFAULT_SORTING 1 /**< order logicor contraints to extract big-gates before smaller ones (-1), do
46  * not order them (0) or order them to extract smaller gates at first (1)
47  */
48 
49 
50 /* This presolver tries to extract gate-constraints meaning and-constraints and set-partitioning constraints (and could
51  * be expanded to find xor-constraints too). This is done by detecting linearizations or systems of inequalities which
52  * form an and-constraint or a set-partitioning constraint. An example:
53  *
54  * we have a logicor constraint of the form: x + y + z >= 1
55  *
56  * and we also have the following set-packing constraints: (x + y <= 1 and x + z <= 1) <=> (~x + ~y >= 1 and ~x + ~z >= 1)
57  *
58  * - these three constraints form an and-constraint: x = ~y * ~z (x = AND(~y,~z))
59  *
60  * if an additional set-packing constraint exists: y + z <= 1
61  *
62  * - these four constraints form a set-partitioning cons.: x + y + z = 1
63  *
64  * some information can be found:
65  *
66  * http://www.cs.ubc.ca/~hutter/earg/papers07/cnf-structure.pdf
67  * http://www.cadence.com/cn/cadence/cadence_labs/Documents/niklas_SAT_2005_Effective.pdf
68  *
69  * We also do some check for logicor and set-packing/-partitioning constraint with the same variables to upgrade these
70  * both constraints into one. For example:
71  *
72  * x + y + z >= 1 and x + y + z <= 1 form x + y + z = 1
73  *
74  */
75 
76 
77 /*
78  * Data structures
79  */
80 
81 
82 /** data object to compare constraint easier */
83 struct HashData
84 {
85  SCIP_CONS* cons; /**< pointer the the corresponding constraint */
86  SCIP_VAR** vars; /**< constraint variables used for hash comparison */
87  int nvars; /**< number of variables */
88 };
89 typedef struct HashData HASHDATA;
90 
91 
92 /** presolver data */
93 struct SCIP_PresolData
94 {
95  HASHDATA** setppchashdatas; /**< setppc-hashdata array pointing to the storage */
96  HASHDATA* setppchashdatastore;/**< setppc-hashdata storage */
97  SCIP_HASHTABLE* hashdatatable; /**< setppc-hashdata hashtable for usable setppc constraints */
98  SCIP_HASHTABLE* setppchashtable; /**< setppc hashtable for usable setppc constraints */
99  SCIP_HASHTABLE* logicorhashtable; /**< logicor hashtable for usable logicor constraints */
100  SCIP_CONS** usefullogicor; /**< array for usable logicors */
101  int nusefullogicor; /**< number of usable logicors */
102  int susefullogicor; /**< size of array for usable logicor constraints */
103  int nsetppchashdatas; /**< number of setppchashdata elements added to the hashtable */
104  int ssetppchashdatas; /**< size of setppchashdata elements added to the hashtable */
105  int ngates; /**< number of found gates in presolving */
106  int firstchangedlogicor;/**< position of the first new/changed logicor constraint in the
107  * usefullogicor array
108  */
109  int maxnvarslogicor; /**< maximal number of variables a logicor constraint has */
110  int sorting; /**< integer parameter how to sort logicor constraints for extracting
111  * gates
112  */
113  SCIP_Bool usefulsetppcexist; /**< did we find usable set-packing constraints for gate extraction */
114  SCIP_Bool usefullogicorexist; /**< did we find usable logicor constraints for gate extraction */
115  SCIP_Bool newsetppchashdatas; /**< flag indicating whether we found new set-packing constraint with two
116  * variables since the last presolving round
117  */
118  SCIP_Bool initialized; /**< was data alredy be initialized */
119  SCIP_Bool onlysetpart; /**< boolean parameter whetehr we only want to extract linear gates */
120  SCIP_Bool searchequations; /**< boolean parameter whetehr we want to search for equations arising from
121  * logicor and setppc constraints
122  */
123 };
124 
125 
126 /*
127  * Local methods
128  */
129 
130 
131 /** returns TRUE iff both keys are equal; two constraints are equal if they have the same pointer */
132 static
133 SCIP_DECL_HASHKEYEQ(hashdataKeyEqCons)
134 {
135 #ifndef NDEBUG
136  SCIP* scip;
137 #endif
138  HASHDATA* hashdata1;
139  HASHDATA* hashdata2;
140  int v;
141 
142  hashdata1 = (HASHDATA*)key1;
143  hashdata2 = (HASHDATA*)key2;
144 #ifndef NDEBUG
145  scip = (SCIP*)userptr;
146  assert(scip != NULL);
147 #endif
148 
149  /* check data structure */
150  assert(hashdata1->nvars == 2);
151  assert(hashdata2->nvars == 2);
152  /* at least one data object needs to be have a real set packing constraint */
153  assert(hashdata1->cons != NULL || hashdata2->cons != NULL);
154 
155  for( v = 1; v >= 0; --v )
156  {
157  /* tests if variables are equal */
158  if( hashdata1->vars[v] != hashdata2->vars[v] )
159  return FALSE;
160 
161  assert(SCIPvarCompare(hashdata1->vars[v], hashdata2->vars[v]) == 0);
162  }
163 
164  /* a hashdata object is only equal if it has the same constraint pointer, or one has no constraint pointer, latter
165  * means that this hashdata object is derived from a logicor constraint
166  */
167  if( hashdata1->cons == NULL || hashdata2->cons == NULL || hashdata1->cons == hashdata2->cons )
168  return TRUE;
169  else
170  return FALSE;
171 }
172 
173 /** returns the hash value of the key */
174 static
175 SCIP_DECL_HASHKEYVAL(hashdataKeyValCons)
176 { /*lint --e{715}*/
177  HASHDATA* hashdata;
178  unsigned int hashval;
180  hashdata = (HASHDATA*)key;
181  assert(hashdata != NULL);
182  assert(hashdata->vars != NULL);
183  assert(hashdata->nvars == 2);
184 
185  /* if we have only two variables we store at each 16 bits of the hash value the index of a variable */
186  hashval = (SCIPvarGetIndex(hashdata->vars[1]) << 16) + SCIPvarGetIndex(hashdata->vars[0]); /*lint !e701*/
187 
188  return hashval;
189 }
190 
191 
192 /** returns TRUE iff both keys are equal; two constraints are equal if they have the same pointer */
193 static
194 SCIP_DECL_HASHKEYEQ(setppcHashdataKeyEqCons)
195 {
196 #ifndef NDEBUG
197  SCIP* scip;
198 #endif
199  HASHDATA* hashdata1;
200  HASHDATA* hashdata2;
201  int v;
202 
203  hashdata1 = (HASHDATA*)key1;
204  hashdata2 = (HASHDATA*)key2;
205 #ifndef NDEBUG
206  scip = (SCIP*)userptr;
207  assert(scip != NULL);
208 #endif
209 
210  /* check data structure */
211  assert(hashdata1->nvars >= 2);
212  assert(hashdata2->nvars >= 2);
213  /* at least one data object needs to be have a real set-packing/partitioning constraint */
214  assert(hashdata1->cons != NULL || hashdata2->cons != NULL);
215 
216  if( hashdata1->nvars != hashdata2->nvars )
217  return FALSE;
218 
219  for( v = hashdata1->nvars - 1; v >= 0; --v )
220  {
221  /* tests if variables are equal */
222  if( hashdata1->vars[v] != hashdata2->vars[v] )
223  return FALSE;
224 
225  assert(SCIPvarCompare(hashdata1->vars[v], hashdata2->vars[v]) == 0);
226  }
227 
228  /* a hashdata object is only equal if it has the same constraint pointer, or one has no constraint pointer, latter
229  * means that this hashdata object is derived from a logicor constraint
230  */
231  if( hashdata1->cons == NULL || hashdata2->cons == NULL || hashdata1->cons == hashdata2->cons )
232  return TRUE;
233  else
234  return FALSE;
235 }
236 
237 /** returns the hash value of the key */
238 static
239 SCIP_DECL_HASHKEYVAL(setppcHashdataKeyValCons)
240 { /*lint --e{715}*/
241  HASHDATA* hashdata;
242  unsigned int hashval;
243  int v;
244 
245  hashdata = (HASHDATA*)key;
246  assert(hashdata != NULL);
247  assert(hashdata->vars != NULL);
248  assert(hashdata->nvars >= 2);
249 
250  hashval = 0;
251 
252  /* if we have more then one variables the index of each variable is imaged to a bit positioned from 0 to 31, and over
253  * all variables these bitfields are combined by an or operation to get a good hashvalue for distinguishing the data
254  */
255  for( v = 1; v >= 0; --v )
256  hashval |= (1 << (SCIPvarGetIndex(hashdata->vars[v]) % 32)); /*lint !e701*/
257 
258  return hashval;
259 }
260 
261 /** initialize gateextraction presolver data */
262 static
263 void presoldataInit(
264  SCIP_PRESOLDATA* presoldata /**< data object of presolver */
265  )
266 {
267  assert(presoldata != NULL);
268 
269  presoldata->usefullogicor = NULL;
270  presoldata->nusefullogicor = 0;
271  presoldata->susefullogicor = 0;
272  presoldata->firstchangedlogicor = -1;
273  presoldata->maxnvarslogicor = 0;;
274  presoldata->nsetppchashdatas = 0;
275  presoldata->ssetppchashdatas = 0;
276  presoldata->ngates = 0;
277  presoldata->usefulsetppcexist = FALSE;
278  presoldata->usefullogicorexist = FALSE;
279  presoldata->newsetppchashdatas = FALSE;
280  presoldata->initialized = FALSE;
281 
282  presoldata->hashdatatable = NULL;
283  presoldata->setppchashtable = NULL;
284  presoldata->logicorhashtable = NULL;
285 }
286 
287 /** initialize gateextraction hashtables */
288 static
290  SCIP* scip, /**< SCIP data structure */
291  SCIP_PRESOLDATA* presoldata /**< data object of presolver */
292  )
293 {
294  assert(scip != NULL);
295  assert(presoldata != NULL);
296 
297  assert(presoldata->nusefullogicor == 0);
298  assert(presoldata->susefullogicor == 0);
299  assert(presoldata->nsetppchashdatas == 0);
300  assert(presoldata->ssetppchashdatas == 0);
301  assert(presoldata->firstchangedlogicor == -1);
302  assert(presoldata->ngates == 0);
303  assert(presoldata->usefullogicorexist == FALSE);
304  assert(presoldata->usefulsetppcexist == FALSE);
305  assert(presoldata->newsetppchashdatas == FALSE);
306  assert(presoldata->initialized == FALSE);
307 
308  assert(presoldata->hashdatatable == NULL);
309  assert(presoldata->setppchashtable == NULL);
310  assert(presoldata->logicorhashtable == NULL);
311 
312  /* create hashtables */
313  SCIP_CALL( SCIPhashtableCreate(&(presoldata->hashdatatable), SCIPblkmem(scip), HASHSIZE_SETPPCCONS, SCIPhashGetKeyStandard, hashdataKeyEqCons, hashdataKeyValCons, (void*) scip) );
314  SCIP_CALL( SCIPhashtableCreate(&(presoldata->setppchashtable), SCIPblkmem(scip), HASHSIZE_SETPPCCONS, SCIPhashGetKeyStandard, SCIPhashKeyEqPtr, SCIPhashKeyValPtr, (void*) scip) );
315  SCIP_CALL( SCIPhashtableCreate(&(presoldata->logicorhashtable), SCIPblkmem(scip), HASHSIZE_LOGICORCONS, SCIPhashGetKeyStandard, SCIPhashKeyEqPtr, SCIPhashKeyValPtr, (void*) scip) );
316 
317  return SCIP_OKAY;
318 }
319 
320 
321 /** create useful set-packing information by adding new set-packing constraints with two variables */
322 static
324  SCIP* scip, /**< SCIP data structure */
325  SCIP_PRESOLDATA* presoldata, /**< data object of presolver */
326  SCIP_CONS** setppcs, /**< active setppc constraints */
327  int nsetppcs, /**< number of active setppc constraints */
328  SCIP_CONS** logicors, /**< active logicor constraints */
329  int nlogicors /**< number of active logicor constraints */
330  )
331 {
332  SCIP_CONS** usefulconss;
333  int nusefulconss = 0;
334  int size;
335  int c;
336 
337  assert(scip != NULL);
338  assert(presoldata != NULL);
339  assert(setppcs != NULL);
340  assert(nsetppcs > 0);
341  assert(logicors != NULL);
342  assert(nlogicors > 0);
343  assert(presoldata->setppchashtable != NULL);
344  assert(presoldata->logicorhashtable != NULL);
345 
346  presoldata->initialized = TRUE;
347 
348  size = MAX(nsetppcs, nlogicors);
349 
350  /* temporary memory for collecting set-packing constraints */
351  SCIP_CALL( SCIPallocBufferArray(scip, &usefulconss, size) );
352 
353  if( !presoldata->usefulsetppcexist )
354  {
355  /* find set-packing constraints with exactly two varibales */
356  for( c = 0; c < nsetppcs; ++c )
357  {
358  assert(SCIPconsIsActive(setppcs[c]));
359 
360  if( SCIPgetTypeSetppc(scip, setppcs[c]) == SCIP_SETPPCTYPE_PACKING && SCIPgetNVarsSetppc(scip, setppcs[c]) == 2 && !SCIPconsIsModifiable(setppcs[c]) )
361  {
362  /* insert new element in hashtable */
363  SCIP_CALL( SCIPhashtableInsert(presoldata->setppchashtable, (void*) setppcs[c]) );
364 
365  usefulconss[nusefulconss] = setppcs[c];
366  ++nusefulconss;
367  }
368  }
369 
370  /* add usefulconss constraints to hashdata elements */
371  if( nusefulconss > 0 )
372  {
373  SCIP_Bool negated[2];
374  int h;
375 
376  presoldata->usefulsetppcexist = TRUE;
377  presoldata->ssetppchashdatas = nusefulconss;
378 
379  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(presoldata->setppchashdatas), nusefulconss) );
380  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(presoldata->setppchashdatastore), nusefulconss) );
381 
382  h = 0;
383  for( c = 0; c < nusefulconss; ++c )
384  {
385  assert(SCIPconsIsActive(usefulconss[c]));
386  assert(SCIPgetNVarsSetppc(scip, usefulconss[c]) == 2);
387  presoldata->setppchashdatas[h] = &(presoldata->setppchashdatastore[h]);
388 
389  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(presoldata->setppchashdatas[h]->vars), SCIPgetVarsSetppc(scip, usefulconss[c]), 2) );
390 
391  SCIP_CALL( SCIPgetBinvarRepresentative(scip, presoldata->setppchashdatas[h]->vars[0], &(presoldata->setppchashdatas[h]->vars[0]), &(negated[0])) );
392  SCIP_CALL( SCIPgetBinvarRepresentative(scip, presoldata->setppchashdatas[h]->vars[1], &(presoldata->setppchashdatas[h]->vars[1]), &(negated[1])) );
393 
394  if( SCIPvarGetStatus(presoldata->setppchashdatas[h]->vars[0]) == SCIP_VARSTATUS_FIXED || SCIPvarGetStatus(presoldata->setppchashdatas[h]->vars[0]) == SCIP_VARSTATUS_MULTAGGR
395  || SCIPvarGetStatus(presoldata->setppchashdatas[h]->vars[1]) == SCIP_VARSTATUS_FIXED || SCIPvarGetStatus(presoldata->setppchashdatas[h]->vars[1]) == SCIP_VARSTATUS_MULTAGGR )
396  {
397  SCIPfreeBlockMemoryArray(scip, &(presoldata->setppchashdatas[h]->vars), 2);
398  continue;
399  }
400 
401  presoldata->setppchashdatas[h]->nvars = 2;
402 
403  /* capture variables */
404  SCIP_CALL( SCIPcaptureVar(scip, presoldata->setppchashdatas[h]->vars[0]) );
405  SCIP_CALL( SCIPcaptureVar(scip, presoldata->setppchashdatas[h]->vars[1]) );
406 
407  /* order the variables after their index */
408  if( SCIPvarGetIndex(presoldata->setppchashdatas[h]->vars[0]) > SCIPvarGetIndex(presoldata->setppchashdatas[h]->vars[1]) )
409  {
410  SCIP_VAR* tmp = presoldata->setppchashdatas[h]->vars[0];
411  presoldata->setppchashdatas[h]->vars[0] = presoldata->setppchashdatas[h]->vars[1];
412  presoldata->setppchashdatas[h]->vars[1] = tmp;
413  }
414 
415  presoldata->setppchashdatas[h]->cons = usefulconss[c];
416 
417  SCIP_CALL( SCIPhashtableInsert(presoldata->hashdatatable, (void*) presoldata->setppchashdatas[h]) );
418  SCIP_CALL( SCIPcaptureCons(scip, usefulconss[c]) );
419 
420  ++h;
421  }
422  presoldata->nsetppchashdatas = h;
423 
424  if( presoldata->nsetppchashdatas > 0 )
425  presoldata->newsetppchashdatas = TRUE;
426  }
427  }
428 
429  nusefulconss = 0;
430 
431  if( !presoldata->usefullogicorexist )
432  {
433  /* capture all logicor constraints */
434  for( c = 0; c < nlogicors; ++c )
435  {
436  assert(SCIPconsIsActive(logicors[c]));
437 
438  if( !SCIPconsIsModifiable(logicors[c]) && SCIPgetNVarsLogicor(scip, logicors[c]) >= 3 )
439  {
440  /* insert new element in hashtable */
441  SCIP_CALL( SCIPhashtableInsert(presoldata->logicorhashtable, (void*) logicors[c]) );
442  SCIP_CALL( SCIPcaptureCons(scip, logicors[c]) );
443 
444  usefulconss[nusefulconss] = logicors[c];
445  ++nusefulconss;
446 
447  /* update maximal entries in a logicor constraint */
448  if( presoldata->maxnvarslogicor < SCIPgetNVarsLogicor(scip, logicors[c]) )
449  presoldata->maxnvarslogicor = SCIPgetNVarsLogicor(scip, logicors[c]);
450  }
451  }
452 
453  /* no usefulconss constraints */
454  if( nusefulconss > 0 )
455  {
456  presoldata->firstchangedlogicor = 0;
457  presoldata->usefullogicorexist = TRUE;
458  presoldata->susefullogicor = nusefulconss;
459  presoldata->nusefullogicor = nusefulconss;
460  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &presoldata->usefullogicor, usefulconss, presoldata->susefullogicor) );
461  }
462  }
463 
464  /* free temporary memory */
465  SCIPfreeBufferArray(scip, &usefulconss);
466 
467  return SCIP_OKAY;
468 }
469 
470 
471 /** remove old setppchashdatas objects, so that the allocated memory will stay low */
472 static
474  SCIP* scip, /**< SCIP data structure */
475  SCIP_PRESOLDATA* presoldata /**< data object of presolver */
476  )
477 {
478  assert(scip != NULL);
479  assert(presoldata != NULL);
480 
481  if( presoldata->usefulsetppcexist )
482  {
483  int c;
484 
485  assert(presoldata->setppchashdatas != NULL || presoldata->nsetppchashdatas == 0);
486 
487  for( c = presoldata->nsetppchashdatas - 1; c >= 0; --c )
488  {
489  SCIP_Bool removeentry = FALSE;
490 
491  assert(presoldata->setppchashdatas[c] != NULL);
492  assert(presoldata->setppchashdatas[c]->cons != NULL);
493 
494  if( SCIPconsIsDeleted(presoldata->setppchashdatas[c]->cons) || SCIPconsIsModifiable(presoldata->setppchashdatas[c]->cons)
495  || SCIPgetTypeSetppc(scip, presoldata->setppchashdatas[c]->cons) != SCIP_SETPPCTYPE_PACKING || SCIPgetNVarsSetppc(scip, presoldata->setppchashdatas[c]->cons) != 2 )
496  {
497  removeentry = TRUE;
498  }
499  else
500  {
501  SCIP_VAR* vars[2];
502  SCIP_Bool negated[2];
503 
504  SCIP_CALL( SCIPgetBinvarRepresentative(scip, presoldata->setppchashdatas[c]->vars[0], &(vars[0]), &(negated[0])) );
505  SCIP_CALL( SCIPgetBinvarRepresentative(scip, presoldata->setppchashdatas[c]->vars[1], &(vars[1]), &(negated[1])) );
506 
509  || presoldata->setppchashdatas[c]->vars[0] != vars[0] || presoldata->setppchashdatas[c]->vars[1] != vars[1] )
510  {
511  removeentry = TRUE;
512  }
513  }
514 
515  if( removeentry )
516  {
517  /* remove constraint from setppc-hashtable */
518  assert(SCIPhashtableExists(presoldata->setppchashtable, (void*) presoldata->setppchashdatas[c]->cons));
519  SCIP_CALL( SCIPhashtableRemove(presoldata->setppchashtable, (void*) presoldata->setppchashdatas[c]->cons) );
520 
521  /* remove hashdata entry from hashtable */
522  SCIP_CALL( SCIPhashtableRemove(presoldata->hashdatatable, (void*) presoldata->setppchashdatas[c]) );
523 
524  /* release old constraints */
525  SCIP_CALL( SCIPreleaseCons(scip, &(presoldata->setppchashdatas[c]->cons)) );
526 
527  /* release variables */
528  SCIP_CALL( SCIPreleaseVar(scip, &(presoldata->setppchashdatas[c]->vars[0])) );
529  SCIP_CALL( SCIPreleaseVar(scip, &(presoldata->setppchashdatas[c]->vars[1])) );
530 
531  /* free memory for variables */
532  SCIPfreeBlockMemoryArray(scip, &(presoldata->setppchashdatas[c]->vars), 2);
533 
534  if( c < presoldata->nsetppchashdatas - 1 )
535  {
536  /* remove old hashdata entry from hashtable */
537  SCIP_CALL( SCIPhashtableRemove(presoldata->hashdatatable, (void*) presoldata->setppchashdatas[presoldata->nsetppchashdatas - 1]) );
538  }
539 
540  /* move last content to free position */
541  presoldata->setppchashdatas[c]->cons = presoldata->setppchashdatas[presoldata->nsetppchashdatas - 1]->cons;
542  presoldata->setppchashdatas[c]->vars = presoldata->setppchashdatas[presoldata->nsetppchashdatas - 1]->vars;
543  presoldata->setppchashdatas[c]->nvars = presoldata->setppchashdatas[presoldata->nsetppchashdatas - 1]->nvars;
544 
545  if( c < presoldata->nsetppchashdatas - 1 )
546  {
547  /* add new hashdata entry from hashtable */
548  SCIP_CALL( SCIPhashtableInsert(presoldata->hashdatatable, (void*) presoldata->setppchashdatas[c]) );
549  }
550  --(presoldata->nsetppchashdatas);
551  }
552  }
553 
554 #ifndef NDEBUG
555  for( c = presoldata->nsetppchashdatas - 1; c >= 0; --c )
556  {
557  assert(presoldata->setppchashdatas[c] != NULL);
558  assert(presoldata->setppchashdatas[c]->nvars == 2);
559  assert(presoldata->setppchashdatas[c]->vars != NULL);
560  assert(presoldata->setppchashdatas[c]->vars[0] != NULL);
561  assert(presoldata->setppchashdatas[c]->vars[1] != NULL);
562  assert(presoldata->setppchashdatas[c]->cons != NULL);
563  assert(SCIPconsIsActive(presoldata->setppchashdatas[c]->cons));
564  assert(SCIPhashtableExists(presoldata->hashdatatable, (void*) presoldata->setppchashdatas[c]));
565  assert(SCIPhashtableExists(presoldata->setppchashtable, (void*) presoldata->setppchashdatas[c]->cons));
566  }
567 #endif
568  }
569 
570  return SCIP_OKAY;
571 }
572 
573 /** refresh useful set-packing information, delete redundant constraints and add new constraints */
574 static
576  SCIP* scip, /**< SCIP data structure */
577  SCIP_PRESOLDATA* presoldata, /**< data object of presolver */
578  SCIP_CONS** setppcs, /**< active setppc constraints */
579  int nsetppcs, /**< number of active setppc constraints */
580  SCIP_CONS** logicors, /**< active setppc constraints */
581  int nlogicors /**< number of active setppc constraints */
582  )
583 {
584  int oldnsetppchashdatas;
585  int c;
586 
587  assert(scip != NULL);
588  assert(presoldata != NULL);
589  assert(setppcs != NULL);
590  assert(nsetppcs > 0);
591  assert(logicors != NULL);
592  assert(nlogicors > 0);
593  assert(presoldata->initialized);
594  assert(presoldata->setppchashtable != NULL);
595  assert(presoldata->logicorhashtable != NULL);
596 
597  /* check if there already exist some set-packing and some logicor constraints with the right amount of variables */
598  if( !presoldata->usefulsetppcexist || !presoldata->usefullogicorexist )
599  {
600  SCIP_Bool usefullogicorexisted = presoldata->usefullogicorexist;
601 
602  SCIP_CALL( createPresoldata(scip, presoldata, setppcs, nsetppcs, logicors, nlogicors) );
603 
604  /* if we already had useful logicor constraints but did not find any useful setppc constraint, the maximal number
605  * of variables appearing in a logicor constraint was not updated, so we do it here
606  */
607  if( usefullogicorexisted && !presoldata->usefulsetppcexist )
608  {
609  /* correct maximal number of varables in logicor constraints */
610  for( c = nlogicors - 1; c >= 0; --c )
611  {
612  assert(SCIPconsIsActive(logicors[c]));
613 
614  /* update maximal entries in a logicor constraint */
615  if( presoldata->maxnvarslogicor < SCIPgetNVarsLogicor(scip, logicors[c]) )
616  presoldata->maxnvarslogicor = SCIPgetNVarsLogicor(scip, logicors[c]);
617  }
618  }
619 
620  /* no correct logicor or set-packing constraints available, so abort */
621  if( !presoldata->usefulsetppcexist || !presoldata->usefullogicorexist )
622  return SCIP_OKAY;
623  }
624 
625  /* correct old data */
626  SCIP_CALL( cleanupHashDatas(scip, presoldata) );
627 
628  oldnsetppchashdatas = presoldata->nsetppchashdatas;
629 
630  /* first update setppc part */
631  /* add new setppc constraints */
632  for( c = nsetppcs - 1; c >= 0; --c )
633  {
634  assert(SCIPconsIsActive(setppcs[c]));
635 
636  if( SCIPgetTypeSetppc(scip, setppcs[c]) == SCIP_SETPPCTYPE_PACKING && SCIPgetNVarsSetppc(scip, setppcs[c]) == 2 && !SCIPconsIsModifiable(setppcs[c]) )
637  {
638  /* check if constraint is new, and correct array size if necessary */
639  if( !SCIPhashtableExists(presoldata->setppchashtable, (void*) setppcs[c]) )
640  {
641  SCIP_Bool negated[2];
642 
643  /* resize array if necessary */
644  if( presoldata->nsetppchashdatas == presoldata->ssetppchashdatas )
645  {
646  int newsize;
647  int d;
648 
649  newsize = SCIPcalcMemGrowSize(scip, presoldata->nsetppchashdatas + 1);
650 
651  /* array already at maximal size */
652  if( newsize <= presoldata->ssetppchashdatas )
653  return SCIP_NOMEMORY;
654 
655  /* correct hashtable, remove old elements */
656  SCIPhashtableRemoveAll(presoldata->hashdatatable);
657 
658  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(presoldata->setppchashdatas), presoldata->ssetppchashdatas, newsize) );
659  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(presoldata->setppchashdatastore), presoldata->ssetppchashdatas, newsize) );
660  presoldata->ssetppchashdatas = newsize;
661 
662  /* correct pointers in array, to point to the new storage, due to allocation, and add all elements to the
663  * hashtable again
664  */
665  for( d = presoldata->nsetppchashdatas - 1; d >= 0; --d )
666  {
667  presoldata->setppchashdatas[d] = &(presoldata->setppchashdatastore[d]);
668  SCIP_CALL( SCIPhashtableInsert(presoldata->hashdatatable, (void*) presoldata->setppchashdatas[d]) );
669  }
670  }
671 
672  /* insert new element in hashtable */
673  SCIP_CALL( SCIPhashtableInsert(presoldata->setppchashtable, (void*) setppcs[c]) );
674 
675  assert(SCIPgetNVarsSetppc(scip, setppcs[c]) == 2);
676  presoldata->setppchashdatas[presoldata->nsetppchashdatas] = &(presoldata->setppchashdatastore[presoldata->nsetppchashdatas]);
677 
678  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars), SCIPgetVarsSetppc(scip, setppcs[c]), 2) );
679  SCIP_CALL( SCIPgetBinvarRepresentative(scip, presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[0], &(presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[0]), &(negated[0])) );
680  SCIP_CALL( SCIPgetBinvarRepresentative(scip, presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[1], &(presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[1]), &(negated[1])) );
681 
682  if( SCIPvarGetStatus(presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[0]) == SCIP_VARSTATUS_FIXED || SCIPvarGetStatus(presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[0]) == SCIP_VARSTATUS_MULTAGGR
683  || SCIPvarGetStatus(presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[1]) == SCIP_VARSTATUS_FIXED || SCIPvarGetStatus(presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[1]) == SCIP_VARSTATUS_MULTAGGR )
684  {
685  SCIPfreeBlockMemoryArray(scip, &(presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars), 2);
686  continue;
687  }
688 
689  presoldata->setppchashdatas[presoldata->nsetppchashdatas]->nvars = 2;
690 
691  /* capture variables */
692  SCIP_CALL( SCIPcaptureVar(scip, presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[0]) );
693  SCIP_CALL( SCIPcaptureVar(scip, presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[1]) );
694 
695  /* order the variables after their index */
696  if( SCIPvarGetIndex(presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[0]) > SCIPvarGetIndex(presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[1]) )
697  {
698  SCIP_VAR* tmp = presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[0];
699  presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[0] = presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[1];
700  presoldata->setppchashdatas[presoldata->nsetppchashdatas]->vars[1] = tmp;
701  }
702 
703  presoldata->setppchashdatas[presoldata->nsetppchashdatas]->cons = setppcs[c];
704 
705  SCIP_CALL( SCIPhashtableInsert(presoldata->hashdatatable, (void*) presoldata->setppchashdatas[presoldata->nsetppchashdatas]) );
706  SCIP_CALL( SCIPcaptureCons(scip, setppcs[c]) );
707 
708  ++(presoldata->nsetppchashdatas);
709  }
710  }
711  }
712 
713  /* if we found new set-packing constraints, we want to check against all logicors */
714  if( oldnsetppchashdatas < presoldata->nsetppchashdatas )
715  presoldata->newsetppchashdatas = TRUE;
716 
717  /* now logicor part */
718  /* removed last deleted logicor constraints from local presolver data */
719  while( presoldata->nusefullogicor > 0 && !SCIPconsIsActive(presoldata->usefullogicor[presoldata->nusefullogicor - 1]) )
720  {
721  SCIP_CALL( SCIPhashtableRemove(presoldata->logicorhashtable, (void*) presoldata->usefullogicor[presoldata->nusefullogicor - 1]) );
722  SCIP_CALL( SCIPreleaseCons(scip, &(presoldata->usefullogicor[presoldata->nusefullogicor - 1])) );
723 
724  --(presoldata->nusefullogicor);
725  }
726 
727  /* remove old inactive logicor constraints */
728  for( c = presoldata->nusefullogicor - 1; c >= 0; --c )
729  {
730  /* update maximal entries in a logicor constraint */
731  if( presoldata->maxnvarslogicor < SCIPgetNVarsLogicor(scip, presoldata->usefullogicor[c]) )
732  presoldata->maxnvarslogicor = SCIPgetNVarsLogicor(scip, presoldata->usefullogicor[c]);
733 
734  if( !SCIPconsIsActive(presoldata->usefullogicor[c]) || SCIPconsIsModifiable(presoldata->usefullogicor[c]) || SCIPgetNVarsLogicor(scip, presoldata->usefullogicor[c]) < 3 )
735  {
736  SCIP_CALL( SCIPhashtableRemove(presoldata->logicorhashtable, (void*) presoldata->usefullogicor[c]) );
737  SCIP_CALL( SCIPreleaseCons(scip, &(presoldata->usefullogicor[c])) );
738 
739  presoldata->usefullogicor[c] = presoldata->usefullogicor[presoldata->nusefullogicor - 1];
740  --(presoldata->nusefullogicor);
741  }
742  }
743 
744  presoldata->firstchangedlogicor = presoldata->nusefullogicor;
745  assert(presoldata->firstchangedlogicor >= 0);
746 
747  /* add new logicor constraints */
748  for( c = nlogicors - 1; c >= 0; --c )
749  {
750  assert(SCIPconsIsActive(logicors[c]));
751 
752  if( !SCIPconsIsModifiable(logicors[c]) && SCIPgetNVarsLogicor(scip, logicors[c]) >= 3 )
753  {
754  /* check if constraint is new, and correct array size if necessary */
755  if( !SCIPhashtableExists(presoldata->logicorhashtable, (void*) logicors[c]) )
756  {
757  /* resize array if necessary */
758  if( presoldata->nusefullogicor == presoldata->susefullogicor )
759  {
760  int newsize;
761 
762  newsize = SCIPcalcMemGrowSize(scip, presoldata->nusefullogicor + 1);
763 
764  /* array already at maximal size */
765  if( newsize <= presoldata->susefullogicor )
766  return SCIP_NOMEMORY;
767 
768  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &(presoldata->usefullogicor), presoldata->susefullogicor, newsize) );
769  presoldata->susefullogicor = newsize;
770  }
771 
772  /* insert new element in hashtable */
773  SCIP_CALL( SCIPhashtableInsert(presoldata->logicorhashtable, (void*) logicors[c]) );
774  SCIP_CALL( SCIPcaptureCons(scip, logicors[c]) );
775 
776  presoldata->usefullogicor[presoldata->nusefullogicor] = logicors[c];
777  ++(presoldata->nusefullogicor);
778 
779  /* update maximal entries in a logicor constraint */
780  if( presoldata->maxnvarslogicor < SCIPgetNVarsLogicor(scip, logicors[c]) )
781  presoldata->maxnvarslogicor = SCIPgetNVarsLogicor(scip, logicors[c]);
782  }
783  }
784  }
785 
786  return SCIP_OKAY;
787 }
788 
789 
790 /** extract and-constraints and set-partitioning constraints */
791 static
793  SCIP* scip, /**< SCIP data structure */
794  SCIP_PRESOLDATA* presoldata, /**< data object of presolver */
795  int pos, /**< position of logicor in usefullogicor array to presolve */
796  SCIP_HASHMAP* varmap, /**< variable map mapping inactive variables to their active representation */
797  SCIP_CONS** gateconss, /**< allocated memory for all gate-constraints */
798  SCIP_VAR** activevars, /**< allocated memory for active variables */
799  SCIP_VAR** posresultants, /**< allocated memory for all possible resultant variables */
800  HASHDATA* hashdata, /**< allocated memory for a hashdata object */
801  int* ndelconss, /**< pointer to store number of deleted constraints */
802  int* naddconss /**< pointer to store number of added constraints */
803  )
804 {
805  SCIP_VAR** logicorvars;
806  SCIP_VAR* tmpvars[2];
807  HASHDATA* hashmaphashdata;
808  SCIP_CONS* logicor;
809  SCIP_Bool negated;
810  int ngateconss;
811  int nlogicorvars;
812  int nposresultants;
813  int d;
814  int v;
815 
816  assert(scip != NULL);
817  assert(presoldata != NULL);
818  assert(0 <= pos && pos < presoldata->nusefullogicor);
819  assert(gateconss != NULL);
820  assert(activevars != NULL);
821  assert(posresultants != NULL);
822  assert(hashdata != NULL);
823  assert(hashdata->nvars == 2);
824  assert(hashdata->cons == NULL);
825  assert(ndelconss != NULL);
826  assert(naddconss != NULL);
827 
828  assert(presoldata->usefullogicor != NULL);
829  logicor = presoldata->usefullogicor[pos];
830  assert(logicor != NULL);
831 
832  if( !SCIPconsIsActive(logicor) )
833  return SCIP_OKAY;
834 
835  assert(!SCIPconsIsModifiable(logicor));
836 
837  nlogicorvars = SCIPgetNVarsLogicor(scip, logicor);
838  assert(nlogicorvars >= 3 && nlogicorvars <= presoldata->maxnvarslogicor);
839 
840  logicorvars = SCIPgetVarsLogicor(scip, logicor);
841  assert(logicorvars != NULL);
842 
843  nposresultants = 0;
844 
845  /* get active logicor variables and determine all possible resultants */
846  for( d = nlogicorvars - 1; d >= 0; --d )
847  {
848  /* do not work with fixed variables */
849  if( SCIPvarGetLbLocal(logicorvars[d]) > 0.5 || SCIPvarGetUbLocal(logicorvars[d]) < 0.5 )
850  return SCIP_OKAY;
851 
852  activevars[d] = (SCIP_VAR*) SCIPhashmapGetImage(varmap, logicorvars[d]);
853 
854  if( activevars[d] == NULL )
855  {
856  SCIP_CALL( SCIPgetBinvarRepresentative(scip, logicorvars[d], &(activevars[d]), &negated) );
857  SCIP_CALL( SCIPhashmapInsert(varmap, logicorvars[d], activevars[d]) );
858  }
859 
860  /* determine possible resultants a check if the other variables can appear in a set-packing constraint */
861  if( SCIPvarIsNegated(activevars[d]) )
862  {
863  assert(SCIPvarIsActive(SCIPvarGetNegatedVar(activevars[d])));
864 
865  if( SCIPvarGetNLocksDown(SCIPvarGetNegatedVar(activevars[d])) >= nlogicorvars - 1 )
866  {
867  posresultants[nposresultants] = activevars[d];
868  ++nposresultants;
869  }
870  else if( SCIPvarGetNLocksDown(SCIPvarGetNegatedVar(activevars[d])) == 0 )
871  return SCIP_OKAY;
872  }
873  else
874  {
875  assert(SCIPvarIsActive(activevars[d]));
876 
877  if( SCIPvarGetNLocksUp(activevars[d]) >= nlogicorvars - 1 )
878  {
879  posresultants[nposresultants] = activevars[d];
880  ++nposresultants;
881  }
882  else if( SCIPvarGetNLocksUp(activevars[d]) == 0 )
883  return SCIP_OKAY;
884  }
885  }
886 
887  if( nposresultants == 0 )
888  return SCIP_OKAY;
889 
890  /* sort variables after indices */
891  SCIPsortPtr((void**)activevars, SCIPvarComp, nlogicorvars);
892 
893  /* check that we have really different variables, if not remove the constraint from the hashmap and the data
894  * storage
895  */
896  for( d = nlogicorvars - 1; d > 0; --d )
897  {
898  if( SCIPvarGetIndex(activevars[d]) == SCIPvarGetIndex(activevars[d - 1]) )
899  {
900  assert(presoldata->usefullogicor[pos] == logicor);
901 
902  SCIP_CALL( SCIPhashtableRemove(presoldata->logicorhashtable, (void*) logicor) );
903  SCIP_CALL( SCIPreleaseCons(scip, &logicor) );
904 
905  presoldata->usefullogicor[pos] = presoldata->usefullogicor[presoldata->nusefullogicor - 1];
906  --(presoldata->nusefullogicor);
907 
908  return SCIP_OKAY;
909  }
910  }
911 
912  ngateconss = 0;
913 
914  for( d = nposresultants - 1; d >= 0; --d )
915  {
916  ngateconss = 0;
917 
918  for( v = nlogicorvars - 1; v >= 0; --v )
919  {
920  if( activevars[v] == posresultants[d] )
921  continue;
922 
923  /* variables need to be sorted */
924  if( SCIPvarCompare(posresultants[d], activevars[v]) > 0 )
925  {
926  tmpvars[0] = activevars[v];
927  tmpvars[1] = posresultants[d];
928  }
929  else
930  {
931  tmpvars[0] = posresultants[d];
932  tmpvars[1] = activevars[v];
933  }
934  hashdata->vars = tmpvars;
935 
936  hashmaphashdata = (HASHDATA*) SCIPhashtableRetrieve(presoldata->hashdatatable, (void*) hashdata);
937 
938  if( hashmaphashdata != NULL && SCIPconsIsActive(hashmaphashdata->cons) )
939  {
940  gateconss[ngateconss] = hashmaphashdata->cons;
941  ++ngateconss;
942  }
943  else
944  break;
945  }
946  if( ngateconss == nlogicorvars - 1 )
947  break;
948  }
949 
950  /* @todo, check for clique of all variables except the resultant */
951  /* check if we have a set-partitioning 'gate' */
952  if( ngateconss == nlogicorvars - 1 && nlogicorvars == 3 )
953  {
954  assert(d >= 0 && d < nposresultants);
955  assert(ngateconss >= 2);
956 
957  if( activevars[0] == posresultants[d] )
958  {
959  tmpvars[0] = activevars[1];
960  tmpvars[1] = activevars[2];
961  }
962  else if( activevars[1] == posresultants[d] )
963  {
964  tmpvars[0] = activevars[0];
965  tmpvars[1] = activevars[2];
966  }
967  else
968  {
969  assert(activevars[2] == posresultants[d]);
970  tmpvars[0] = activevars[0];
971  tmpvars[1] = activevars[1];
972  }
973  hashdata->vars = tmpvars;
974 
975  hashmaphashdata = (HASHDATA*) SCIPhashtableRetrieve(presoldata->hashdatatable, (void*) hashdata);
976  assert(hashmaphashdata == NULL || hashmaphashdata->cons != NULL);
977 
978  if( hashmaphashdata != NULL && SCIPconsIsActive(hashmaphashdata->cons) )
979  {
980  gateconss[ngateconss] = hashmaphashdata->cons;
981  ++ngateconss;
982  }
983  }
984 
985  /* did we find enough (>= number of variables in logicor - 1) set-packing constraints for an upgrade to either
986  * an and-constraint or even a set-partitioning constraint
987  */
988  if( ngateconss == nlogicorvars || (ngateconss >= nlogicorvars - 1 && !presoldata->onlysetpart))
989  {
990  SCIP_CONS* newcons;
991  char name[SCIP_MAXSTRLEN];
992  SCIP_Bool initial;
993  SCIP_Bool separate;
994  SCIP_Bool enforce;
995  SCIP_Bool check;
996  SCIP_Bool propagate;
997  SCIP_Bool local;
998  SCIP_Bool modifiable;
999  SCIP_Bool dynamic;
1000  SCIP_Bool removable;
1001  SCIP_Bool stickingatnode;
1002  int i;
1003 
1004  assert(ngateconss <= nlogicorvars);
1005  assert(d >= 0 && d < nposresultants);
1006 
1007  initial = SCIPconsIsInitial(logicor);
1008  separate = SCIPconsIsSeparated(logicor);
1009  enforce = SCIPconsIsEnforced(logicor);
1010  check = SCIPconsIsChecked(logicor);
1011  propagate = SCIPconsIsPropagated(logicor);
1012  local = SCIPconsIsLocal(logicor);
1013  modifiable = SCIPconsIsModifiable(logicor);
1014  dynamic = SCIPconsIsDynamic(logicor);
1015  removable = SCIPconsIsRemovable(logicor);
1016  stickingatnode = SCIPconsIsStickingAtNode(logicor);
1017 
1018 #ifdef SCIP_DEBUG
1019  if( ngateconss == nlogicorvars )
1020  {
1021  SCIPdebugMessage("Following constraints form a set-partitioning constraint.\n");
1022  }
1023  else
1024  {
1025  SCIPdebugMessage("Following constraints form an and-constraint.\n");
1026  }
1027 #endif
1028 
1029  for( v = ngateconss - 1; v >= 0; --v )
1030  {
1031  assert(gateconss[v] != NULL);
1032 
1033  initial |= SCIPconsIsInitial(gateconss[v]);
1034  separate |= SCIPconsIsSeparated(gateconss[v]);
1035  enforce |= SCIPconsIsEnforced(gateconss[v]);
1036  check |= SCIPconsIsChecked(gateconss[v]);
1037  propagate |= SCIPconsIsPropagated(gateconss[v]);
1038  local &= SCIPconsIsLocal(gateconss[v]);
1039  modifiable &= SCIPconsIsModifiable(gateconss[v]);
1040  dynamic &= SCIPconsIsDynamic(gateconss[v]);
1041  removable &= SCIPconsIsRemovable(gateconss[v]);
1042  stickingatnode &= SCIPconsIsStickingAtNode(gateconss[v]);
1043 
1044  SCIPdebugPrintCons(scip, gateconss[v], NULL);
1045 
1046  SCIP_CALL( SCIPdelCons(scip, gateconss[v]) );
1047  ++(*ndelconss);
1048  }
1049 
1050  SCIPdebugPrintCons(scip, logicor, NULL);
1051 
1052  if( ngateconss == nlogicorvars - 1 )
1053  {
1054  SCIP_VAR** consvars;
1055 
1056  assert(!presoldata->onlysetpart);
1057 
1058  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, ngateconss) );
1059  i = 0;
1060 
1061  /* determine and operands */
1062  for( v = nlogicorvars - 1; v >= 0; --v )
1063  {
1064  if( activevars[v] == posresultants[d] )
1065  continue;
1066 
1067  SCIP_CALL( SCIPgetNegatedVar(scip, activevars[v], &consvars[i]) );
1068  ++i;
1069  }
1070  assert(i == ngateconss);
1071 
1072  /* create and add "and" constraint for the extracted gate */
1073  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "andgate_%d", presoldata->ngates);
1074  SCIP_CALL( SCIPcreateConsAnd(scip, &newcons, name, posresultants[d], ngateconss, consvars,
1075  initial, separate, enforce, check, propagate,
1076  local, modifiable, dynamic, removable, stickingatnode) );
1077 
1078  SCIP_CALL( SCIPaddCons(scip, newcons) );
1079  SCIPdebugMessage("-------------->\n");
1080  SCIPdebugPrintCons(scip, newcons, NULL);
1081 
1082  ++(*naddconss);
1083  ++(presoldata->ngates);
1084 
1085  SCIP_CALL( SCIPdelCons(scip, logicor) );
1086  ++(*ndelconss);
1087 
1088  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
1089 
1090  SCIPfreeBufferArray(scip, &consvars);
1091  }
1092  else
1093  {
1094  assert(ngateconss == nlogicorvars);
1095 
1096  /* create and add set-partitioning constraint */
1097  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "setpart_%d", presoldata->ngates);
1098  SCIP_CALL( SCIPcreateConsSetpart(scip, &newcons, name, nlogicorvars, activevars,
1099  initial, separate, enforce, check, propagate,
1100  local, modifiable, dynamic, removable, stickingatnode) );
1101 
1102  SCIP_CALL( SCIPaddCons(scip, newcons) );
1103  SCIPdebugMessage("-------------->\n");
1104  SCIPdebugPrintCons(scip, newcons, NULL);
1105 
1106  ++(*naddconss);
1107  ++(presoldata->ngates);
1108 
1109  SCIP_CALL( SCIPdelCons(scip, logicor) );
1110  ++(*ndelconss);
1111 
1112  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
1113  }
1114  }
1115 
1116  return SCIP_OKAY;
1117 }
1118 
1119 
1120 /*
1121  * Callback methods of presolver
1122  */
1123 
1124 
1125 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
1126 static
1127 SCIP_DECL_PRESOLCOPY(presolCopyGateextraction)
1128 { /*lint --e{715}*/
1129  assert(scip != NULL);
1130  assert(presol != NULL);
1131  assert(strcmp(SCIPpresolGetName(presol), PRESOL_NAME) == 0);
1132 
1133  /* call inclusion method of presolver */
1135 
1136  return SCIP_OKAY;
1137 }
1138 
1139 
1140 /** destructor of presolver to free user data (called when SCIP is exiting) */
1141 static
1142 SCIP_DECL_PRESOLFREE(presolFreeGateextraction)
1143 { /*lint --e{715}*/
1144  SCIP_PRESOLDATA* presoldata;
1145 
1146  /* free presolver data */
1147  presoldata = SCIPpresolGetData(presol);
1148  assert(presoldata != NULL);
1149 
1150  if( presoldata->hashdatatable != NULL )
1151  {
1152  assert(presoldata->setppchashtable != NULL);
1153  assert(presoldata->logicorhashtable != NULL);
1154 
1155  SCIPhashtableFree(&(presoldata->logicorhashtable));
1156  SCIPhashtableFree(&(presoldata->setppchashtable));
1157  SCIPhashtableFree(&(presoldata->hashdatatable));
1158  }
1159 
1160  SCIPfreeMemory(scip, &presoldata);
1161  SCIPpresolSetData(presol, NULL);
1162 
1163  return SCIP_OKAY;
1164 }
1165 
1166 
1167 /** deinitialization method of presolver (called before transformed problem is freed) */
1168 static
1169 SCIP_DECL_PRESOLEXIT(presolExitGateextraction)
1170 { /*lint --e{715}*/
1171  SCIP_PRESOLDATA* presoldata;
1172  int c;
1174  /* free presolver data */
1175  presoldata = SCIPpresolGetData(presol);
1176  assert(presoldata != NULL);
1177 
1178  /* release old constraints */
1179  for( c = presoldata->nusefullogicor - 1; c >= 0; --c )
1180  {
1181  SCIP_CALL( SCIPreleaseCons(scip, &(presoldata->usefullogicor[c])) );
1182  }
1183 
1184  if( presoldata->usefullogicorexist )
1185  {
1186  SCIPfreeBlockMemoryArray(scip, &presoldata->usefullogicor, presoldata->susefullogicor);
1187  }
1188 
1189  if( presoldata->usefulsetppcexist )
1190  {
1191  assert(presoldata->setppchashdatas != NULL || presoldata->nsetppchashdatas == 0);
1192  for( c = presoldata->nsetppchashdatas - 1; c >= 0; --c )
1193  {
1194  assert(presoldata->setppchashdatas[c] != NULL);
1195  assert(presoldata->setppchashdatas[c]->cons != NULL);
1196  assert(presoldata->setppchashdatas[c]->vars != NULL);
1197 
1198  /* remove constraint from setppc-hashtable */
1199  assert(SCIPhashtableExists(presoldata->setppchashtable, (void*) presoldata->setppchashdatas[c]->cons));
1200  SCIP_CALL( SCIPhashtableRemove(presoldata->setppchashtable, (void*) presoldata->setppchashdatas[c]->cons) );
1201 
1202  /* release old constraints */
1203  SCIP_CALL( SCIPreleaseCons(scip, &(presoldata->setppchashdatas[c]->cons)) );
1204 
1205  /* remove hashdata entry from hashtable */
1206  SCIP_CALL( SCIPhashtableRemove(presoldata->hashdatatable, (void*) presoldata->setppchashdatas[c]) );
1207 
1208  /* release variables */
1209  SCIP_CALL( SCIPreleaseVar(scip, &(presoldata->setppchashdatas[c]->vars[0])) );
1210  SCIP_CALL( SCIPreleaseVar(scip, &(presoldata->setppchashdatas[c]->vars[1])) );
1211 
1212  /* free memory for variables */
1213  SCIPfreeBlockMemoryArray(scip, &(presoldata->setppchashdatas[c]->vars), 2);
1214  }
1215 
1216  SCIPfreeBlockMemoryArray(scip, &(presoldata->setppchashdatastore), presoldata->ssetppchashdatas);
1217  SCIPfreeBlockMemoryArray(scip, &(presoldata->setppchashdatas), presoldata->ssetppchashdatas);
1218  }
1219 
1220  if( presoldata->hashdatatable != NULL )
1221  {
1222  assert(presoldata->setppchashtable != NULL);
1223  assert(presoldata->logicorhashtable != NULL);
1224 
1225  /* clear old hashtable entries */
1226  SCIPhashtableRemoveAll(presoldata->hashdatatable);
1227  SCIPhashtableRemoveAll(presoldata->setppchashtable);
1228  SCIPhashtableRemoveAll(presoldata->logicorhashtable);
1229  }
1230 
1231  presoldata->nusefullogicor = 0;
1232  presoldata->susefullogicor = 0;
1233  presoldata->nsetppchashdatas = 0;
1234  presoldata->ssetppchashdatas = 0;
1235  presoldata->firstchangedlogicor = -1;
1236  presoldata->ngates = 0;
1237  presoldata->usefullogicorexist = FALSE;
1238  presoldata->usefulsetppcexist = FALSE;
1239  presoldata->newsetppchashdatas = FALSE;
1240  presoldata->initialized = FALSE;
1241 
1242  return SCIP_OKAY;
1243 }
1244 
1245 
1246 /** presolving initialization method of presolver (called when presolving is about to begin) */
1247 static
1248 SCIP_DECL_PRESOLINITPRE(presolInitpreGateextraction)
1249 { /*lint --e{715}*/
1250  return SCIP_OKAY;
1251 }
1253 
1254 /** presolving deinitialization method of presolver (called after presolving has been finished) */
1255 static
1256 SCIP_DECL_PRESOLEXITPRE(presolExitpreGateextraction)
1257 { /*lint --e{715}*/
1258  return SCIP_OKAY;
1259 }
1261 
1262 #define HASHTABLESIZE_FACTOR 5
1263 
1264 /** execution method of presolver */
1265 static
1266 SCIP_DECL_PRESOLEXEC(presolExecGateextraction)
1267 { /*lint --e{715}*/
1268  SCIP_PRESOLDATA* presoldata;
1269  SCIP_HASHMAP* varmap;
1270  HASHDATA* hashdata;
1271  SCIP_CONSHDLR* conshdlrsetppc;
1272  SCIP_CONSHDLR* conshdlrlogicor;
1273  SCIP_CONSHDLR* conshdlrand;
1274  SCIP_CONS** setppcconss;
1275  SCIP_CONS** logicorconss;
1276  int nsetppcconss;
1277  int nlogicorconss;
1278  int size;
1279  int c;
1280  SCIP_Bool paramvalue;
1281 
1282  assert(scip != NULL);
1283  assert(presol != NULL);
1284  assert(strcmp(SCIPpresolGetName(presol), PRESOL_NAME) == 0);
1285  assert(result != NULL);
1286 
1287  *result = SCIP_DIDNOTRUN;
1288 
1289 #if 0 /* need to include cons_knapsack on top of this file */
1290  /* check for possible knapsacks that form with a logicor a weak relaxation of an and-constraint
1291  *
1292  * the weak relaxation of an and-constraint looks like:
1293  * - row1: resvar - v1 - ... - vn >= 1-n
1294  * - row2: n*resvar - v1 - ... - vn <= 0.0
1295  *
1296  * which look like the following contraints
1297  * - logicor: resvar + ~v1 + ... + ~vn >= 1
1298  * - knapsack: n*resvar + ~v1 + ... + ~vn <= n
1299  */
1300  {
1301  SCIP_CONSHDLR* conshdlrknapsack;
1302  SCIP_CONS** knapsackconss;
1303  int nknapsackconss;
1304  SCIP_VAR** vars;
1305  SCIP_Longint* vals;
1306  SCIP_Longint capacity;
1307  int nvars;
1308 
1309  conshdlrknapsack = SCIPfindConshdlr(scip, "knapsack");
1310 
1311  /* get number of active constraints */
1312  knapsackconss = SCIPconshdlrGetConss(conshdlrknapsack);
1313  nknapsackconss = SCIPconshdlrGetNActiveConss(conshdlrknapsack);
1314  assert(nknapsackconss >= 0);
1315  assert(knapsackconss != NULL || nknapsackconss == 0);
1316 
1317  for( c = nknapsackconss - 1; c >= 0; --c )
1318  {
1319  /* not implemented in master branch, but the constraint may be already sorted */
1320  /*SCIPsortKnapsack(scip, knapsackconss[c]);*/
1321 
1322  nvars = SCIPgetNVarsKnapsack(scip, knapsackconss[c]);
1323  vals = SCIPgetWeightsKnapsack(scip, knapsackconss[c]);
1324  vars = SCIPgetVarsKnapsack(scip, knapsackconss[c]);
1325  capacity = SCIPgetCapacityKnapsack(scip, knapsackconss[c]);
1326 
1327  if( nvars > 1 && capacity == nvars - 1 && vals[0] == capacity && vals[1] == 1 )
1328  {
1329  printf("possible knapsack for gate extraction\n");
1330  }
1331  }
1332  }
1333 #endif
1334 
1335  /* get necessary constraint handlers */
1336  conshdlrsetppc = SCIPfindConshdlr(scip, "setppc");
1337  conshdlrlogicor = SCIPfindConshdlr(scip, "logicor");
1338 
1339  if( conshdlrsetppc == NULL || conshdlrlogicor == NULL )
1340  return SCIP_OKAY;
1341 
1342  /* get number of active constraints */
1343  nsetppcconss = SCIPconshdlrGetNActiveConss(conshdlrsetppc);
1344  assert(nsetppcconss >= 0);
1345  nlogicorconss = SCIPconshdlrGetNActiveConss(conshdlrlogicor);
1346  assert(nlogicorconss >= 0);
1347 
1348  if( nsetppcconss == 0 || nlogicorconss == 0 )
1349  return SCIP_OKAY;
1350 
1351  /* get presolver data */
1352  presoldata = SCIPpresolGetData(presol);
1353  assert(presoldata != NULL);
1354 
1355  conshdlrand = SCIPfindConshdlr(scip, "and");
1356 
1357  /* need and-constraint handler to extract and-gates */
1358  if( conshdlrand == NULL )
1359  {
1360  /* nothing to do when we cannot extract anything */
1361  if( !presoldata->searchequations )
1362  return SCIP_OKAY;
1363  else
1364  {
1365  /* make sure that we correct the parameter for only extrating set-partitioning constraints */
1366  if( SCIPisParamFixed(scip, "presolving/" PRESOL_NAME "/onlysetpart") )
1367  {
1368  SCIPwarningMessage(scip, "unfixing parameter <presolving/" PRESOL_NAME "/onlysetpart> in gate extration presolver\n");
1369  SCIP_CALL( SCIPunfixParam(scip, "presolving/" PRESOL_NAME "/onlysetpart") );
1370  }
1371  SCIP_CALL( SCIPsetBoolParam(scip, "presolving/" PRESOL_NAME "/onlysetpart", TRUE) );
1372  assert(presoldata->onlysetpart);
1373  }
1374  }
1375 
1376  paramvalue = FALSE;
1377  if( conshdlrand != NULL && SCIPgetBoolParam(scip, "constraints/and/linearize", &paramvalue) == SCIP_OKAY )
1378  {
1379  if( paramvalue )
1380  {
1381  SCIPwarningMessage(scip, "Gate-presolving is the 'counterpart' of linearizing all and-constraints, so enabling both presolving steps at ones does not make sense.\n");
1382  }
1383  }
1384  *result = SCIP_DIDNOTFIND;
1385 
1386  /* get active constraints */
1387  SCIP_CALL( SCIPduplicateBufferArray(scip, &setppcconss, SCIPconshdlrGetConss(conshdlrsetppc), nsetppcconss) );
1388 
1389  assert(setppcconss != NULL);
1390  logicorconss = SCIPconshdlrGetConss(conshdlrlogicor);
1391  assert(logicorconss != NULL);
1392 
1393  /* first we need to initialized the hashtables if not yet done */
1394  if( presoldata->hashdatatable == NULL )
1395  {
1396  SCIP_CALL( presoldataInitHashtables(scip, presoldata) );
1397  }
1398  assert(presoldata->hashdatatable != NULL);
1399  assert(presoldata->setppchashtable != NULL);
1400  assert(presoldata->logicorhashtable != NULL);
1401 
1402  presoldata->newsetppchashdatas = FALSE;
1403 
1404  if( !presoldata->initialized )
1405  {
1406  assert(presoldata->usefullogicor == NULL);
1407 
1408  /* create useful set-packing information by adding new set-packing constraints with two variables */
1409  SCIP_CALL( createPresoldata(scip, presoldata, setppcconss, nsetppcconss, logicorconss, nlogicorconss) );
1410  }
1411  else
1412  {
1413  /* refresh useful set-packing information, delete redundant constraints and add new constraints */
1414  SCIP_CALL( correctPresoldata(scip, presoldata, setppcconss, nsetppcconss, logicorconss, nlogicorconss) );
1415  }
1416  assert(presoldata->initialized);
1417 
1418  if( presoldata->nusefullogicor == 0 )
1419  goto TERMINATE;
1420 
1421  /* move the biggate extraction to front or back by sort the logicors after number of variables */
1422 
1423  if( presoldata->sorting != 0 )
1424  {
1425  int* lengths;
1426 
1427  SCIP_CALL( SCIPallocBufferArray(scip, &lengths, presoldata->nusefullogicor) );
1428 
1429  for( c = presoldata->nusefullogicor - 1; c >= 0; --c )
1430  {
1431  lengths[c] = SCIPgetNVarsLogicor(scip, presoldata->usefullogicor[c]);
1432  }
1433 
1434  if( presoldata->sorting == -1 )
1435  SCIPsortDownIntPtr(lengths, (void**)presoldata->usefullogicor, presoldata->nusefullogicor);
1436  else
1437  SCIPsortIntPtr(lengths, (void**)presoldata->usefullogicor, presoldata->nusefullogicor);
1438 
1439  SCIPfreeBufferArray(scip, &lengths);
1440  }
1441 
1442  /* maximal number of binary variables */
1443  size = SCIPgetNBinVars(scip) + SCIPgetNImplVars(scip);
1444 
1445  /* create the variable mapping hash map */
1447 
1448  /* search for set-partitioning constraints arising from a logicor and a set-packing constraints with equal variables */
1449  if( presoldata->searchequations && !SCIPisStopped(scip) )
1450  {
1451  SCIP_HASHTABLE* setppchashdatatable;
1452  HASHDATA** setppchashdatas;
1453  HASHDATA* setppchashdatastore;
1454  HASHDATA* hashmaphashdata;
1455  SCIP_CONS* logicor;
1456  SCIP_CONS* setppc;
1457  SCIP_VAR** logicorvars;
1458  SCIP_VAR** setppcvars;
1459  SCIP_VAR** activevarslogicor;
1460  SCIP_VAR** activevarssetppc;
1461  SCIP_Bool negated;
1462  int nsetppchashdatas;
1463  int nlogicorvars;
1464  int nsetppcvars;
1465  int d;
1466  int v;
1467 
1468  assert(nsetppcconss > 0);
1469 
1470  /* create local hashtable */
1471  SCIP_CALL( SCIPhashtableCreate(&setppchashdatatable, SCIPblkmem(scip), 5 * nsetppcconss, SCIPhashGetKeyStandard, setppcHashdataKeyEqCons, setppcHashdataKeyValCons, (void*) scip) );
1472 
1473  /* maximal number of binary variables */
1474  size = presoldata->maxnvarslogicor;
1475  assert(size >= 3);
1476 
1477  /* get temporary memory */
1478  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &setppchashdatastore, nsetppcconss) );
1479  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &setppchashdatas, nsetppcconss) );
1480  SCIP_CALL( SCIPallocBufferArray(scip, &activevarssetppc, size) );
1481  SCIP_CALL( SCIPallocBufferArray(scip, &activevarslogicor, size) );
1482 
1483  /* allocate memory for the temporary hashdata object to search for a corresponding set-packing/-partitioning
1484  * constraint
1485  */
1486  SCIP_CALL( SCIPallocBuffer(scip, &hashdata) );
1487  hashdata->cons = NULL;
1488 
1489  nsetppchashdatas = 0;
1490 
1491  /* collect all set-packing/-partitioning constraints and corresponding data to be able to search faster */
1492  for( d = nsetppcconss - 1; d >= 0; --d )
1493  {
1494  setppc = setppcconss[d];
1495  assert(setppc != NULL);
1496 
1497  if( SCIPconsIsDeleted(setppc) )
1498  continue;
1499 
1500  /* @todo if of interest could also be implemented for set-covering constraints */
1501 #if 1
1502  if( SCIPgetTypeSetppc(scip, setppc) == SCIP_SETPPCTYPE_COVERING )
1503  continue;
1504 #endif
1505 
1506  nsetppcvars = SCIPgetNVarsSetppc(scip, setppc);
1507 
1508  if( nsetppcvars < 2 )
1509  continue;
1510 
1511  if( SCIPconsIsModifiable(setppc) )
1512  continue;
1513 
1514  /* to big setppc constraints are picked out */
1515  if( nsetppcvars > size )
1516  continue;
1517 
1518  setppcvars = SCIPgetVarsSetppc(scip, setppc);
1519  assert(setppcvars != NULL);
1520 
1521  /* get active setppc variables */
1522  for( v = nsetppcvars - 1; v >= 0; --v )
1523  {
1524  /* do not work with fixed variables */
1525  if( SCIPvarGetLbLocal(setppcvars[v]) > 0.5 || SCIPvarGetUbLocal(setppcvars[v]) < 0.5 )
1526  break;
1527 
1528  activevarssetppc[v] = (SCIP_VAR*) SCIPhashmapGetImage(varmap, setppcvars[v]);
1529 
1530  if( activevarssetppc[v] == NULL )
1531  {
1532  SCIP_CALL( SCIPgetBinvarRepresentative(scip, setppcvars[v], &(activevarssetppc[v]), &negated) );
1533  SCIP_CALL( SCIPhashmapInsert(varmap, setppcvars[v], activevarssetppc[v]) );
1534  }
1535  }
1536 
1537  /* if we found a fixed variable we want disregard this constraint */
1538  if( v >= 0 )
1539  continue;
1540 
1541  /* variables need to be sorted after indices to be able to do a fast comparison */
1542  SCIPsortPtr((void**)activevarssetppc, SCIPvarComp, nsetppcvars);
1543 
1544  setppchashdatas[nsetppchashdatas] = &(setppchashdatastore[nsetppchashdatas]);
1545 
1546  /* memorize set-packing data */
1547  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(setppchashdatas[nsetppchashdatas]->vars), activevarssetppc, nsetppcvars) );
1548 
1549  setppchashdatas[nsetppchashdatas]->nvars = nsetppcvars;
1550  setppchashdatas[nsetppchashdatas]->cons = setppc;
1551  /* need to capture this constraint, because it might get deleted during the process */
1552  SCIP_CALL( SCIPcaptureCons(scip, setppc) );
1553 
1554  /* add entry to local hashtable */
1555  SCIP_CALL( SCIPhashtableInsert(setppchashdatatable, (void*) setppchashdatas[nsetppchashdatas]) );
1556  ++nsetppchashdatas;
1557  }
1558 
1559  /* check all (new) logicors against all collected set-packing/-partitioning constraints */
1560  for( c = nlogicorconss - 1; c >= 0 && !SCIPisStopped(scip); --c )
1561  {
1562  logicor = logicorconss[c];
1563  assert(logicor != NULL);
1564 
1565  if( SCIPconsIsDeleted(logicor) )
1566  continue;
1567 
1568  nlogicorvars = SCIPgetNVarsLogicor(scip, logicor);
1569 
1570  if( nlogicorvars < 2 )
1571  continue;
1572 
1573  if( SCIPconsIsModifiable(logicor) )
1574  continue;
1575 
1576  assert(nlogicorvars <= size);
1577 
1578  logicorvars = SCIPgetVarsLogicor(scip, logicor);
1579  assert(logicorvars != NULL);
1580 
1581  /* get active logicor variables */
1582  for( v = nlogicorvars - 1; v >= 0; --v )
1583  {
1584  /* do not work with fixed variables */
1585  if( SCIPvarGetLbLocal(logicorvars[v]) > 0.5 || SCIPvarGetUbLocal(logicorvars[v]) < 0.5 )
1586  break;
1587 
1588  activevarslogicor[v] = (SCIP_VAR*) SCIPhashmapGetImage(varmap, logicorvars[v]);
1589 
1590  /* if image does not exist, then there is no corresponding set-packing constraint */
1591  if( activevarslogicor[v] == NULL )
1592  break;
1593  }
1594 
1595  if( v == -1 )
1596  {
1597  /* need sorting to be able to find the correct hashdata element */
1598  SCIPsortPtr((void**)activevarslogicor, SCIPvarComp, nlogicorvars);
1599 
1600  hashdata->nvars = nlogicorvars;
1601  hashdata->vars = activevarslogicor;
1602 
1603  hashmaphashdata = (HASHDATA*) SCIPhashtableRetrieve(setppchashdatatable, (void*) hashdata);
1604  assert(hashmaphashdata == NULL || hashmaphashdata->cons != NULL);
1605 
1606  if( hashmaphashdata != NULL && !SCIPconsIsDeleted(hashmaphashdata->cons) )
1607  {
1608  SCIP_Bool initial;
1609  SCIP_Bool separate;
1610  SCIP_Bool enforce;
1611  SCIP_Bool check;
1612  SCIP_Bool propagate;
1613  SCIP_Bool local;
1614  SCIP_Bool modifiable;
1615  SCIP_Bool dynamic;
1616  SCIP_Bool removable;
1617  SCIP_Bool stickingatnode;
1618 
1619  setppc = hashmaphashdata->cons;
1620  assert(SCIPconsGetHdlr(setppc) == SCIPfindConshdlr(scip, "setppc"));
1621 
1622  initial = SCIPconsIsInitial(logicor) || SCIPconsIsInitial(setppc);
1623  separate = SCIPconsIsSeparated(logicor) || SCIPconsIsSeparated(setppc);
1624  enforce = SCIPconsIsEnforced(logicor) || SCIPconsIsEnforced(setppc);
1625  check = SCIPconsIsChecked(logicor) || SCIPconsIsChecked(setppc);
1626  propagate = SCIPconsIsPropagated(logicor) || SCIPconsIsPropagated(setppc);
1627  local = SCIPconsIsLocal(logicor) && SCIPconsIsLocal(setppc);
1628  modifiable = SCIPconsIsModifiable(logicor) && SCIPconsIsModifiable(setppc);
1629  dynamic = SCIPconsIsDynamic(logicor) && SCIPconsIsDynamic(setppc);
1630  removable = SCIPconsIsRemovable(logicor) && SCIPconsIsRemovable(setppc);
1631  stickingatnode = SCIPconsIsStickingAtNode(logicor) && SCIPconsIsStickingAtNode(setppc);
1632 
1633  /* check if logicor is redundant against a set-partitioning constraint */
1634  if( SCIPgetTypeSetppc(scip, setppc) == SCIP_SETPPCTYPE_PARTITIONING )
1635  {
1636  SCIP_CALL( SCIPsetConsInitial(scip, setppc, initial) );
1637  SCIP_CALL( SCIPsetConsSeparated(scip, setppc, separate) );
1638  SCIP_CALL( SCIPsetConsEnforced(scip, setppc, enforce) );
1639  SCIP_CALL( SCIPsetConsChecked(scip, setppc, check) );
1640  SCIP_CALL( SCIPsetConsPropagated(scip, setppc, propagate) );
1641  SCIP_CALL( SCIPsetConsLocal(scip, setppc, local) );
1642  SCIP_CALL( SCIPsetConsModifiable(scip, setppc, modifiable) );
1643  SCIP_CALL( SCIPsetConsDynamic(scip, setppc, dynamic) );
1644  SCIP_CALL( SCIPsetConsRemovable(scip, setppc, removable) );
1645  SCIP_CALL( SCIPsetConsStickingAtNode(scip, setppc, stickingatnode) );
1646 
1647  SCIPdebugMessage("Following logicor is redundant to the set-partitioning constraint.\n");
1648  SCIPdebugPrintCons(scip, logicor, NULL);
1649  SCIPdebugPrintCons(scip, setppc, NULL);
1650  }
1651  else
1652  {
1653  SCIP_CONS* newcons;
1654  char name[SCIP_MAXSTRLEN];
1655 
1656  assert(SCIPgetTypeSetppc(scip, setppc) == SCIP_SETPPCTYPE_PACKING);
1657 
1658  SCIPdebugMessage("Following logicor and set-packing constraints form a set-partitioning constraint.\n");
1659  SCIPdebugPrintCons(scip, logicor, NULL);
1660  SCIPdebugPrintCons(scip, setppc, NULL);
1661 
1662  /* create and add set-partitioning constraint */
1663  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "setpart_%d", presoldata->ngates);
1664  SCIP_CALL( SCIPcreateConsSetpart(scip, &newcons, name, nlogicorvars, activevarslogicor,
1665  initial, separate, enforce, check, propagate,
1666  local, modifiable, dynamic, removable, stickingatnode) );
1667 
1668  SCIP_CALL( SCIPaddCons(scip, newcons) );
1669  SCIPdebugMessage("-------------->\n");
1670  SCIPdebugPrintCons(scip, newcons, NULL);
1671 
1672  ++(*naddconss);
1673  ++(presoldata->ngates);
1674 
1675  /* delete redundant set-packing constraint */
1676  SCIP_CALL( SCIPdelCons(scip, setppc) );
1677  ++(*ndelconss);
1678 
1679  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
1680  }
1681 
1682  /* delete redundant logicor constraint */
1683  SCIP_CALL( SCIPdelCons(scip, logicor) );
1684  ++(*ndelconss);
1685  }
1686  }
1687  }
1688 
1689  /* need to clear/release parts of hashdata objects */
1690  for( d = nsetppchashdatas - 1; d >= 0; --d )
1691  {
1692  /* need to release captured constraint */
1693  SCIP_CALL( SCIPreleaseCons(scip, &(setppchashdatas[d]->cons)) );
1694  /* need to free copied memory */
1695  SCIPfreeBlockMemoryArray(scip, &(setppchashdatas[d]->vars), setppchashdatas[d]->nvars);
1696  }
1697 
1698  /* delete local hashtable */
1699  SCIPhashtableFree(&setppchashdatatable);
1700 
1701  /* free all temporary memory */
1702  SCIPfreeBuffer(scip, &hashdata);
1703  SCIPfreeBufferArray(scip, &activevarslogicor);
1704  SCIPfreeBufferArray(scip, &activevarssetppc);
1705  SCIPfreeBlockMemoryArray(scip, &setppchashdatas, nsetppcconss);
1706  SCIPfreeBlockMemoryArray(scip, &setppchashdatastore, nsetppcconss);
1707  }
1708 
1709  /* we do not have any useful set-packing or logicor constraint, or since last run did not get any new constraints, so abort */
1710  if( presoldata->nsetppchashdatas == 0 || (presoldata->firstchangedlogicor == presoldata->nusefullogicor && !presoldata->newsetppchashdatas) )
1711  {
1712  SCIPhashmapFree(&varmap);
1713  goto TERMINATE;
1714  }
1715 
1716  assert(presoldata->usefullogicor != NULL);
1717  assert(presoldata->nusefullogicor > 0);
1718  assert(presoldata->firstchangedlogicor >= 0);
1719  assert(presoldata->nsetppchashdatas > 0);
1720 
1721  /* search for gates */
1722  if( presoldata->nsetppchashdatas > 0 && !SCIPisStopped(scip) )
1723  {
1724  SCIP_CONS** gateconss;
1725  SCIP_VAR** activevars;
1726  SCIP_VAR** posresultants;
1727  int endloop;
1728 
1729  /* if we found new setppcs we want to check all logicors again */
1730  if( presoldata->newsetppchashdatas )
1731  endloop = 0;
1732  else
1733  endloop = MAX(presoldata->firstchangedlogicor, 0);
1734 
1735  assert(presoldata->maxnvarslogicor >= 3);
1736  SCIP_CALL( SCIPallocBufferArray(scip, &gateconss, presoldata->maxnvarslogicor) );
1737  SCIP_CALL( SCIPallocBufferArray(scip, &activevars, presoldata->maxnvarslogicor) );
1738  SCIP_CALL( SCIPallocBufferArray(scip, &posresultants, presoldata->maxnvarslogicor) );
1739  SCIP_CALL( SCIPallocBuffer(scip, &hashdata) );
1740 
1741  hashdata->nvars = 2;
1742  hashdata->cons = NULL;
1743 
1744  /* check all (new) logicors against all set-packing constraints, to extract and-constraints with two or more
1745  * operands or set-partitioning constraints three or more variables
1746  */
1747  for( c = presoldata->nusefullogicor - 1; c >= endloop && !SCIPisStopped(scip); --c )
1748  {
1749  assert(presoldata->usefullogicor[c] != NULL);
1750 
1751  /* logicor constraint has the form: x + y + z >= 1
1752  *
1753  * find set-packing constraints: (~x + ~y >= 1 and ~x + ~z >= 1) <=> (x + y <= 1 and x + z <= 1)
1754  *
1755  * - these three constraints are aquivalent to: x = ~y * ~z (x = AND(~y,~z))
1756  *
1757  * if an additional set-packing constraint exists: y + z <= 1
1758  *
1759  * - these four constraints are aquivalent to: x + y + z = 1
1760  */
1761  SCIP_CALL( extractGates(scip, presoldata, c, varmap, gateconss, activevars, posresultants, hashdata, ndelconss, naddconss) );
1762  }
1763  SCIPfreeBuffer(scip, &hashdata);
1764  SCIPfreeBufferArray(scip, &posresultants);
1765  SCIPfreeBufferArray(scip, &activevars);
1766  SCIPfreeBufferArray(scip, &gateconss);
1767  }
1768 
1769  SCIPhashmapFree(&varmap);
1770 
1771  TERMINATE:
1772  SCIPfreeBufferArray(scip, &setppcconss);
1773 
1774  /* remove old setppchashdatas objects */
1775  SCIP_CALL( cleanupHashDatas(scip, presoldata) );
1776 
1777  return SCIP_OKAY;
1778 }
1779 
1780 
1781 /*
1782  * presolver specific interface methods
1783  */
1784 
1785 /** creates the gateextraction presolver and includes it in SCIP */
1787  SCIP* scip /**< SCIP data structure */
1788  )
1789 {
1790  SCIP_PRESOLDATA* presoldata;
1791  SCIP_PRESOL* presol;
1792 
1793  /* alloc presolve data object */
1794  SCIP_CALL( SCIPallocMemory(scip, &presoldata) );
1795 
1796  /* initialize gateextraction presolver data */
1797  presoldataInit(presoldata);
1798 
1799  /* include presolver */
1801  PRESOL_TIMING, presolExecGateextraction, presoldata) );
1802 
1803  SCIP_CALL( SCIPsetPresolCopy(scip, presol, presolCopyGateextraction) );
1804  SCIP_CALL( SCIPsetPresolFree(scip, presol, presolFreeGateextraction) );
1805  SCIP_CALL( SCIPsetPresolExit(scip, presol, presolExitGateextraction) );
1806  SCIP_CALL( SCIPsetPresolInitpre(scip, presol, presolInitpreGateextraction) );
1807  SCIP_CALL( SCIPsetPresolExitpre(scip, presol, presolExitpreGateextraction) );
1808 
1809  /* add gateextraction presolver parameters */
1811  "presolving/" PRESOL_NAME "/onlysetpart",
1812  "should we only try to extract set-partitioning constraints and no and-constraints",
1813  &presoldata->onlysetpart, TRUE, DEFAULT_ONLYSETPART, NULL, NULL) );
1814 
1815  /* add gateextraction presolver parameters */
1817  "presolving/" PRESOL_NAME "/searchequations",
1818  "should we try to extract set-partitioning constraint out of one logicor and one corresponding set-packing constraint",
1819  &presoldata->searchequations, TRUE, DEFAULT_SEARCHEQUATIONS, NULL, NULL) );
1820 
1821  /* add gateextraction presolver parameters */
1822  SCIP_CALL( SCIPaddIntParam(scip,
1823  "presolving/" PRESOL_NAME "/sorting",
1824  "order logicor contraints to extract big-gates before smaller ones (-1), do not order them (0) or order them to extract smaller gates at first (1)",
1825  &presoldata->sorting, TRUE, DEFAULT_SORTING, -1, 1, NULL, NULL) );
1826 
1827  return SCIP_OKAY;
1828 }
void SCIPpresolSetData(SCIP_PRESOL *presol, SCIP_PRESOLDATA *presoldata)
Definition: presol.c:476
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:5878
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:20526
struct SCIP_PresolData SCIP_PRESOLDATA
Definition: type_presol.h:37
#define HASHTABLESIZE_FACTOR
static SCIP_DECL_PRESOLCOPY(presolCopyGateextraction)
static SCIP_RETCODE createPresoldata(SCIP *scip, SCIP_PRESOLDATA *presoldata, SCIP_CONS **setppcs, int nsetppcs, SCIP_CONS **logicors, int nlogicors)
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1567
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip.h:20573
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:8890
SCIP_RETCODE SCIPsetConsDynamic(SCIP *scip, SCIP_CONS *cons, SCIP_Bool dynamic)
Definition: scip.c:25225
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:11540
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip.c:1248
#define SCIP_MAXSTRLEN
Definition: def.h:201
#define NULL
Definition: lpi_spx.cpp:130
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17113
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4258
#define DEFAULT_ONLYSETPART
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1125
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:7849
SCIP_RETCODE SCIPsetPresolCopy(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLCOPY((*presolcopy)))
Definition: scip.c:6226
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:7681
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9086
SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
static SCIP_DECL_PRESOLEXEC(presolExecGateextraction)
const char * SCIPpresolGetName(SCIP_PRESOL *presol)
Definition: presol.c:553
int SCIPconshdlrGetNActiveConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4322
SCIP_RETCODE SCIPunfixParam(SCIP *scip, const char *name)
Definition: scip.c:3875
#define FALSE
Definition: def.h:56
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:2057
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:10743
static SCIP_DECL_PRESOLFREE(presolFreeGateextraction)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:8174
#define TRUE
Definition: def.h:55
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:7640
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
static SCIP_RETCODE extractGates(SCIP *scip, SCIP_PRESOLDATA *presoldata, int pos, SCIP_HASHMAP *varmap, SCIP_CONS **gateconss, SCIP_VAR **activevars, SCIP_VAR **posresultants, HASHDATA *hashdata, int *ndelconss, int *naddconss)
#define SCIP_CALL(x)
Definition: def.h:266
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** vars
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip.h:20556
#define SCIPdebugMessage
Definition: pub_message.h:77
void SCIPsortDownIntPtr(int *intarray, void **ptrarray, int len)
Constraint handler for "and" constraints, .
SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:24914
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:2116
SCIP_RETCODE SCIPsetConsPropagated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool propagate)
Definition: scip.c:25147
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:7839
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:7779
Constraint handler for the set partitioning / packing / covering constraints .
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip.c:24949
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
Definition: var.c:11206
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:7769
#define HASHSIZE_LOGICORCONS
SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
Definition: misc.c:1480
SCIP_PRESOLDATA * SCIPpresolGetData(SCIP_PRESOL *presol)
Definition: presol.c:466
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:3547
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16562
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:3573
void SCIPsortIntPtr(int *intarray, void **ptrarray, int len)
SCIP_RETCODE SCIPsetConsLocal(SCIP *scip, SCIP_CONS *cons, SCIP_Bool local)
Definition: scip.c:25174
SCIP_RETCODE SCIPsetConsStickingAtNode(SCIP *scip, SCIP_CONS *cons, SCIP_Bool stickingatnode)
Definition: scip.c:25275
SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
Definition: scip.c:17233
SCIP_RETCODE SCIPsetPresolExitpre(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLEXITPRE((*presolexitpre)))
Definition: scip.c:6306
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:20542
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:7879
int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
SCIP_CONS * cons
SCIP_RETCODE SCIPsetConsRemovable(SCIP *scip, SCIP_CONS *cons, SCIP_Bool removable)
Definition: scip.c:25250
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
int SCIPcalcHashtableSize(int minsize)
Definition: misc.c:1157
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9107
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip.c:17163
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip.c:41353
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:83
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:16598
static SCIP_DECL_HASHKEYVAL(hashdataKeyValCons)
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:2075
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip.h:20562
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3204
#define PRESOL_DESC
void SCIPsortPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
#define PRESOL_MAXROUNDS
void SCIPhashtableRemoveAll(SCIP_HASHTABLE *hashtable)
Definition: misc.c:1753
SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1719
static SCIP_DECL_PRESOLEXITPRE(presolExitpreGateextraction)
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip.c:16884
static SCIP_RETCODE correctPresoldata(SCIP *scip, SCIP_PRESOLDATA *presoldata, SCIP_CONS **setppcs, int nsetppcs, SCIP_CONS **logicors, int nlogicors)
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:16873
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:16850
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17123
#define HASHSIZE_SETPPCCONS
SCIP_RETCODE SCIPsetConsEnforced(SCIP *scip, SCIP_CONS *cons, SCIP_Bool enforce)
Definition: scip.c:25097
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:16740
#define SCIP_Bool
Definition: def.h:53
SCIP_RETCODE SCIPsetPresolFree(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLFREE((*presolfree)))
Definition: scip.c:6242
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:7859
SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
Definition: scip.c:3709
#define MAX(x, y)
Definition: tclique_def.h:75
#define PRESOL_NAME
static SCIP_RETCODE cleanupHashDatas(SCIP *scip, SCIP_PRESOLDATA *presoldata)
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:7869
static SCIP_DECL_PRESOLEXIT(presolExitGateextraction)
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:7739
SCIP_RETCODE SCIPsetPresolExit(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLEXIT((*presolexit)))
Definition: scip.c:6274
SCIP_RETCODE SCIPincludePresolGateextraction(SCIP *scip)
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
Definition: misc.c:1627
#define PRESOL_PRIORITY
static SCIP_RETCODE presoldataInitHashtables(SCIP *scip, SCIP_PRESOLDATA *presoldata)
static void presoldataInit(SCIP_PRESOLDATA *presoldata)
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:1510
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:11477
#define DEFAULT_SORTING
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20585
SCIP_RETCODE SCIPsetConsSeparated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool separate)
Definition: scip.c:25072
SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPcreateConsAnd(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *resvar, 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_and.c:4922
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip.h:20593
static SCIP_DECL_HASHKEYEQ(hashdataKeyEqCons)
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:7799
SCIP_RETCODE SCIPsetConsInitial(SCIP *scip, SCIP_CONS *cons, SCIP_Bool initial)
Definition: scip.c:25047
SCIP_RETCODE SCIPsetConsModifiable(SCIP *scip, SCIP_CONS *cons, SCIP_Bool modifiable)
Definition: scip.c:25200
SCIP_RETCODE SCIPsetConsChecked(SCIP *scip, SCIP_CONS *cons, SCIP_Bool check)
Definition: scip.c:25122
gateextraction presolver
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip.h:20568
#define DEFAULT_SEARCHEQUATIONS
#define SCIPfreeBuffer(scip, ptr)
Definition: scip.h:20595
#define SCIP_Longint
Definition: def.h:112
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1692
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition: scip.c:3938
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:20597
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9128
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:16730
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip.c:41422
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:2094
int SCIPgetNImplVars(SCIP *scip)
Definition: scip.c:10833
#define PRESOL_TIMING
SCIP_RETCODE SCIPsetPresolInitpre(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLINITPRE((*presolinitpre)))
Definition: scip.c:6290
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:7789
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:7819
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip.c:3740
static SCIP_DECL_PRESOLINITPRE(presolInitpreGateextraction)
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3149
SCIP_RETCODE SCIPincludePresolBasic(SCIP *scip, SCIP_PRESOL **presolptr, const char *name, const char *desc, int priority, int maxrounds, SCIP_PRESOLTIMING timing, SCIP_DECL_PRESOLEXEC((*presolexec)), SCIP_PRESOLDATA *presoldata)
Definition: scip.c:6191
#define SCIPallocBuffer(scip, ptr)
Definition: scip.h:20583