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
32#include <assert.h>
33
35
36#define IISFINDER_NAME "greedy"
37#define IISFINDER_DESC "greedy deletion or addition constraint deletion"
38#define IISFINDER_PRIORITY 8000
39
40#define DEFAULT_TIMELIMPERITER 1e+20 /**< time limit of optimization process for each individual subproblem */
41#define DEFAULT_NODELIMPERITER -1L /**< node limit of optimization process for each individual subproblem */
42
43#define DEFAULT_ADDITIVE TRUE /**< should an additive constraint approach be used instead of deletion */
44#define DEFAULT_CONSERVATIVE TRUE /**< should an unsolved problem (by e.g. user interrupt, node limit, time limit) be considered feasible when deleting constraints */
45#define DEFAULT_DELAFTERADD TRUE /**< should the deletion routine be performed after the addition routine (in the case of additive) */
46#define DEFAULT_DYNAMICREORDERING TRUE /**< should satisfied constraints outside the batch of an intermediate solve be added during the additive method */
47
48#define DEFAULT_INITBATCHSIZE 16 /**< the initial batchsize for the first iteration, ignored if initrelbatchsize is positive */
49#define DEFAULT_INITRELBATCHSIZE 0.03125 /**< the initial batchsize relative to the original problem for the first iteration (0.0: use initbatchsize) */
50#define DEFAULT_MAXBATCHSIZE INT_MAX /**< the maximum batchsize per iteration */
51#define DEFAULT_MAXRELBATCHSIZE 0.5 /**< the maximum batchsize relative to the original problem per iteration */
52#define DEFAULT_BATCHINGFACTOR 2.0 /**< the factor with which the batchsize is multiplied in every update */
53#define DEFAULT_BATCHINGOFFSET 0.0 /**< the offset which is added to the multiplied batchsize in every update */
54#define DEFAULT_BATCHUPDATEINTERVAL 1 /**< the number of iterations to run with a constant batchsize before updating (1: always update) */
55
56
57/*
58 * Data structures
59 */
60
61/** IIS finder data */
62struct SCIP_IISfinderData
63{
64 SCIP_Real timelimperiter; /**< time limit of optimization process for each individual subproblem */
65 SCIP_Longint nodelimperiter; /**< node limit of optimization process for each individual subproblem */
66
67 SCIP_Bool additive; /**< should an additive constraint approach be used instead of deletion */
68 SCIP_Bool conservative; /**< should an unsolved problem (by e.g. user interrupt, node limit, time limit) be considered feasible when deleting constraints */
69 SCIP_Bool delafteradd; /**< should the deletion routine be performed after the addition routine (in the case of additive) */
70 SCIP_Bool dynamicreordering; /**< should satisfied constraints outside the batch of an intermediate solve be added during the additive method */
71
72 int initbatchsize; /**< the initial batchsize for the first iteration, ignored if initrelbatchsize is positive */
73 SCIP_Real initrelbatchsize; /**< the initial batchsize relative to the original problem for the first iteration (0.0: use initbatchsize) */
74 int maxbatchsize; /**< the maximum batchsize per iteration */
75 SCIP_Real maxrelbatchsize; /**< the maximum batchsize relative to the original problem per iteration */
76 SCIP_Real batchingfactor; /**< the factor with which the batchsize is multiplied in every update */
77 SCIP_Real batchingoffset; /**< the offset which is added to the multiplied batchsize in every update */
78 int batchupdateinterval; /**< the number of iterations to run with a constant batchsize before updating (1: always update) */
79};
80
81/*
82 * Local methods
83 */
84
85/* Set time and node limits on the subproblem */
86static
88 SCIP* scip, /**< SCIP instance to analyze */
89 SCIP_IIS* iis, /**< IIS data structure containing subscip */
90 SCIP_Real timelim, /**< total time limit allowed of the whole call */
91 SCIP_Real timelimperiter, /**< time limit per individual solve call */
92 SCIP_Longint nodelim, /**< node limit allowed for the whole call */
93 SCIP_Longint nodelimperiter /**< maximum number of nodes per individual solve call */
94 )
95{
96 SCIP_Real currtime;
97 SCIP_Real mintimelim;
98 SCIP_Longint globalnodelim;
99
100 /* 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 */
101 currtime = SCIPiisGetTime(iis);
102 mintimelim = MIN(timelim - currtime, timelimperiter);
103 mintimelim = MAX(mintimelim, 0);
104 SCIP_CALL( SCIPsetRealParam(scip, "limits/time", mintimelim) );
105
106 /* 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 */
107 if( nodelim == -1 )
108 globalnodelim = -1;
109 else
110 {
111 globalnodelim = nodelim - SCIPiisGetNNodes(iis);
112 assert( globalnodelim >= 0 );
113 }
114 if( globalnodelim == -1 && nodelimperiter == -1 )
115 {
116 SCIP_CALL( SCIPsetLongintParam(scip, "limits/nodes", nodelim) );
117 }
118 else if( globalnodelim == -1 || nodelimperiter == -1 )
119 {
120 SCIP_CALL( SCIPsetLongintParam(scip, "limits/nodes", MAX(globalnodelim, nodelimperiter)) );
121 }
122 else
123 {
124 SCIP_CALL( SCIPsetLongintParam(scip, "limits/nodes", MIN(globalnodelim, nodelimperiter)) );
125 }
126 return SCIP_OKAY;
127}
128
129/* Revert bound changes made in the subproblem */
130static
132 SCIP* scip, /**< SCIP instance to analyze */
133 SCIP_VAR** vars, /**< the array of variables whose bounds are changed */
134 SCIP_Real* bounds, /**< the array of original bounds for the variables */
135 int* idxs, /**< the indices of the vars (in the vars array) that have been deleted */
136 int ndelbounds, /**< the number of bounds that will be deleted */
137 SCIP_Bool islb /**< are the bounds that are being deleted LBs? */
138 )
139{
140 int i;
141
142 /* Iterate over the affected variables and restore the bounds back to their original values */
143 for (i = 0; i < ndelbounds; ++i)
144 {
145 if( islb )
146 {
147 if( !SCIPisInfinity(scip, -bounds[i]) )
148 SCIP_CALL( SCIPchgVarLb(scip, vars[idxs[i]], bounds[i]) );
149 }
150 else
151 {
152 if( !SCIPisInfinity(scip, bounds[i]) )
153 SCIP_CALL( SCIPchgVarUb(scip, vars[idxs[i]], bounds[i]) );
154 }
155 }
156 return SCIP_OKAY;
157}
158
159/* Revert deleted constraint changes made in the subproblem */
160static
162 SCIP* scip, /**< SCIP instance to analyze */
163 SCIP_CONS** conss, /**< the array of constraints where some have been deleted */
164 int* idxs, /**< the indices of the cons (in the conss array) that have been deleted */
165 int ndelconss, /**< the number of constraints that have been deleted */
166 SCIP_Bool releaseonly /**< Should the constraints just be released instead of added back */
167 )
168{
169 int i;
170 SCIP_CONS* copycons;
171
172 for( i = 0; i < ndelconss; ++i )
173 {
174 if( releaseonly )
175 {
176 SCIP_CALL( SCIPreleaseCons(scip, &conss[idxs[i]]) );
177 }
178 else
179 {
180 SCIP_CALL( SCIPaddCons(scip, conss[idxs[i]]) );
181 copycons = conss[idxs[i]];
182 assert(SCIPconsGetNUses(copycons) > 1);
183 SCIP_CALL( SCIPreleaseCons(scip, &copycons) );
184 }
185 }
186
187 return SCIP_OKAY;
188}
189
190/* Update the batchsize accoring to the chosen rule */
191static
193 SCIP* scip, /**< SCIP data structure */
194 int initbatchsize, /**< the initial batchsize */
195 int maxbatchsize, /**< the maximum batchsize per iteration */
196 int iteration, /**< the current iteration */
197 SCIP_Bool resettoinit, /**< should the batchsize be reset to the initial batchsize? */
198 SCIP_Real batchingfactor, /**< the factor with which the batchsize is multiplied in every update */
199 SCIP_Real batchingoffset, /**< the offset which is added to the multiplied batchsize in every update */
200 int batchupdateinterval, /**< the number of iterations to run with a constant batchsize before updating (1: always update) */
201 int* batchsize /**< the batchsize to be updated */
202 )
203{
204 if( resettoinit )
205 *batchsize = initbatchsize;
206 else if( iteration % batchupdateinterval == 0 )
207 *batchsize = (int)ceil(batchingfactor * (*batchsize) + batchingoffset);
208
209 /* respect limits and maximum */
210 *batchsize = MIN(*batchsize, maxbatchsize);
211 *batchsize = MAX(*batchsize, 1);
212 SCIPdebugMsg(scip, "Updated batchsize to %d\n", *batchsize);
213
214 return SCIP_OKAY;
215}
216
217/** solve subproblem for deletionFilter */
218static
220 SCIP_IIS* iis, /**< IIS data structure containing subscip */
221 SCIP_CONS** conss, /**< The array of constraints (may be a superset of the current constraints) */
222 SCIP_VAR** vars, /**< the array of vars */
223 int* idxs, /**< the indices of the constraints / vars that will be deleted / bounds removed */
224 int ndels, /**< the number of bounds that will be deleted */
225 SCIP_Real timelim, /**< The global time limit on the IIS finder call */
226 SCIP_Real timelimperiter, /**< time limit per individual solve call */
227 SCIP_Longint nodelim, /**< The global node limit on the IIS finder call */
228 SCIP_Longint nodelimperiter, /**< maximum number of nodes per individual solve call */
229 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 */
230 SCIP_Bool delbounds, /**< whether bounds should be deleted instead of constraints */
231 SCIP_Bool islb, /**< are the bounds that are being deleted LBs? */
232 SCIP_Bool* deleted, /**< have the deleted bounds or constraints stayed deleted */
233 SCIP_Bool* stop, /**< pointer to store whether we have to stop */
234 SCIP_Bool* alldeletionssolved /**< pointer to store whether all the subscips solved */
235 )
236{
237 SCIP* scip;
238 SCIP_Real* bounds = NULL;
239 SCIP_RETCODE retcode;
240 SCIP_STATUS status;
241 SCIP_Bool chgmade = FALSE;
242 int i;
243
244 *deleted = FALSE;
245 *stop = FALSE;
246 scip = SCIPiisGetSubscip(iis);
247
248 /* remove bounds or constraints */
249 if( delbounds )
250 {
251 assert(vars != NULL);
252 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &bounds, ndels) );
253 for (i = 0; i < ndels; ++i)
254 {
255 if( islb )
256 {
257 bounds[i] = SCIPvarGetLbOriginal(vars[idxs[i]]);
258 if( !SCIPisInfinity(scip, -bounds[i]) )
259 {
261 chgmade = TRUE;
262 }
263 }
264 else
265 {
266 bounds[i] = SCIPvarGetUbOriginal(vars[idxs[i]]);
267 if( !SCIPisInfinity(scip, bounds[i]) )
268 {
270 chgmade = TRUE;
271 }
272 }
273 }
274 }
275 else
276 {
277 assert(conss != NULL);
278
279 if( ndels > 0 )
280 chgmade = TRUE;
281 for (i = 0; i < ndels; ++i)
282 {
283 assert( SCIPconsIsInProb(conss[idxs[i]]) );
284 SCIP_CALL( SCIPcaptureCons(scip, conss[idxs[i]]) );
285 SCIP_CALL( SCIPdelCons(scip, conss[idxs[i]]) );
286 }
287 }
288
289 if( !chgmade )
290 {
291 if( delbounds )
292 SCIPfreeBlockMemoryArray(scip, &bounds, ndels);
293 return SCIP_OKAY;
294 }
295
296 /* solve problem until first solution is found or infeasibility has been proven */
297 SCIP_CALL( setLimits(scip, iis, timelim, timelimperiter, nodelim, nodelimperiter) );
298 retcode = SCIPsolve(scip);
300
301 if( retcode != SCIP_OKAY )
302 {
304 SCIPdebugMsg(scip, "Error in sub-scip with deleted constraints / bounds. Re-adding them.\n");
305 if( delbounds )
306 {
307 SCIP_CALL( revertBndChgs(scip, vars, bounds, idxs, ndels, islb) );
308 SCIPfreeBlockMemoryArray(scip, &bounds, ndels);
309 }
310 else
311 {
312 SCIP_CALL( revertConssDeletions(scip, conss, idxs, ndels, FALSE) );
313 }
314 *alldeletionssolved = FALSE;
315 return SCIP_OKAY;
316 }
317
318 status = SCIPgetStatus(scip);
320
321 /* check status and handle accordingly */
322 switch ( status )
323 {
324 case SCIP_STATUS_USERINTERRUPT: /* if a user interrupt occurred, just stop */
326 SCIPdebugMsg(scip, "User interrupt. Stopping.\n");
327 if( delbounds )
328 {
329 SCIP_CALL( revertBndChgs(scip, vars, bounds, idxs, ndels, islb) );
330 }
331 else
332 {
333 SCIP_CALL( revertConssDeletions(scip, conss, idxs, ndels, !conservative) );
334 }
335 *stop = TRUE;
336 *alldeletionssolved = FALSE;
337 break;
338
339 case SCIP_STATUS_TIMELIMIT: /* if we reached some status that may have ended up in an infeasible problem */
348 *alldeletionssolved = FALSE;
349 SCIPdebugMsg(scip, "Some limit reached. Keeping bounds / constraints removed if non-conservative.\n");
350 if( !conservative )
351 {
353 *deleted = TRUE;
354 }
355 if( conservative && delbounds )
356 {
357 SCIP_CALL( revertBndChgs(scip, vars, bounds, idxs, ndels, islb) );
358 }
359 if( !delbounds )
360 {
361 SCIP_CALL( revertConssDeletions(scip, conss, idxs, ndels, !conservative) );
362 }
363 break;
364
365 case SCIP_STATUS_INFEASIBLE: /* if the problem is infeasible */
366 SCIPdebugMsg(scip, "Subproblem with bounds / constraints removed infeasible. Keep them removed.\n");
368 if( !delbounds )
369 {
370 SCIP_CALL( revertConssDeletions(scip, conss, idxs, ndels, TRUE) );
371 }
372 *deleted = TRUE;
373 break;
374
375 case SCIP_STATUS_BESTSOLLIMIT: /* we found a solution */
380 SCIPdebugMsg(scip, "Found solution to subproblem with bounds / constraints removed. Add them back.\n");
381 if( delbounds )
382 {
383 SCIP_CALL( revertBndChgs(scip, vars, bounds, idxs, ndels, islb) );
384 }
385 else
386 {
387 SCIP_CALL( revertConssDeletions(scip, conss, idxs, ndels, FALSE) );
388 }
389 break;
390
392 default:
393 *alldeletionssolved = FALSE;
394 SCIPerrorMessage("Unexpected return status %d in removed bounds subproblem. Exiting...\n", status);
395 if( delbounds )
396 SCIPfreeBlockMemoryArray(scip, &bounds, ndels);
397 return SCIP_ERROR;
398 }
399
400 if( delbounds )
401 SCIPfreeBlockMemoryArray(scip, &bounds, ndels);
402
403 return SCIP_OKAY;
404}
405
406/** solve subproblem for additionFilter */
407static
409 SCIP_IIS* iis, /**< IIS data structure containing subscip */
410 SCIP_Real timelim, /**< The global time limit on the IIS finder call */
411 SCIP_Real timelimperiter, /**< time limit per individual solve call */
412 SCIP_Longint nodelim, /**< The global node limit on the IIS finder call */
413 SCIP_Longint nodelimperiter, /**< maximum number of nodes per individual solve call */
414 SCIP_Bool* feasible, /**< pointer to store whether the problem is feasible */
415 SCIP_Bool* stop /**< pointer to store whether we have to stop */
416 )
417{
418 SCIP* scip;
419 SCIP_RETCODE retcode;
420 SCIP_STATUS status;
421
422 assert( stop != NULL );
423 scip = SCIPiisGetSubscip(iis);
424
425 *stop = FALSE;
426
427 /* solve problem until first solution is found or infeasibility has been proven */
428 SCIP_CALL( setLimits(scip, iis, timelim, timelimperiter, nodelim, nodelimperiter) );
429 retcode = SCIPsolve(scip);
430
431 if( retcode != SCIP_OKAY )
432 {
433 SCIPdebugMsg(scip, "Error in sub-scip with added constraints. Keep added constraints.\n");
434 return SCIP_ERROR;
435 }
436
438 status = SCIPgetStatus(scip);
439
440 /* check status */
441 switch ( status )
442 {
443 case SCIP_STATUS_USERINTERRUPT: /* if an user interrupt occurred, just stop */
445 SCIPdebugMsg(scip, "User interrupt. Stopping.\n");
446 *stop = TRUE;
447 break;
448
449 case SCIP_STATUS_NODELIMIT: /* if we reached some limit */
459 SCIPdebugMsg(scip, "Some limit reached. Added constraint batch failed to induce infeasibility. Continue adding.\n");
460 break;
461
462 case SCIP_STATUS_INFEASIBLE: /* if the problem is infeasible */
463 SCIPdebugMsg(scip, "Subproblem with added constraints infeasible. Final batch of constraints added.\n");
464 *feasible = FALSE;
465 break;
466
467 case SCIP_STATUS_BESTSOLLIMIT: /* we found a solution */
471 SCIPdebugMsg(scip, "Found solution of subproblem with added constraints. Keep adding constraint batches.\n");
472 *feasible = TRUE;
473 break;
474
476 default:
477 SCIPerrorMessage("Unexpected return status %d. Exiting ...\n", status);
478 return SCIP_ERROR;
479 }
480
481 return SCIP_OKAY;
482}
483
484
485/** Deletion filter to greedily remove constraints to obtain an (I)IS */
486static
488 SCIP_IIS* iis, /**< IIS data structure containing subscip */
489 SCIP_Real timelim, /**< The global time limit on the IIS finder call */
490 SCIP_Longint nodelim, /**< The global node limit on the IIS finder call */
491 SCIP_Bool removebounds, /**< Whether the algorithm should remove bounds as well as constraints */
492 SCIP_Bool silent, /**< should the run be performed silently without printing progress information */
493
494 SCIP_Real timelimperiter, /**< time limit per individual solve call */
495 SCIP_Longint nodelimperiter, /**< maximum number of nodes per individual solve call */
496 SCIP_Bool conservative, /**< should a node or time limit solve be counted as feasible when deleting constraints */
497
498 int initbatchsize, /**< the initial batchsize for the first iteration */
499 int maxbatchsize, /**< the maximum batchsize per iteration */
500 SCIP_Real batchingfactor, /**< the factor with which the batchsize is multiplied in every update */
501 SCIP_Real batchingoffset, /**< the offset which is added to the multiplied batchsize in every update */
502 int batchupdateinterval, /**< the number of iterations to run with a constant batchsize before updating (1: always update) */
503
504 SCIP_Bool* alldeletionssolved /**< pointer to store whether all the subscips solved */
505 )
506{
507 SCIP* scip;
508 SCIP_CONS** origconss;
509 SCIP_CONS** conss;
510 SCIP_VAR** origvars;
511 SCIP_VAR** vars;
512 SCIP_RANDNUMGEN* randnumgen;
513 int* order;
514 int* idxs;
515 SCIP_Bool stopiter;
516 SCIP_Bool deleted;
517 int nconss;
518 int nvars;
519 int batchindex;
520 int batchsize = initbatchsize;
521 int iteration;
522 int i;
523 int k;
524
525 /* get current subscip */
526 scip = SCIPiisGetSubscip(iis);
527 assert( scip != NULL );
529
530 /* get random generator */
531 randnumgen = SCIPiisGetRandnumgen(iis);
532 assert( randnumgen != NULL );
533
534 /* get batch size */
535 assert( initbatchsize >= 1 );
536 assert( maxbatchsize >= 1 );
537 initbatchsize = MIN(initbatchsize, maxbatchsize);
538
539 /* allocate indices array */
540 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &idxs, maxbatchsize) );
541
542 /* get constraint information */
543 nconss = SCIPgetNOrigConss(scip);
544 origconss = SCIPgetOrigConss(scip);
545 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &conss, origconss, nconss) );
546
547 /* reset problem */
550
551 /* prepare random order for constraints */
552 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &order, nconss) );
553 for (i = 0; i < nconss; ++i)
554 order[i] = i;
555 SCIPrandomPermuteIntArray(randnumgen, order, 0, nconss);
556
557 /* Loop through all batches of constraints in random order */
558 i = 0;
559 iteration = 0;
560 deleted = FALSE;
561 stopiter = FALSE;
562 while( i < nconss )
563 {
564 /* update batchsize */
565 SCIP_CALL( updateBatchsize(scip, initbatchsize, maxbatchsize, iteration, !deleted, batchingfactor, batchingoffset, batchupdateinterval, &batchsize) );
566
567 k = 0;
568 batchindex = i;
569 while( i < nconss && k < batchsize )
570 {
571 assert( conss[order[i]] != NULL );
572 if( SCIPconsGetNUses(conss[order[i]]) == 1 )
573 {
574 idxs[k] = order[i];
575 k++;
576 }
577 i++;
578 }
579
580 /* treat subproblem */
581 SCIP_CALL( deletionSubproblem(iis, conss, NULL, idxs, k, timelim, timelimperiter, nodelim, nodelimperiter,
582 conservative, FALSE, FALSE, &deleted, &stopiter, alldeletionssolved) );
583 if( !silent && deleted )
585
586 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) || stopiter )
587 break;
588
589 /* reset i to beginning of current batch if batch has not been deleted and k was large */
590 if( !deleted && k > initbatchsize )
591 i = batchindex;
592
593 ++iteration;
594
596 }
597
598 SCIPfreeBlockMemoryArray(scip, &order, nconss);
599 SCIPfreeBlockMemoryArray(scip, &conss, nconss);
600 SCIPfreeBlockMemoryArray(scip, &idxs, maxbatchsize);
601
602 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) || stopiter )
603 return SCIP_OKAY;
604
605 /* Repeat the above procedure but for bounds instead of constraints */
606 if( removebounds )
607 {
608 /* allocate indices array */
609 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &idxs, maxbatchsize) );
610
612 origvars = SCIPgetOrigVars(scip);
614
616 for (i = 0; i < nvars; ++i)
617 order[i] = i;
618 SCIPrandomPermuteIntArray(randnumgen, order, 0, nvars);
619
620 i = 0;
621 iteration = 0;
622 deleted = FALSE;
623 while( i < nvars )
624 {
625 /* update batchsize */
626 SCIP_CALL( updateBatchsize(scip, initbatchsize, maxbatchsize, iteration, !deleted, batchingfactor, batchingoffset, batchupdateinterval, &batchsize) );
627
628 k = 0;
629 batchindex = i;
630 /* Do not delete bounds of binary variables or bother with calculations of free variables */
631 while( i < nvars && k < batchsize )
632 {
634 {
635 idxs[k] = order[i];
636 k++;
637 }
638 i++;
639 }
640 if( k == 0 )
641 break;
642
643 /* treat subproblem with LB deletions */
644 SCIP_CALL( deletionSubproblem(iis, NULL, vars, idxs, k, timelim, timelimperiter, nodelim, nodelimperiter,
645 conservative, TRUE, TRUE, &deleted, &stopiter, alldeletionssolved) );
646 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) || stopiter )
647 break;
648 if( !silent && deleted )
650
651 /* treat subproblem with UB deletions */
652 SCIP_CALL( deletionSubproblem(iis, NULL, vars, idxs, k, timelim, timelimperiter, nodelim, nodelimperiter,
653 conservative, TRUE, FALSE, &deleted, &stopiter, alldeletionssolved) );
654
655 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) || stopiter )
656 break;
657 if( !silent && deleted )
659
660 /* reset i to beginning of current batch if batch has not been deleted and k was large */
661 if( !deleted && k > initbatchsize )
662 i = batchindex;
663
664 ++iteration;
665 }
666
669 SCIPfreeBlockMemoryArray(scip, &idxs, maxbatchsize);
670 }
671
672 return SCIP_OKAY;
673}
674
675/** Addition filter to greedily add constraints to obtain an (I)IS */
676static
678 SCIP_IIS* iis, /**< IIS data structure containing subscip */
679 SCIP_Real timelim, /**< The global time limit on the IIS finder call */
680 SCIP_Longint nodelim, /**< The global node limit on the IIS finder call */
681 SCIP_Bool silent, /**< should the run be performed silently without printing progress information */
682
683 SCIP_Real timelimperiter, /**< time limit per individual solve call */
684 SCIP_Longint nodelimperiter, /**< maximum number of nodes per individual solve call */
685 SCIP_Bool dynamicreordering, /**< should satisfied constraints outside the batch of an intermediate solve be added during the additive method */
686
687 int initbatchsize, /**< the initial batchsize for the first iteration */
688 int maxbatchsize, /**< the maximum batchsize per iteration */
689 SCIP_Real batchingfactor, /**< the factor with which the batchsize is multiplied in every update */
690 SCIP_Real batchingoffset, /**< the offset which is added to the multiplied batchsize in every update */
691 int batchupdateinterval /**< the number of iterations to run with a constant batchsize before updating (1: always update) */
692 )
693{
694 SCIP* scip;
695 SCIP_CONS** origconss;
696 SCIP_CONS** conss;
697 SCIP_RANDNUMGEN* randnumgen;
698 SCIP_SOL* sol;
699 SCIP_SOL* copysol;
700 SCIP_Bool* inIS;
701 int* order;
702 SCIP_Bool feasible;
703 SCIP_Bool stopiter;
704 SCIP_RETCODE retcode;
706 int nconss;
707 int batchsize;
708 int iteration;
709 int i;
710 int j;
711 int k;
712
713 /* get current subscip */
714 scip = SCIPiisGetSubscip(iis);
715 assert( scip != NULL );
717
718 /* get random generator */
719 randnumgen = SCIPiisGetRandnumgen(iis);
720 assert( randnumgen != NULL );
721
722 /* get batch size */
723 assert( initbatchsize >= 1 );
724 assert( maxbatchsize >= 1 );
725 initbatchsize = MIN(initbatchsize, maxbatchsize);
726 batchsize = initbatchsize;
727
728 /* get constraint information */
729 nconss = SCIPgetNOrigConss(scip);
730 origconss = SCIPgetOrigConss(scip);
731 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &conss, origconss, nconss) );
732
733 /* Initialise information for whether a constraint is in the final infeasible system */
734 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &inIS, nconss) );
735
736 /* First capture and then delete all constraints */
738 for( i = 0; i < nconss; ++i )
739 {
740 assert( SCIPconsIsInProb(conss[i]) );
741 if( SCIPconsGetNUses(conss[i]) > 1 )
742 {
743 inIS[i] = TRUE;
744 }
745 else
746 {
747 SCIP_CALL( SCIPcaptureCons(scip, conss[i]) );
748 SCIP_CALL( SCIPdelCons(scip, conss[i]) );
749 inIS[i] = FALSE;
750 }
751 }
753
754 /* Prepare random order in which the constraints will be added back */
755 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &order, nconss) );
756 for (i = 0; i < nconss; ++i)
757 order[i] = i;
758 SCIPrandomPermuteIntArray(randnumgen, order, 0, nconss);
759
760 /* Continue to add constraints until an infeasible status is reached */
761 i = 0;
762 iteration = 0;
763 feasible = TRUE;
764 stopiter = FALSE;
765 while( i < nconss )
766 {
767 /* Add the next batch of constraints */
768 k = 0;
769 while( i < nconss && k < batchsize )
770 {
771 if( !inIS[order[i]] )
772 {
773 SCIP_CALL( SCIPaddCons(scip, conss[order[i]]) );
774 SCIP_CALL( SCIPreleaseCons(scip, &conss[order[i]]) );
775 inIS[order[i]] = TRUE;
776 ++k;
777 }
778 i++;
779 }
780
781 /* We have the full infeasible problem again */
782 if( i == nconss )
783 {
784 feasible = FALSE;
785 break;
786 }
787
788 /* Solve the reduced problem */
789 retcode = additionSubproblem(iis, timelim, timelimperiter, nodelim, nodelimperiter, &feasible, &stopiter);
790 if( !feasible || stopiter || timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) )
791 {
793 break;
794 }
795
796 if( !silent )
798
799 if( dynamicreordering && retcode == SCIP_OKAY )
800 {
801 /* free transform and copy solution if there is one */
802 copysol = NULL;
804 if( sol != NULL )
805 {
807 SCIP_CALL( SCIPunlinkSol(scip, copysol) );
808 }
811
812 /* Add any other constraints that are also feasible for the current solution */
813 if( copysol != NULL )
814 {
815 k = 0;
816 for( j = i; j < nconss; ++j )
817 {
818 /* Don't dynamically add indicator constraints */
819 if( !inIS[order[j]]
820 && strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(conss[order[j]])), "indicator") != 0 )
821 {
822 SCIP_CALL( SCIPcheckCons(scip, conss[order[j]], copysol, FALSE, FALSE, FALSE, &result) );
823 if( result == SCIP_FEASIBLE )
824 {
825 SCIP_CALL( SCIPaddCons(scip, conss[order[j]]) );
826 SCIP_CALL( SCIPreleaseCons(scip, &conss[order[j]]) );
827 inIS[order[j]] = TRUE;
828 k++;
829 }
830 }
831 }
832 SCIPdebugMsg(scip, "Added %d constraints by reordering dynamically.\n", k);
833 SCIP_CALL( SCIPfreeSol(scip, &copysol) );
834 }
835 }
836 else
837 {
840 }
841
842 ++iteration;
843
844 /* update batchsize */
845 SCIP_CALL( updateBatchsize(scip, initbatchsize, maxbatchsize, iteration, FALSE, batchingfactor, batchingoffset, batchupdateinterval, &batchsize) );
846 }
847
848 /* If problem is feasible due to limit or interrupt, add the deleted constraints of the full infeasible problem */
849 if( feasible )
850 {
851 assert(stopiter || SCIPiisGetTime(iis) >= timelim || (nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim));
852 SCIPdebugMsg(scip, "Hit limit or interrupt. Restore full infeasible problem.\n");
853 for( i = 0; i < nconss; ++i )
854 {
855 if( !inIS[order[i]] )
856 {
857 SCIP_CALL( SCIPaddCons(scip, conss[order[i]]) );
858 SCIP_CALL( SCIPreleaseCons(scip, &conss[order[i]]) );
859 inIS[order[i]] = TRUE;
860 }
861 }
862 }
863 else
864 {
865 /* Release any cons not in the IS */
866 for( i = 0; i < nconss; ++i )
867 {
868 if( !inIS[order[i]] )
869 {
870 SCIP_CALL( SCIPreleaseCons(scip, &conss[order[i]]) );
871 }
872 }
873 }
874
875 SCIPfreeBlockMemoryArray(scip, &order, nconss);
876 SCIPfreeBlockMemoryArray(scip, &inIS, nconss);
877 SCIPfreeBlockMemoryArray(scip, &conss, nconss);
879
880 if( !silent )
882
883 return SCIP_OKAY;
884}
885
886/** perform a greedy addition or deletion algorithm to obtain an infeasible subsystem (IS).
887 *
888 * This is the generation method for the greedy IIS finder rule.
889 * Depending on the parameter choices, constraints are either greedily added from an empty problem,
890 * or deleted from a complete problem. In the case of constraints being added, this is done until the problem
891 * becomes infeasible, after which one can then begin deleting constraints. In the case of deleting constraints,
892 * this is done until no more constraints (or batches of constraints) can be deleted without making
893 * the problem feasible.
894 */
895static
897 SCIP_IIS* iis, /**< IIS data structure */
898 SCIP_IISFINDERDATA* iisfinderdata, /**< IIS finder data */
899 SCIP_RESULT* result /**< pointer to store the result of the IIS finder run. SCIP_DIDNOTFIND if the algorithm failed, otherwise SCIP_SUCCESS. */
900 )
901{
903 SCIP_Real timelim;
904 SCIP_Longint nodelim;
905 SCIP_Bool removebounds;
906 SCIP_Bool silent;
907 SCIP_Bool alldeletionssolved = TRUE;
908 int nvars;
909 int nconss;
910 int maxbatchsize;
911 int initbatchsize;
912
913 assert( scip != NULL );
914 assert( iisfinderdata != NULL );
915 assert( result != NULL );
916
917 SCIP_CALL( SCIPgetRealParam(scip, "iis/time", &timelim) );
918 SCIP_CALL( SCIPgetLongintParam(scip, "iis/nodes", &nodelim) );
919 SCIP_CALL( SCIPgetBoolParam(scip, "iis/removebounds", &removebounds) );
920 SCIP_CALL( SCIPgetBoolParam(scip, "iis/silent", &silent) );
921
923 nconss = SCIPgetNOrigConss(scip);
924 maxbatchsize = MAX(nvars, nconss);
925 initbatchsize = iisfinderdata->initrelbatchsize > 0.0
926 ? (int)ceil(iisfinderdata->initrelbatchsize * maxbatchsize) : MIN(iisfinderdata->initbatchsize, maxbatchsize);
927 maxbatchsize = (int)ceil(iisfinderdata->maxrelbatchsize * maxbatchsize);
928 maxbatchsize = MIN(iisfinderdata->maxbatchsize, maxbatchsize);
929 initbatchsize = MAX(initbatchsize, 1);
930 maxbatchsize = MAX(maxbatchsize, 1);
931
933
934 if( iisfinderdata->additive )
935 {
936 if( !silent )
937 {
938 SCIPdebugMsg(scip, "----- STARTING GREEDY ADDITION ALGORITHM -----\n");
939 }
940 SCIP_CALL( additionFilterBatch(iis, timelim, nodelim, silent, iisfinderdata->timelimperiter,
941 iisfinderdata->nodelimperiter, iisfinderdata->dynamicreordering, initbatchsize, maxbatchsize,
942 iisfinderdata->batchingfactor, iisfinderdata->batchingoffset, iisfinderdata->batchupdateinterval) );
944 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) )
945 return SCIP_OKAY;
946 }
947 else
948 {
949 if( !silent )
950 {
951 SCIPdebugMsg(scip, "----- STARTING GREEDY DELETION ALGORITHM -----\n");
952 }
953 SCIP_CALL( deletionFilterBatch(iis, timelim, nodelim, removebounds, silent, iisfinderdata->timelimperiter,
954 iisfinderdata->nodelimperiter, iisfinderdata->conservative, initbatchsize, maxbatchsize,
955 iisfinderdata->batchingfactor, iisfinderdata->batchingoffset, iisfinderdata->batchupdateinterval,
956 &alldeletionssolved) );
957 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) )
958 return SCIP_OKAY;
959 if( alldeletionssolved && initbatchsize == 1 )
961 }
962
963 if( iisfinderdata->delafteradd && iisfinderdata->additive )
964 {
965 if( !silent )
966 {
967 SCIPdebugMsg(scip, "----- STARTING GREEDY DELETION ALGORITHM FOLLOWING COMPLETED ADDITION ALGORITHM -----\n");
968 }
969 SCIP_CALL( deletionFilterBatch(iis, timelim, nodelim, removebounds, silent, iisfinderdata->timelimperiter,
970 iisfinderdata->nodelimperiter, iisfinderdata->conservative, initbatchsize, maxbatchsize,
971 iisfinderdata->batchingfactor, iisfinderdata->batchingoffset, iisfinderdata->batchupdateinterval,
972 &alldeletionssolved) );
973 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) )
974 return SCIP_OKAY;
975 if( alldeletionssolved && initbatchsize == 1 )
977 }
978
979 return SCIP_OKAY;
980}
981
982
983/*
984 * Callback methods of IIS finder
985 */
986
987
988/** copy method for IIS finder plugin (called when SCIP copies plugins) */
989static
990SCIP_DECL_IISFINDERCOPY(iisfinderCopyGreedy)
991{ /*lint --e{715}*/
992 assert(scip != NULL);
993 assert(iisfinder != NULL);
994 assert(strcmp(SCIPiisfinderGetName(iisfinder), IISFINDER_NAME) == 0);
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 = SCIPiisGetSubscip(iis);
1139 SCIP_Real timelim;
1140 SCIP_Longint nodelim;
1141 SCIP_Bool removebounds;
1142 SCIP_Bool silent;
1143 SCIP_Bool alldeletionssolved = TRUE;
1144 int nvars;
1145 int nconss;
1146 int maxbatchsize;
1147
1148 assert( scip != NULL );
1149
1150 if( !SCIPiisIsSubscipInfeasible(iis) )
1151 {
1152 SCIPerrorMessage("infeasible problem required\n");
1153 return SCIP_INVALIDDATA;
1154 }
1155
1157 nconss = SCIPgetNOrigConss(scip);
1158 maxbatchsize = MAX(nvars, nconss);
1159
1160 SCIP_CALL( SCIPgetRealParam(scip, "iis/time", &timelim) );
1161 SCIP_CALL( SCIPgetLongintParam(scip, "iis/nodes", &nodelim) );
1162 SCIP_CALL( SCIPgetBoolParam(scip, "iis/removebounds", &removebounds) );
1163 SCIP_CALL( SCIPgetBoolParam(scip, "iis/silent", &silent) );
1164
1165 SCIP_CALL( deletionFilterBatch(iis, timelim, nodelim, removebounds, silent,
1168 if( alldeletionssolved && SCIPiisGetTime(iis) < timelim && ( nodelim == -1 || SCIPiisGetNNodes(iis) < nodelim ) )
1170
1171 return SCIP_OKAY;
1172}
#define NULL
Definition def.h:255
#define SCIP_Longint
Definition def.h:148
#define SCIP_REAL_MAX
Definition def.h:165
#define SCIP_INVALID
Definition def.h:185
#define SCIP_Bool
Definition def.h:98
#define MIN(x, y)
Definition def.h:231
#define SCIP_Real
Definition def.h:163
#define TRUE
Definition def.h:100
#define FALSE
Definition def.h:101
#define MAX(x, y)
Definition def.h:227
#define SCIP_REAL_MIN
Definition def.h:166
#define SCIP_LONGINT_MAX
Definition def.h:149
#define SCIP_CALL(x)
Definition def.h:362
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
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:314
SCIP_IISFINDERDATA * SCIPiisfinderGetData(SCIP_IISFINDER *iisfinder)
Definition iisfinder.c:653
void SCIPiisfinderSetData(SCIP_IISFINDER *iisfinder, SCIP_IISFINDERDATA *iisfinderdata)
Definition iisfinder.c:663
void SCIPiisfinderInfoMessage(SCIP_IIS *iis, SCIP_Bool printheaders)
Definition iisfinder.c:741
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:950
void SCIPiisAddNNodes(SCIP_IIS *iis, SCIP_Longint nnodes)
Definition iisfinder.c:940
SCIP * SCIPiisGetSubscip(SCIP_IIS *iis)
Definition iisfinder.c:959
void SCIPiisSetSubscipIrreducible(SCIP_IIS *iis, SCIP_Bool irreducible)
Definition iisfinder.c:930
SCIP_Longint SCIPiisGetNNodes(SCIP_IIS *iis)
Definition iisfinder.c:910
SCIP_Real SCIPiisGetTime(SCIP_IIS *iis)
Definition iisfinder.c:880
SCIP_Bool SCIPiisIsSubscipInfeasible(SCIP_IIS *iis)
Definition iisfinder.c:890
void SCIPiisSetSubscipInfeasible(SCIP_IIS *iis, SCIP_Bool infeasible)
Definition iisfinder.c:920
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:110
#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:2988
SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:1506
SCIP_RETCODE SCIPcreateSolCopyOrig(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol)
Definition scip_sol.c:924
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:24021
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:23454
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition var.c:24064
return SCIP_OKAY
SCIPfreeSol(scip, &heurdata->sol))
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
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_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_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