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