SCIP Doxygen Documentation
Loading...
Searching...
No Matches
iisfinder_greedy.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file iisfinder_greedy.c
26 * @brief greedy deletion and addition filter heuristic to compute (I)ISs
27 * @author Marc Pfetsch
28 * @author Mark Turner
29 * @author Paul Meinhold
30 */
31
34
35#define IISFINDER_NAME "greedy"
36#define IISFINDER_DESC "greedy deletion or addition constraint deletion"
37#define IISFINDER_PRIORITY 8000
38
39#define DEFAULT_TIMELIMPERITER 1e+20 /**< time limit of optimization process for each individual subproblem */
40#define DEFAULT_NODELIMPERITER -1L /**< node limit of optimization process for each individual subproblem */
41
42#define DEFAULT_ADDITIVE TRUE /**< should an additive constraint approach be used instead of deletion */
43#define DEFAULT_CONSERVATIVE TRUE /**< should an unsolved problem (by e.g. user interrupt, node limit, time limit) be considered feasible when deleting constraints */
44#define DEFAULT_DELAFTERADD TRUE /**< should the deletion routine be performed after the addition routine (in the case of additive) */
45#define DEFAULT_DYNAMICREORDERING TRUE /**< should satisfied constraints outside the batch of an intermediate solve be added during the additive method */
46
47#define DEFAULT_INITBATCHSIZE 16 /**< the initial batchsize for the first iteration, ignored if initrelbatchsize is positive */
48#define DEFAULT_INITRELBATCHSIZE 0.03125 /**< the initial batchsize relative to the original problem for the first iteration (0.0: use initbatchsize) */
49#define DEFAULT_MAXBATCHSIZE INT_MAX /**< the maximum batchsize per iteration */
50#define DEFAULT_MAXRELBATCHSIZE 0.5 /**< the maximum batchsize relative to the original problem per iteration */
51#define DEFAULT_BATCHINGFACTOR 2.0 /**< the factor with which the batchsize is multiplied in every update */
52#define DEFAULT_BATCHINGOFFSET 0.0 /**< the offset which is added to the multiplied batchsize in every update */
53#define DEFAULT_BATCHUPDATEINTERVAL 1 /**< the number of iterations to run with a constant batchsize before updating (1: always update) */
54
55
56/*
57 * Data structures
58 */
59
60/** IIS finder data */
61struct SCIP_IISfinderData
62{
63 SCIP_Real timelimperiter; /**< time limit of optimization process for each individual subproblem */
64 SCIP_Longint nodelimperiter; /**< node limit of optimization process for each individual subproblem */
65
66 SCIP_Bool additive; /**< should an additive constraint approach be used instead of deletion */
67 SCIP_Bool conservative; /**< should an unsolved problem (by e.g. user interrupt, node limit, time limit) be considered feasible when deleting constraints */
68 SCIP_Bool delafteradd; /**< should the deletion routine be performed after the addition routine (in the case of additive) */
69 SCIP_Bool dynamicreordering; /**< should satisfied constraints outside the batch of an intermediate solve be added during the additive method */
70
71 int initbatchsize; /**< the initial batchsize for the first iteration, ignored if initrelbatchsize is positive */
72 SCIP_Real initrelbatchsize; /**< the initial batchsize relative to the original problem for the first iteration (0.0: use initbatchsize) */
73 int maxbatchsize; /**< the maximum batchsize per iteration */
74 SCIP_Real maxrelbatchsize; /**< the maximum batchsize relative to the original problem per iteration */
75 SCIP_Real batchingfactor; /**< the factor with which the batchsize is multiplied in every update */
76 SCIP_Real batchingoffset; /**< the offset which is added to the multiplied batchsize in every update */
77 int batchupdateinterval; /**< the number of iterations to run with a constant batchsize before updating (1: always update) */
78};
79
80/*
81 * Local methods
82 */
83
84/* Set time and node limits on the subproblem */
85static
87 SCIP* scip, /**< SCIP instance to analyze */
88 SCIP_IIS* iis, /**< IIS data structure containing subscip */
89 SCIP_Real timelim, /**< total time limit allowed of the whole call */
90 SCIP_Real timelimperiter, /**< time limit per individual solve call */
91 SCIP_Longint nodelim, /**< node limit allowed for the whole call */
92 SCIP_Longint nodelimperiter /**< maximum number of nodes per individual solve call */
93 )
94{
95 SCIP_Real currtime;
96 SCIP_Real mintimelim;
97 SCIP_Longint globalnodelim;
98
99 /* Set the time limit for the solve call. Take into account the global time limit, the current time used, and the time lim on each individual call */
100 currtime = SCIPiisGetTime(iis);
101 mintimelim = MIN(timelim - currtime, timelimperiter);
102 mintimelim = MAX(mintimelim, 0);
103 SCIP_CALL( SCIPsetRealParam(scip, "limits/time", mintimelim) );
104
105 /* Set the node limit for the solve call. Take into account the global node limit, the current nodes processed, and the node lim on each individual call */
106 if( nodelim == -1 )
107 globalnodelim = -1;
108 else
109 {
110 globalnodelim = nodelim - SCIPiisGetNNodes(iis);
111 assert( globalnodelim >= 0 );
112 }
113 if( globalnodelim == -1 && nodelimperiter == -1 )
114 {
115 SCIP_CALL( SCIPsetLongintParam(scip, "limits/nodes", nodelim) );
116 }
117 else if( globalnodelim == -1 || nodelimperiter == -1 )
118 {
119 SCIP_CALL( SCIPsetLongintParam(scip, "limits/nodes", MAX(globalnodelim, nodelimperiter)) );
120 }
121 else
122 {
123 SCIP_CALL( SCIPsetLongintParam(scip, "limits/nodes", MIN(globalnodelim, nodelimperiter)) );
124 }
125 return SCIP_OKAY;
126}
127
128/* Revert bound changes made in the subproblem */
129static
131 SCIP* scip, /**< SCIP instance to analyze */
132 SCIP_VAR** vars, /**< the array of variables whose bounds are changed */
133 SCIP_Real* bounds, /**< the array of original bounds for the variables */
134 int* idxs, /**< the indices of the vars (in the vars array) that have been deleted */
135 int ndelbounds, /**< the number of bounds that will be deleted */
136 SCIP_Bool islb /**< are the bounds that are being deleted LBs? */
137 )
138{
139 int i;
140
141 /* Iterate over the affected variables and restore the bounds back to their original values */
142 for (i = 0; i < ndelbounds; ++i)
143 {
144 if( islb )
145 {
146 if( !SCIPisInfinity(scip, -bounds[i]) )
147 SCIP_CALL( SCIPchgVarLb(scip, vars[idxs[i]], bounds[i]) );
148 }
149 else
150 {
151 if( !SCIPisInfinity(scip, bounds[i]) )
152 SCIP_CALL( SCIPchgVarUb(scip, vars[idxs[i]], bounds[i]) );
153 }
154 }
155 return SCIP_OKAY;
156}
157
158/* Revert deleted constraint changes made in the subproblem */
159static
161 SCIP* scip, /**< SCIP instance to analyze */
162 SCIP_CONS** conss, /**< the array of constraints where some have been deleted */
163 int* idxs, /**< the indices of the cons (in the conss array) that have been deleted */
164 int ndelconss, /**< the number of constraints that have been deleted */
165 SCIP_Bool releaseonly /**< Should the constraints just be released instead of added back */
166 )
167{
168 int i;
169 SCIP_CONS* copycons;
170
171 for( i = 0; i < ndelconss; ++i )
172 {
173 if( releaseonly )
174 {
175 SCIP_CALL( SCIPreleaseCons(scip, &conss[idxs[i]]) );
176 }
177 else
178 {
179 SCIP_CALL( SCIPaddCons(scip, conss[idxs[i]]) );
180 copycons = conss[idxs[i]];
181 assert(SCIPconsGetNUses(copycons) > 1);
182 SCIP_CALL( SCIPreleaseCons(scip, &copycons) );
183 }
184 }
185
186 return SCIP_OKAY;
187}
188
189/* Update the batchsize accoring to the chosen rule */
190static
192 SCIP* scip, /**< SCIP data structure */
193 int initbatchsize, /**< the initial batchsize */
194 int maxbatchsize, /**< the maximum batchsize per iteration */
195 int iteration, /**< the current iteration */
196 SCIP_Bool resettoinit, /**< should the batchsize be reset to the initial batchsize? */
197 SCIP_Real batchingfactor, /**< the factor with which the batchsize is multiplied in every update */
198 SCIP_Real batchingoffset, /**< the offset which is added to the multiplied batchsize in every update */
199 int batchupdateinterval, /**< the number of iterations to run with a constant batchsize before updating (1: always update) */
200 int* batchsize /**< the batchsize to be updated */
201 )
202{
203 if( resettoinit )
204 *batchsize = initbatchsize;
205 else if( iteration % batchupdateinterval == 0 )
206 *batchsize = (int)ceil(batchingfactor * (*batchsize) + batchingoffset);
207
208 /* respect limits and maximum */
209 *batchsize = MIN(*batchsize, maxbatchsize);
210 *batchsize = MAX(*batchsize, 1);
211 SCIPdebugMsg(scip, "Updated batchsize to %d\n", *batchsize);
212
213 return SCIP_OKAY;
214}
215
216/** solve subproblem for deletionFilter */
217static
219 SCIP_IIS* iis, /**< IIS data structure containing subscip */
220 SCIP_CONS** conss, /**< The array of constraints (may be a superset of the current constraints) */
221 SCIP_VAR** vars, /**< the array of vars */
222 int* idxs, /**< the indices of the constraints / vars that will be deleted / bounds removed */
223 int ndels, /**< the number of bounds that will be deleted */
224 SCIP_Real timelim, /**< The global time limit on the IIS finder call */
225 SCIP_Real timelimperiter, /**< time limit per individual solve call */
226 SCIP_Longint nodelim, /**< The global node limit on the IIS finder call */
227 SCIP_Longint nodelimperiter, /**< maximum number of nodes per individual solve call */
228 SCIP_Bool conservative, /**< whether we treat a subproblem to be feasible, if it reaches some status that could result in infeasible, e.g. node limit */
229 SCIP_Bool delbounds, /**< whether bounds should be deleted instead of constraints */
230 SCIP_Bool islb, /**< are the bounds that are being deleted LBs? */
231 SCIP_Bool* deleted, /**< have the deleted bounds or constraints stayed deleted */
232 SCIP_Bool* stop, /**< pointer to store whether we have to stop */
233 SCIP_Bool* alldeletionssolved /**< pointer to store whether all the subscips solved */
234 )
235{
236 SCIP* scip;
237 SCIP_Real* bounds = NULL;
238 SCIP_RETCODE retcode;
239 SCIP_STATUS status;
240 SCIP_Bool chgmade = FALSE;
241 int i;
242
243 *deleted = FALSE;
244 *stop = FALSE;
245 scip = SCIPiisGetSubscip(iis);
246
247 /* remove bounds or constraints */
248 if( delbounds )
249 {
250 assert(vars != NULL);
251 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &bounds, ndels) );
252 for (i = 0; i < ndels; ++i)
253 {
254 if( islb )
255 {
256 bounds[i] = SCIPvarGetLbOriginal(vars[idxs[i]]);
257 if( !SCIPisInfinity(scip, -bounds[i]) )
258 {
260 chgmade = TRUE;
261 }
262 }
263 else
264 {
265 bounds[i] = SCIPvarGetUbOriginal(vars[idxs[i]]);
266 if( !SCIPisInfinity(scip, bounds[i]) )
267 {
269 chgmade = TRUE;
270 }
271 }
272 }
273 }
274 else
275 {
276 assert(conss != NULL);
277
278 if( ndels > 0 )
279 chgmade = TRUE;
280 for (i = 0; i < ndels; ++i)
281 {
282 assert( SCIPconsIsInProb(conss[idxs[i]]) );
283 SCIP_CALL( SCIPcaptureCons(scip, conss[idxs[i]]) );
284 SCIP_CALL( SCIPdelCons(scip, conss[idxs[i]]) );
285 }
286 }
287
288 if( !chgmade )
289 {
290 if( delbounds )
291 SCIPfreeBlockMemoryArray(scip, &bounds, ndels);
292 return SCIP_OKAY;
293 }
294
295 /* solve problem until first solution is found or infeasibility has been proven */
296 SCIP_CALL( setLimits(scip, iis, timelim, timelimperiter, nodelim, nodelimperiter) );
297 retcode = SCIPsolve(scip);
299
300 if( retcode != SCIP_OKAY )
301 {
303 SCIPdebugMsg(scip, "Error in sub-scip with deleted constraints / bounds. Re-adding them.\n");
304 if( delbounds )
305 {
306 SCIP_CALL( revertBndChgs(scip, vars, bounds, idxs, ndels, islb) );
307 SCIPfreeBlockMemoryArray(scip, &bounds, ndels);
308 }
309 else
310 {
311 SCIP_CALL( revertConssDeletions(scip, conss, idxs, ndels, FALSE) );
312 }
313 *alldeletionssolved = FALSE;
314 return SCIP_OKAY;
315 }
316
317 status = SCIPgetStatus(scip);
319
320 /* check status and handle accordingly */
321 switch ( status )
322 {
323 case SCIP_STATUS_USERINTERRUPT: /* if a user interrupt occurred, just stop */
325 SCIPdebugMsg(scip, "User interrupt. Stopping.\n");
326 if( delbounds )
327 {
328 SCIP_CALL( revertBndChgs(scip, vars, bounds, idxs, ndels, islb) );
329 }
330 else
331 {
332 SCIP_CALL( revertConssDeletions(scip, conss, idxs, ndels, !conservative) );
333 }
334 *stop = TRUE;
335 *alldeletionssolved = FALSE;
336 break;
337
338 case SCIP_STATUS_TIMELIMIT: /* if we reached some status that may have ended up in an infeasible problem */
347 *alldeletionssolved = FALSE;
348 SCIPdebugMsg(scip, "Some limit reached. Keeping bounds / constraints removed if non-conservative.\n");
349 if( !conservative )
350 {
352 *deleted = TRUE;
353 }
354 if( conservative && delbounds )
355 {
356 SCIP_CALL( revertBndChgs(scip, vars, bounds, idxs, ndels, islb) );
357 }
358 if( !delbounds )
359 {
360 SCIP_CALL( revertConssDeletions(scip, conss, idxs, ndels, !conservative) );
361 }
362 break;
363
364 case SCIP_STATUS_INFEASIBLE: /* if the problem is infeasible */
365 SCIPdebugMsg(scip, "Subproblem with bounds / constraints removed infeasible. Keep them removed.\n");
367 if( !delbounds )
368 {
369 SCIP_CALL( revertConssDeletions(scip, conss, idxs, ndels, TRUE) );
370 }
371 *deleted = TRUE;
372 break;
373
374 case SCIP_STATUS_BESTSOLLIMIT: /* we found a solution */
379 SCIPdebugMsg(scip, "Found solution to subproblem with bounds / constraints removed. Add them back.\n");
380 if( delbounds )
381 {
382 SCIP_CALL( revertBndChgs(scip, vars, bounds, idxs, ndels, islb) );
383 }
384 else
385 {
386 SCIP_CALL( revertConssDeletions(scip, conss, idxs, ndels, FALSE) );
387 }
388 break;
389
391 default:
392 *alldeletionssolved = FALSE;
393 SCIPerrorMessage("Unexpected return status %d in removed bounds subproblem. Exiting...\n", status);
394 if( delbounds )
395 SCIPfreeBlockMemoryArray(scip, &bounds, ndels);
396 return SCIP_ERROR;
397 }
398
399 if( delbounds )
400 SCIPfreeBlockMemoryArray(scip, &bounds, ndels);
401
402 return SCIP_OKAY;
403}
404
405/** solve subproblem for additionFilter */
406static
408 SCIP_IIS* iis, /**< IIS data structure containing subscip */
409 SCIP_Real timelim, /**< The global time limit on the IIS finder call */
410 SCIP_Real timelimperiter, /**< time limit per individual solve call */
411 SCIP_Longint nodelim, /**< The global node limit on the IIS finder call */
412 SCIP_Longint nodelimperiter, /**< maximum number of nodes per individual solve call */
413 SCIP_Bool* feasible, /**< pointer to store whether the problem is feasible */
414 SCIP_Bool* stop /**< pointer to store whether we have to stop */
415 )
416{
417 SCIP* scip;
418 SCIP_RETCODE retcode;
419 SCIP_STATUS status;
420
421 assert( stop != NULL );
422 scip = SCIPiisGetSubscip(iis);
423
424 *stop = FALSE;
425
426 /* solve problem until first solution is found or infeasibility has been proven */
427 SCIP_CALL( setLimits(scip, iis, timelim, timelimperiter, nodelim, nodelimperiter) );
428 retcode = SCIPsolve(scip);
429
430 if( retcode != SCIP_OKAY )
431 {
432 SCIPdebugMsg(scip, "Error in sub-scip with added constraints. Keep added constraints.\n");
433 return SCIP_ERROR;
434 }
435
437 status = SCIPgetStatus(scip);
438
439 /* check status */
440 switch ( status )
441 {
442 case SCIP_STATUS_USERINTERRUPT: /* if an user interrupt occurred, just stop */
444 SCIPdebugMsg(scip, "User interrupt. Stopping.\n");
445 *stop = TRUE;
446 break;
447
448 case SCIP_STATUS_NODELIMIT: /* if we reached some limit */
458 SCIPdebugMsg(scip, "Some limit reached. Added constraint batch failed to induce infeasibility. Continue adding.\n");
459 break;
460
461 case SCIP_STATUS_INFEASIBLE: /* if the problem is infeasible */
462 SCIPdebugMsg(scip, "Subproblem with added constraints infeasible. Final batch of constraints added.\n");
463 *feasible = FALSE;
464 break;
465
466 case SCIP_STATUS_BESTSOLLIMIT: /* we found a solution */
470 SCIPdebugMsg(scip, "Found solution of subproblem with added constraints. Keep adding constraint batches.\n");
471 *feasible = TRUE;
472 break;
473
475 default:
476 SCIPerrorMessage("Unexpected return status %d. Exiting ...\n", status);
477 return SCIP_ERROR;
478 }
479
480 return SCIP_OKAY;
481}
482
483
484/** Deletion filter to greedily remove constraints to obtain an (I)IS */
485static
487 SCIP_IIS* iis, /**< IIS data structure containing subscip */
488 SCIP_Real timelim, /**< The global time limit on the IIS finder call */
489 SCIP_Longint nodelim, /**< The global node limit on the IIS finder call */
490 SCIP_Bool removebounds, /**< Whether the algorithm should remove bounds as well as constraints */
491 SCIP_Bool silent, /**< should the run be performed silently without printing progress information */
492
493 SCIP_Real timelimperiter, /**< time limit per individual solve call */
494 SCIP_Longint nodelimperiter, /**< maximum number of nodes per individual solve call */
495 SCIP_Bool conservative, /**< should a node or time limit solve be counted as feasible when deleting constraints */
496
497 int initbatchsize, /**< the initial batchsize for the first iteration */
498 int maxbatchsize, /**< the maximum batchsize per iteration */
499 SCIP_Real batchingfactor, /**< the factor with which the batchsize is multiplied in every update */
500 SCIP_Real batchingoffset, /**< the offset which is added to the multiplied batchsize in every update */
501 int batchupdateinterval, /**< the number of iterations to run with a constant batchsize before updating (1: always update) */
502
503 SCIP_Bool* alldeletionssolved /**< pointer to store whether all the subscips solved */
504 )
505{
506 SCIP* scip;
507 SCIP_CONS** origconss;
508 SCIP_CONS** conss;
509 SCIP_VAR** origvars;
510 SCIP_VAR** vars;
511 SCIP_RANDNUMGEN* randnumgen;
512 int* order;
513 int* idxs;
514 SCIP_Bool stopiter;
515 SCIP_Bool deleted;
516 int nconss;
517 int nvars;
518 int batchindex;
519 int batchsize = initbatchsize;
520 int iteration;
521 int i;
522 int k;
523
524 /* get current subscip */
525 scip = SCIPiisGetSubscip(iis);
526 assert( scip != NULL );
528
529 /* get random generator */
530 randnumgen = SCIPiisGetRandnumgen(iis);
531 assert( randnumgen != NULL );
532
533 /* get batch size */
534 assert( initbatchsize >= 1 );
535 assert( maxbatchsize >= 1 );
536 initbatchsize = MIN(initbatchsize, maxbatchsize);
537
538 /* allocate indices array */
539 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &idxs, maxbatchsize) );
540
541 /* get constraint information */
542 nconss = SCIPgetNOrigConss(scip);
543 origconss = SCIPgetOrigConss(scip);
544 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &conss, origconss, nconss) );
545
546 /* reset problem */
549
550 /* prepare random order for constraints */
551 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &order, nconss) );
552 for (i = 0; i < nconss; ++i)
553 order[i] = i;
554 SCIPrandomPermuteIntArray(randnumgen, order, 0, nconss);
555
556 /* Loop through all batches of constraints in random order */
557 i = 0;
558 iteration = 0;
559 deleted = FALSE;
560 stopiter = FALSE;
561 while( i < nconss )
562 {
563 /* update batchsize */
564 SCIP_CALL( updateBatchsize(scip, initbatchsize, maxbatchsize, iteration, !deleted, batchingfactor, batchingoffset, batchupdateinterval, &batchsize) );
565
566 k = 0;
567 batchindex = i;
568 while( i < nconss && k < batchsize )
569 {
570 assert( conss[order[i]] != NULL );
571 if( SCIPconsGetNUses(conss[order[i]]) == 1 )
572 {
573 idxs[k] = order[i];
574 k++;
575 }
576 i++;
577 }
578
579 /* treat subproblem */
580 SCIP_CALL( deletionSubproblem(iis, conss, NULL, idxs, k, timelim, timelimperiter, nodelim, nodelimperiter,
581 conservative, FALSE, FALSE, &deleted, &stopiter, alldeletionssolved) );
582 if( !silent && deleted )
584
585 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) || stopiter )
586 break;
587
588 /* reset i to beginning of current batch if batch has not been deleted and k was large */
589 if( !deleted && k > initbatchsize )
590 i = batchindex;
591
592 ++iteration;
593
595 }
596
597 SCIPfreeBlockMemoryArray(scip, &order, nconss);
598 SCIPfreeBlockMemoryArray(scip, &conss, nconss);
599 SCIPfreeBlockMemoryArray(scip, &idxs, maxbatchsize);
600
601 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) || stopiter )
602 return SCIP_OKAY;
603
604 /* Repeat the above procedure but for bounds instead of constraints */
605 if( removebounds )
606 {
607 /* allocate indices array */
608 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &idxs, maxbatchsize) );
609
611 origvars = SCIPgetOrigVars(scip);
613
615 for (i = 0; i < nvars; ++i)
616 order[i] = i;
617 SCIPrandomPermuteIntArray(randnumgen, order, 0, nvars);
618
619 i = 0;
620 iteration = 0;
621 deleted = FALSE;
622 while( i < nvars )
623 {
624 /* update batchsize */
625 SCIP_CALL( updateBatchsize(scip, initbatchsize, maxbatchsize, iteration, !deleted, batchingfactor, batchingoffset, batchupdateinterval, &batchsize) );
626
627 k = 0;
628 batchindex = i;
629 /* Do not delete bounds of binary variables or bother with calculations of free variables */
630 while( i < nvars && k < batchsize )
631 {
633 {
634 idxs[k] = order[i];
635 k++;
636 }
637 i++;
638 }
639 if( k == 0 )
640 break;
641
642 /* treat subproblem with LB deletions */
643 SCIP_CALL( deletionSubproblem(iis, NULL, vars, idxs, k, timelim, timelimperiter, nodelim, nodelimperiter,
644 conservative, TRUE, TRUE, &deleted, &stopiter, alldeletionssolved) );
645 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) || stopiter )
646 break;
647 if( !silent && deleted )
649
650 /* treat subproblem with UB deletions */
651 SCIP_CALL( deletionSubproblem(iis, NULL, vars, idxs, k, timelim, timelimperiter, nodelim, nodelimperiter,
652 conservative, TRUE, FALSE, &deleted, &stopiter, alldeletionssolved) );
653
654 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) || stopiter )
655 break;
656 if( !silent && deleted )
658
659 /* reset i to beginning of current batch if batch has not been deleted and k was large */
660 if( !deleted && k > initbatchsize )
661 i = batchindex;
662
663 ++iteration;
664 }
665
668 SCIPfreeBlockMemoryArray(scip, &idxs, maxbatchsize);
669 }
670
671 return SCIP_OKAY;
672}
673
674/** Addition filter to greedily add constraints to obtain an (I)IS */
675static
677 SCIP_IIS* iis, /**< IIS data structure containing subscip */
678 SCIP_Real timelim, /**< The global time limit on the IIS finder call */
679 SCIP_Longint nodelim, /**< The global node limit on the IIS finder call */
680 SCIP_Bool silent, /**< should the run be performed silently without printing progress information */
681
682 SCIP_Real timelimperiter, /**< time limit per individual solve call */
683 SCIP_Longint nodelimperiter, /**< maximum number of nodes per individual solve call */
684 SCIP_Bool dynamicreordering, /**< should satisfied constraints outside the batch of an intermediate solve be added during the additive method */
685
686 int initbatchsize, /**< the initial batchsize for the first iteration */
687 int maxbatchsize, /**< the maximum batchsize per iteration */
688 SCIP_Real batchingfactor, /**< the factor with which the batchsize is multiplied in every update */
689 SCIP_Real batchingoffset, /**< the offset which is added to the multiplied batchsize in every update */
690 int batchupdateinterval /**< the number of iterations to run with a constant batchsize before updating (1: always update) */
691 )
692{
693 SCIP* scip;
694 SCIP_CONS** origconss;
695 SCIP_CONS** conss;
696 SCIP_RANDNUMGEN* randnumgen;
697 SCIP_SOL* sol;
698 SCIP_SOL* copysol;
699 SCIP_Bool* inIS;
700 int* order;
701 SCIP_Bool feasible;
702 SCIP_Bool stopiter;
703 SCIP_RETCODE retcode;
705 int nconss;
706 int batchsize;
707 int iteration;
708 int i;
709 int j;
710 int k;
711
712 /* get current subscip */
713 scip = SCIPiisGetSubscip(iis);
714 assert( scip != NULL );
716
717 /* get random generator */
718 randnumgen = SCIPiisGetRandnumgen(iis);
719 assert( randnumgen != NULL );
720
721 /* get batch size */
722 assert( initbatchsize >= 1 );
723 assert( maxbatchsize >= 1 );
724 initbatchsize = MIN(initbatchsize, maxbatchsize);
725 batchsize = initbatchsize;
726
727 /* get constraint information */
728 nconss = SCIPgetNOrigConss(scip);
729 origconss = SCIPgetOrigConss(scip);
730 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &conss, origconss, nconss) );
731
732 /* Initialise information for whether a constraint is in the final infeasible system */
733 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &inIS, nconss) );
734
735 /* First capture and then delete all constraints */
737 for( i = 0; i < nconss; ++i )
738 {
739 assert( SCIPconsIsInProb(conss[i]) );
740 if( SCIPconsGetNUses(conss[i]) > 1 )
741 {
742 inIS[i] = TRUE;
743 }
744 else
745 {
746 SCIP_CALL( SCIPcaptureCons(scip, conss[i]) );
747 SCIP_CALL( SCIPdelCons(scip, conss[i]) );
748 inIS[i] = FALSE;
749 }
750 }
752
753 /* Prepare random order in which the constraints will be added back */
754 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &order, nconss) );
755 for (i = 0; i < nconss; ++i)
756 order[i] = i;
757 SCIPrandomPermuteIntArray(randnumgen, order, 0, nconss);
758
759 /* Continue to add constraints until an infeasible status is reached */
760 i = 0;
761 iteration = 0;
762 feasible = TRUE;
763 stopiter = FALSE;
764 while( i < nconss )
765 {
766 /* Add the next batch of constraints */
767 k = 0;
768 while( i < nconss && k < batchsize )
769 {
770 if( !inIS[order[i]] )
771 {
772 SCIP_CALL( SCIPaddCons(scip, conss[order[i]]) );
773 SCIP_CALL( SCIPreleaseCons(scip, &conss[order[i]]) );
774 inIS[order[i]] = TRUE;
775 ++k;
776 }
777 i++;
778 }
779
780 /* We have the full infeasible problem again */
781 if( i == nconss )
782 {
783 feasible = FALSE;
784 break;
785 }
786
787 /* Solve the reduced problem */
788 retcode = additionSubproblem(iis, timelim, timelimperiter, nodelim, nodelimperiter, &feasible, &stopiter);
789 if( !feasible || stopiter || timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) )
790 {
792 break;
793 }
794
795 if( !silent )
797
798 if( dynamicreordering && retcode == SCIP_OKAY )
799 {
800 /* free transform and copy solution if there is one */
801 copysol = NULL;
803 if( sol != NULL )
804 {
806 SCIP_CALL( SCIPunlinkSol(scip, copysol) );
807 }
810
811 /* Add any other constraints that are also feasible for the current solution */
812 if( copysol != NULL )
813 {
814 k = 0;
815 for( j = i; j < nconss; ++j )
816 {
817 /* Don't dynamically add indicator constraints */
818 if( !inIS[order[j]]
819 && strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[order[j]])), "indicator") != 0 )
820 {
821 SCIP_CALL( SCIPcheckCons(scip, conss[order[j]], copysol, FALSE, FALSE, FALSE, &result) );
822 if( result == SCIP_FEASIBLE )
823 {
824 SCIP_CALL( SCIPaddCons(scip, conss[order[j]]) );
825 SCIP_CALL( SCIPreleaseCons(scip, &conss[order[j]]) );
826 inIS[order[j]] = TRUE;
827 k++;
828 }
829 }
830 }
831 SCIPdebugMsg(scip, "Added %d constraints by reordering dynamically.\n", k);
832 SCIP_CALL( SCIPfreeSol(scip, &copysol) );
833 }
834 }
835 else
836 {
839 }
840
841 ++iteration;
842
843 /* update batchsize */
844 SCIP_CALL( updateBatchsize(scip, initbatchsize, maxbatchsize, iteration, FALSE, batchingfactor, batchingoffset, batchupdateinterval, &batchsize) );
845 }
846
847 /* If problem is feasible due to limit or interrupt, add the deleted constraints of the full infeasible problem */
848 if( feasible )
849 {
850 assert(stopiter || SCIPiisGetTime(iis) >= timelim || (nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim));
851 SCIPdebugMsg(scip, "Hit limit or interrupt. Restore full infeasible problem.\n");
852 for( i = 0; i < nconss; ++i )
853 {
854 if( !inIS[order[i]] )
855 {
856 SCIP_CALL( SCIPaddCons(scip, conss[order[i]]) );
857 SCIP_CALL( SCIPreleaseCons(scip, &conss[order[i]]) );
858 inIS[order[i]] = TRUE;
859 }
860 }
861 }
862 else
863 {
864 /* Release any cons not in the IS */
865 for( i = 0; i < nconss; ++i )
866 {
867 if( !inIS[order[i]] )
868 {
869 SCIP_CALL( SCIPreleaseCons(scip, &conss[order[i]]) );
870 }
871 }
872 }
873
874 SCIPfreeBlockMemoryArray(scip, &order, nconss);
875 SCIPfreeBlockMemoryArray(scip, &inIS, nconss);
876 SCIPfreeBlockMemoryArray(scip, &conss, nconss);
878
879 if( !silent )
881
882 return SCIP_OKAY;
883}
884
885/** perform a greedy addition or deletion algorithm to obtain an infeasible subsystem (IS).
886 *
887 * This is the generation method for the greedy IIS finder rule.
888 * Depending on the parameter choices, constraints are either greedily added from an empty problem,
889 * or deleted from a complete problem. In the case of constraints being added, this is done until the problem
890 * becomes infeasible, after which one can then begin deleting constraints. In the case of deleting constraints,
891 * this is done until no more constraints (or batches of constraints) can be deleted without making
892 * the problem feasible.
893 */
894static
896 SCIP_IIS* iis, /**< IIS data structure */
897 SCIP_IISFINDERDATA* iisfinderdata, /**< IIS finder data */
898 SCIP_RESULT* result /**< pointer to store the result of the IIS finder run. SCIP_DIDNOTFIND if the algorithm failed, otherwise SCIP_SUCCESS. */
899 )
900{
902 SCIP_Real timelim;
903 SCIP_Longint nodelim;
904 SCIP_Bool removebounds;
905 SCIP_Bool silent;
906 SCIP_Bool alldeletionssolved = TRUE;
907 int nvars;
908 int nconss;
909 int maxbatchsize;
910 int initbatchsize;
911
912 assert( scip != NULL );
913 assert( iisfinderdata != NULL );
914 assert( result != NULL );
915
916 SCIP_CALL( SCIPgetRealParam(scip, "iis/time", &timelim) );
917 SCIP_CALL( SCIPgetLongintParam(scip, "iis/nodes", &nodelim) );
918 SCIP_CALL( SCIPgetBoolParam(scip, "iis/removebounds", &removebounds) );
919 SCIP_CALL( SCIPgetBoolParam(scip, "iis/silent", &silent) );
920
922 nconss = SCIPgetNOrigConss(scip);
923 maxbatchsize = MAX(nvars, nconss);
924 initbatchsize = iisfinderdata->initrelbatchsize > 0.0
925 ? (int)ceil(iisfinderdata->initrelbatchsize * maxbatchsize) : MIN(iisfinderdata->initbatchsize, maxbatchsize);
926 maxbatchsize = (int)ceil(iisfinderdata->maxrelbatchsize * maxbatchsize);
927 maxbatchsize = MIN(iisfinderdata->maxbatchsize, maxbatchsize);
928 initbatchsize = MAX(initbatchsize, 1);
929 maxbatchsize = MAX(maxbatchsize, 1);
930
932
933 if( iisfinderdata->additive )
934 {
935 if( !silent )
936 {
937 SCIPdebugMsg(scip, "----- STARTING GREEDY ADDITION ALGORITHM -----\n");
938 }
939 SCIP_CALL( additionFilterBatch(iis, timelim, nodelim, silent, iisfinderdata->timelimperiter,
940 iisfinderdata->nodelimperiter, iisfinderdata->dynamicreordering, initbatchsize, maxbatchsize,
941 iisfinderdata->batchingfactor, iisfinderdata->batchingoffset, iisfinderdata->batchupdateinterval) );
943 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) )
944 return SCIP_OKAY;
945 }
946 else
947 {
948 if( !silent )
949 {
950 SCIPdebugMsg(scip, "----- STARTING GREEDY DELETION ALGORITHM -----\n");
951 }
952 SCIP_CALL( deletionFilterBatch(iis, timelim, nodelim, removebounds, silent, iisfinderdata->timelimperiter,
953 iisfinderdata->nodelimperiter, iisfinderdata->conservative, initbatchsize, maxbatchsize,
954 iisfinderdata->batchingfactor, iisfinderdata->batchingoffset, iisfinderdata->batchupdateinterval,
955 &alldeletionssolved) );
956 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) )
957 return SCIP_OKAY;
958 if( alldeletionssolved && initbatchsize == 1 )
960 }
961
962 if( iisfinderdata->delafteradd && iisfinderdata->additive )
963 {
964 if( !silent )
965 {
966 SCIPdebugMsg(scip, "----- STARTING GREEDY DELETION ALGORITHM FOLLOWING COMPLETED ADDITION ALGORITHM -----\n");
967 }
968 SCIP_CALL( deletionFilterBatch(iis, timelim, nodelim, removebounds, silent, iisfinderdata->timelimperiter,
969 iisfinderdata->nodelimperiter, iisfinderdata->conservative, initbatchsize, maxbatchsize,
970 iisfinderdata->batchingfactor, iisfinderdata->batchingoffset, iisfinderdata->batchupdateinterval,
971 &alldeletionssolved) );
972 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) )
973 return SCIP_OKAY;
974 if( alldeletionssolved && initbatchsize == 1 )
976 }
977
978 return SCIP_OKAY;
979}
980
981
982/*
983 * Callback methods of IIS finder
984 */
985
986
987/** copy method for IIS finder plugin (called when SCIP copies plugins) */
988static
989SCIP_DECL_IISFINDERCOPY(iisfinderCopyGreedy)
990{ /*lint --e{715}*/
991 assert(scip != NULL);
992 assert(iisfinder != NULL);
993
995
996 /* call inclusion method of IIS finder */
998
999 return SCIP_OKAY;
1000}
1001
1002/** destructor of IIS finder to free user data (called when SCIP is exiting) */
1003/**! [SnippetIISfinderFreeGreedy] */
1004static
1005SCIP_DECL_IISFINDERFREE(iisfinderFreeGreedy)
1006{ /*lint --e{715}*/
1007 SCIP_IISFINDERDATA* iisfinderdata;
1008
1009 iisfinderdata = SCIPiisfinderGetData(iisfinder);
1010
1011 SCIPfreeBlockMemory(scip, &iisfinderdata);
1012
1013 SCIPiisfinderSetData(iisfinder, NULL);
1014
1015 return SCIP_OKAY;
1016}
1017/**! [SnippetIISfinderFreeGreedy] */
1018
1019/** IIS finder generation method of IIS */
1020static
1021SCIP_DECL_IISFINDEREXEC(iisfinderExecGreedy)
1022{ /*lint --e{715}*/
1023 SCIP_IISFINDERDATA* iisfinderdata;
1024
1025 assert(iisfinder != NULL);
1026 assert(result != NULL);
1027
1029
1030 iisfinderdata = SCIPiisfinderGetData(iisfinder);
1031 assert(iisfinderdata != NULL);
1032
1033 SCIP_CALL( execIISfinderGreedy(iis, iisfinderdata, result) );
1034
1035 return SCIP_OKAY;
1036}
1037
1038
1039/*
1040 * IIS finder specific interface methods
1041 */
1042
1043/** creates the greedy IIS finder and includes it in SCIP */
1045 SCIP* scip /**< SCIP data structure */
1046 )
1047{
1048 SCIP_IISFINDERDATA* iisfinderdata;
1049 SCIP_IISFINDER* iisfinder;
1050
1051 /* create greedy IIS finder data */
1052 SCIP_CALL( SCIPallocBlockMemory(scip, &iisfinderdata) );
1053 BMSclearMemory(iisfinderdata);
1054
1056 iisfinderExecGreedy, iisfinderdata) );
1057
1058 assert(iisfinder != NULL);
1059
1060 /* set non fundamental callbacks via setter functions */
1061 SCIP_CALL( SCIPsetIISfinderCopy(scip, iisfinder, iisfinderCopyGreedy) );
1062 SCIP_CALL( SCIPsetIISfinderFree(scip, iisfinder, iisfinderFreeGreedy) );
1063
1064 /* add greedy IIS finder parameters */
1066 "iis/" IISFINDER_NAME "/timelimperiter",
1067 "time limit of optimization process for each individual subproblem",
1068 &iisfinderdata->timelimperiter, FALSE, DEFAULT_TIMELIMPERITER, 0.0, SCIP_INVALID/10.0, NULL, NULL) );
1069
1071 "iis/" IISFINDER_NAME "/nodelimperiter",
1072 "node limit of optimization process for each individual subproblem",
1073 &iisfinderdata->nodelimperiter, FALSE, DEFAULT_NODELIMPERITER, -1L, SCIP_LONGINT_MAX, NULL, NULL) );
1074
1076 "iis/" IISFINDER_NAME "/additive",
1077 "should an additive constraint approach be used instead of deletion",
1078 &iisfinderdata->additive, FALSE, DEFAULT_ADDITIVE, NULL, NULL) );
1079
1081 "iis/" IISFINDER_NAME "/conservative",
1082 "should an unsolved problem (by e.g. user interrupt, node limit, time limit) be considered feasible when deleting constraints",
1083 &iisfinderdata->conservative, TRUE, DEFAULT_CONSERVATIVE, NULL, NULL) );
1084
1086 "iis/" IISFINDER_NAME "/delafteradd",
1087 "should the deletion routine be performed after the addition routine (in the case of additive)",
1088 &iisfinderdata->delafteradd, TRUE, DEFAULT_DELAFTERADD, NULL, NULL) );
1089
1091 "iis/" IISFINDER_NAME "/dynamicreordering",
1092 "should satisfied constraints outside the batch of an intermediate solve be added during the additive method",
1093 &iisfinderdata->dynamicreordering, TRUE, DEFAULT_DYNAMICREORDERING, NULL, NULL) );
1094
1096 "iis/" IISFINDER_NAME "/initbatchsize",
1097 "the initial batchsize for the first iteration, ignored if initrelbatchsize is positive",
1098 &iisfinderdata->initbatchsize, FALSE, DEFAULT_INITBATCHSIZE, 1, INT_MAX, NULL, NULL) );
1099
1101 "iis/" IISFINDER_NAME "/initrelbatchsize",
1102 "the initial batchsize relative to the original problem for the first iteration (0.0: use initbatchsize)",
1103 &iisfinderdata->initrelbatchsize, FALSE, DEFAULT_INITRELBATCHSIZE, 0.0, 1.0, NULL, NULL) );
1104
1106 "iis/" IISFINDER_NAME "/maxbatchsize",
1107 "the maximum batchsize per iteration",
1108 &iisfinderdata->maxbatchsize, TRUE, DEFAULT_MAXBATCHSIZE, 1, INT_MAX, NULL, NULL) );
1109
1111 "iis/" IISFINDER_NAME "/maxrelbatchsize",
1112 "the maximum batchsize relative to the original problem per iteration",
1113 &iisfinderdata->maxrelbatchsize, TRUE, DEFAULT_MAXRELBATCHSIZE, 0.0, 1.0, NULL, NULL) );
1114
1116 "iis/" IISFINDER_NAME "/batchingfactor",
1117 "the factor with which the batchsize is multiplied in every update",
1118 &iisfinderdata->batchingfactor, TRUE, DEFAULT_BATCHINGFACTOR, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1119
1121 "iis/" IISFINDER_NAME "/batchingoffset",
1122 "the offset which is added to the multiplied batchsize in every update",
1123 &iisfinderdata->batchingoffset, TRUE, DEFAULT_BATCHINGOFFSET, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1124
1126 "iis/" IISFINDER_NAME "/batchupdateinterval",
1127 "the number of iterations to run with a constant batchsize before updating (1: always update)",
1128 &iisfinderdata->batchupdateinterval, TRUE, DEFAULT_BATCHUPDATEINTERVAL, 1, INT_MAX, NULL, NULL) );
1129
1130 return SCIP_OKAY;
1131}
1132
1133/** perform the greedy deletion algorithm with singleton batches to obtain an irreducible infeasible subsystem (IIS) */
1135 SCIP_IIS* iis /**< IIS data structure */
1136 )
1137{
1138 SCIP* scip;
1139 SCIP_HASHMAP* invconssmap = NULL;
1140 SCIP_Real timelim;
1141 SCIP_Longint nodelim;
1142 SCIP_Bool isstandalone;
1143 SCIP_Bool removebounds;
1144 SCIP_Bool silent;
1145 SCIP_Bool alldeletionssolved = TRUE;
1146 int nvars;
1147 int nconss;
1148
1149 if( !SCIPiisIsSubscipInfeasible(iis) )
1150 {
1151 SCIPerrorMessage("infeasible problem required\n");
1152 return SCIP_INVALIDDATA;
1153 }
1154
1155 scip = SCIPiisGetSubscip(iis);
1156 assert( scip != NULL );
1157
1158 /* if this function is called by a user outside of iisfinder.c::SCIPiisGenerate(), build inverse constraints hashmap */
1159 isstandalone = !SCIPhashmapIsEmpty(iis->conssmap);
1160 if( isstandalone )
1161 {
1162 SCIP_HASHMAPENTRY* entry;
1163 SCIP_CONS* imagecons;
1164 int nentries;
1165 int c;
1166
1168 nentries = SCIPhashmapGetNEntries(iis->conssmap);
1169 for( c = 0; c < nentries; ++c )
1170 {
1171 entry = SCIPhashmapGetEntry(iis->conssmap, c);
1172 if( entry == NULL )
1173 continue;
1174
1175 imagecons = SCIPhashmapEntryGetImage(entry);
1176 assert(imagecons != NULL);
1177
1178 SCIP_CALL( SCIPhashmapInsert(invconssmap, imagecons, SCIPhashmapEntryGetOrigin(entry)) );
1179 }
1181 }
1182
1183 /* get relevant parameters */
1184 SCIP_CALL( SCIPgetRealParam(scip, "iis/time", &timelim) );
1185 SCIP_CALL( SCIPgetLongintParam(scip, "iis/nodes", &nodelim) );
1186 SCIP_CALL( SCIPgetBoolParam(scip, "iis/removebounds", &removebounds) );
1187 SCIP_CALL( SCIPgetBoolParam(scip, "iis/silent", &silent) );
1188
1190 nconss = SCIPgetNOrigConss(scip);
1191
1192 /* make irreducible by running the deletion filter with singleton batches */
1193 SCIP_CALL( deletionFilterBatch(iis, timelim, nodelim, removebounds, silent,
1196 if( alldeletionssolved && SCIPiisGetTime(iis) < timelim && ( nodelim == -1 || SCIPiisGetNNodes(iis) < nodelim ) )
1198
1199 /* recreate main constraints hashmap */
1200 if( isstandalone )
1201 {
1202 SCIP_CONS** conss;
1203 SCIP_CONS* imagecons;
1204 int c;
1205
1206 assert(invconssmap != NULL);
1207 nconss = SCIPgetNOrigConss(scip);
1208 conss = SCIPgetOrigConss(scip);
1209 for( c = 0; c < nconss; ++c )
1210 {
1211 imagecons = SCIPhashmapGetImage(invconssmap, conss[c]);
1212 assert(imagecons != NULL);
1213 SCIP_CALL( SCIPhashmapInsert(iis->conssmap, imagecons, conss[c]) );
1214 }
1215 SCIPhashmapFree(&invconssmap);
1216 }
1217
1218 return SCIP_OKAY;
1219}
#define NULL
Definition def.h:257
#define SCIP_Longint
Definition def.h:150
#define SCIP_REAL_MAX
Definition def.h:167
#define SCIP_INVALID
Definition def.h:187
#define SCIP_Bool
Definition def.h:100
#define MIN(x, y)
Definition def.h:233
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define MAX(x, y)
Definition def.h:229
#define SCIP_REAL_MIN
Definition def.h:168
#define SCIP_LONGINT_MAX
Definition def.h:151
#define SCIP_CALL(x)
Definition def.h:364
SCIP_STATUS SCIPgetStatus(SCIP *scip)
SCIP_STAGE SCIPgetStage(SCIP *scip)
int SCIPgetNOrigConss(SCIP *scip)
Definition scip_prob.c:3712
SCIP_VAR ** SCIPgetOrigVars(SCIP *scip)
Definition scip_prob.c:2811
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 SCIPgetNOrigVars(SCIP *scip)
Definition scip_prob.c:2838
SCIP_CONS ** SCIPgetOrigConss(SCIP *scip)
Definition scip_prob.c:3739
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition misc.c:3095
void * SCIPhashmapEntryGetImage(SCIP_HASHMAPENTRY *entry)
Definition misc.c:3613
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
int SCIPhashmapGetNElements(SCIP_HASHMAP *hashmap)
Definition misc.c:3576
int SCIPhashmapGetNEntries(SCIP_HASHMAP *hashmap)
Definition misc.c:3584
SCIP_HASHMAPENTRY * SCIPhashmapGetEntry(SCIP_HASHMAP *hashmap, int entryidx)
Definition misc.c:3592
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition misc.c:3061
void * SCIPhashmapEntryGetOrigin(SCIP_HASHMAPENTRY *entry)
Definition misc.c:3603
SCIP_Bool SCIPhashmapIsEmpty(SCIP_HASHMAP *hashmap)
Definition misc.c:3566
SCIP_RETCODE SCIPhashmapRemoveAll(SCIP_HASHMAP *hashmap)
Definition misc.c:3676
SCIP_RETCODE SCIPiisGreedyMakeIrreducible(SCIP_IIS *iis)
SCIP_RETCODE SCIPincludeIISfinderGreedy(SCIP *scip)
#define SCIPdebugMsg
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition scip_param.c:250
SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:111
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 SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition scip_param.c:545
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:139
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition scip_param.c:307
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 SCIPgetLongintParam(SCIP *scip, const char *name, SCIP_Longint *value)
Definition scip_param.c:288
SCIP_RETCODE SCIPsetRealParam(SCIP *scip, const char *name, SCIP_Real value)
Definition scip_param.c:603
void SCIPrandomPermuteIntArray(SCIP_RANDNUMGEN *randnumgen, int *array, int begin, int end)
Definition misc.c:10264
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4320
SCIP_RETCODE SCIPcheckCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_RESULT *result)
Definition scip_cons.c:2135
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition cons.c:8413
SCIP_Bool SCIPconsIsInProb(SCIP_CONS *cons)
Definition cons.c:8682
int SCIPconsGetNUses(SCIP_CONS *cons)
Definition cons.c:8433
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1173
SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_cons.c:1138
SCIP_RETCODE SCIPsetIISfinderFree(SCIP *scip, SCIP_IISFINDER *iisfinder,)
const char * SCIPiisfinderGetName(SCIP_IISFINDER *iisfinder)
Definition iisfinder.c:315
SCIP_IISFINDERDATA * SCIPiisfinderGetData(SCIP_IISFINDER *iisfinder)
Definition iisfinder.c:706
void SCIPiisfinderSetData(SCIP_IISFINDER *iisfinder, SCIP_IISFINDERDATA *iisfinderdata)
Definition iisfinder.c:716
void SCIPiisfinderInfoMessage(SCIP_IIS *iis, SCIP_Bool printheaders)
Definition iisfinder.c:794
SCIP_RETCODE SCIPsetIISfinderCopy(SCIP *scip, SCIP_IISFINDER *iisfinder,)
SCIP_RETCODE SCIPincludeIISfinderBasic(SCIP *scip, SCIP_IISFINDER **iisfinder, const char *name, const char *desc, int priority, SCIP_DECL_IISFINDEREXEC((*iisfinderexec)), SCIP_IISFINDERDATA *iisfinderdata)
SCIP_RANDNUMGEN * SCIPiisGetRandnumgen(SCIP_IIS *iis)
Definition iisfinder.c:1003
void SCIPiisAddNNodes(SCIP_IIS *iis, SCIP_Longint nnodes)
Definition iisfinder.c:993
SCIP * SCIPiisGetSubscip(SCIP_IIS *iis)
Definition iisfinder.c:1012
void SCIPiisSetSubscipIrreducible(SCIP_IIS *iis, SCIP_Bool irreducible)
Definition iisfinder.c:983
SCIP_Longint SCIPiisGetNNodes(SCIP_IIS *iis)
Definition iisfinder.c:963
SCIP_Real SCIPiisGetTime(SCIP_IIS *iis)
Definition iisfinder.c:933
SCIP_Bool SCIPiisIsSubscipInfeasible(SCIP_IIS *iis)
Definition iisfinder.c:943
void SCIPiisSetSubscipInfeasible(SCIP_IIS *iis, SCIP_Bool infeasible)
Definition iisfinder.c:973
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:110
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition scip_mem.c:57
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:93
#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
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition scip_sol.c:2986
SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:1504
SCIP_RETCODE SCIPcreateSolCopyOrig(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol)
Definition scip_sol.c:922
SCIP_RETCODE SCIPfreeTransform(SCIP *scip)
SCIP_RETCODE SCIPsolve(SCIP *scip)
SCIP_Longint SCIPgetNTotalNodes(SCIP *scip)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:5697
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition var.c:24052
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition scip_var.c:5875
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition var.c:23485
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition var.c:24095
return SCIP_OKAY
SCIPfreeSol(scip, &heurdata->sol))
int c
static SCIP_SOL * sol
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
static SCIP_VAR ** vars
#define IISFINDER_NAME
static SCIP_RETCODE deletionFilterBatch(SCIP_IIS *iis, SCIP_Real timelim, SCIP_Longint nodelim, SCIP_Bool removebounds, SCIP_Bool silent, SCIP_Real timelimperiter, SCIP_Longint nodelimperiter, SCIP_Bool conservative, int initbatchsize, int maxbatchsize, SCIP_Real batchingfactor, SCIP_Real batchingoffset, int batchupdateinterval, SCIP_Bool *alldeletionssolved)
#define DEFAULT_INITBATCHSIZE
static SCIP_RETCODE revertBndChgs(SCIP *scip, SCIP_VAR **vars, SCIP_Real *bounds, int *idxs, int ndelbounds, SCIP_Bool islb)
#define DEFAULT_MAXRELBATCHSIZE
#define DEFAULT_INITRELBATCHSIZE
static SCIP_RETCODE execIISfinderGreedy(SCIP_IIS *iis, SCIP_IISFINDERDATA *iisfinderdata, SCIP_RESULT *result)
#define DEFAULT_BATCHINGOFFSET
static SCIP_RETCODE deletionSubproblem(SCIP_IIS *iis, SCIP_CONS **conss, SCIP_VAR **vars, int *idxs, int ndels, SCIP_Real timelim, SCIP_Real timelimperiter, SCIP_Longint nodelim, SCIP_Longint nodelimperiter, SCIP_Bool conservative, SCIP_Bool delbounds, SCIP_Bool islb, SCIP_Bool *deleted, SCIP_Bool *stop, SCIP_Bool *alldeletionssolved)
static SCIP_RETCODE revertConssDeletions(SCIP *scip, SCIP_CONS **conss, int *idxs, int ndelconss, SCIP_Bool releaseonly)
#define DEFAULT_DELAFTERADD
#define DEFAULT_TIMELIMPERITER
#define IISFINDER_PRIORITY
#define DEFAULT_ADDITIVE
#define DEFAULT_DYNAMICREORDERING
#define DEFAULT_BATCHUPDATEINTERVAL
#define DEFAULT_NODELIMPERITER
#define DEFAULT_CONSERVATIVE
static SCIP_RETCODE updateBatchsize(SCIP *scip, int initbatchsize, int maxbatchsize, int iteration, SCIP_Bool resettoinit, SCIP_Real batchingfactor, SCIP_Real batchingoffset, int batchupdateinterval, int *batchsize)
#define IISFINDER_DESC
#define DEFAULT_BATCHINGFACTOR
#define DEFAULT_MAXBATCHSIZE
static SCIP_RETCODE setLimits(SCIP *scip, SCIP_IIS *iis, SCIP_Real timelim, SCIP_Real timelimperiter, SCIP_Longint nodelim, SCIP_Longint nodelimperiter)
static SCIP_RETCODE additionFilterBatch(SCIP_IIS *iis, SCIP_Real timelim, SCIP_Longint nodelim, SCIP_Bool silent, SCIP_Real timelimperiter, SCIP_Longint nodelimperiter, SCIP_Bool dynamicreordering, int initbatchsize, int maxbatchsize, SCIP_Real batchingfactor, SCIP_Real batchingoffset, int batchupdateinterval)
static SCIP_RETCODE additionSubproblem(SCIP_IIS *iis, SCIP_Real timelim, SCIP_Real timelimperiter, SCIP_Longint nodelim, SCIP_Longint nodelimperiter, SCIP_Bool *feasible, SCIP_Bool *stop)
greedy deletion and addition filter heuristic to compute IISs
#define BMSclearMemory(ptr)
Definition memory.h:129
#define SCIPerrorMessage
Definition pub_message.h:64
SCIP_HASHMAP * conssmap
data structures for irreducible infeasible subsystems (IIS)
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
#define SCIP_DECL_IISFINDERFREE(x)
#define SCIP_DECL_IISFINDEREXEC(x)
struct SCIP_IISfinder SCIP_IISFINDER
struct SCIP_IISfinderData SCIP_IISFINDERDATA
#define SCIP_DECL_IISFINDERCOPY(x)
struct SCIP_HashMap SCIP_HASHMAP
Definition type_misc.h:106
struct SCIP_HashMapEntry SCIP_HASHMAPENTRY
Definition type_misc.h:100
struct SCIP_RandNumGen SCIP_RANDNUMGEN
Definition type_misc.h:127
@ SCIP_FEASIBLE
Definition type_result.h:45
@ SCIP_DIDNOTFIND
Definition type_result.h:44
@ SCIP_SUCCESS
Definition type_result.h:58
enum SCIP_Result SCIP_RESULT
Definition type_result.h:61
@ SCIP_INVALIDDATA
@ SCIP_INVALIDCALL
@ SCIP_ERROR
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
@ SCIP_STAGE_PROBLEM
Definition type_set.h:45
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
@ SCIP_STATUS_OPTIMAL
Definition type_stat.h:43
@ SCIP_STATUS_TOTALNODELIMIT
Definition type_stat.h:50
@ SCIP_STATUS_BESTSOLLIMIT
Definition type_stat.h:60
@ SCIP_STATUS_SOLLIMIT
Definition type_stat.h:59
@ SCIP_STATUS_UNBOUNDED
Definition type_stat.h:45
@ SCIP_STATUS_UNKNOWN
Definition type_stat.h:42
@ SCIP_STATUS_PRIMALLIMIT
Definition type_stat.h:57
@ SCIP_STATUS_GAPLIMIT
Definition type_stat.h:56
@ SCIP_STATUS_USERINTERRUPT
Definition type_stat.h:47
@ SCIP_STATUS_TERMINATE
Definition type_stat.h:48
@ SCIP_STATUS_INFORUNBD
Definition type_stat.h:46
@ SCIP_STATUS_STALLNODELIMIT
Definition type_stat.h:52
@ SCIP_STATUS_TIMELIMIT
Definition type_stat.h:54
@ SCIP_STATUS_INFEASIBLE
Definition type_stat.h:44
@ SCIP_STATUS_NODELIMIT
Definition type_stat.h:49
@ SCIP_STATUS_DUALLIMIT
Definition type_stat.h:58
@ SCIP_STATUS_MEMLIMIT
Definition type_stat.h:55
@ SCIP_STATUS_RESTARTLIMIT
Definition type_stat.h:62
enum SCIP_Status SCIP_STATUS
Definition type_stat.h:64
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_VARTYPE_BINARY
Definition type_var.h:64