Scippy

SCIP

Solving Constraint Integer Programs

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-2025 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file 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 {
260 SCIP_CALL( SCIPchgVarLb(scip, vars[idxs[i]], -SCIPinfinity(scip)) );
261 chgmade = TRUE;
262 }
263 }
264 else
265 {
266 bounds[i] = SCIPvarGetUbOriginal(vars[idxs[i]]);
267 if( !SCIPisInfinity(scip, bounds[i]) )
268 {
269 SCIP_CALL( SCIPchgVarUb(scip, vars[idxs[i]], SCIPinfinity(scip)) );
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;
521 int iteration;
522 int i;
523 int k;
524
525 /* get current subscip */
526 scip = SCIPiisGetSubscip(iis);
527 assert( scip != NULL );
528 assert( SCIPiisIsSubscipInfeasible(iis) );
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
611 nvars = SCIPgetNOrigVars(scip);
612 origvars = SCIPgetOrigVars(scip);
613 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &vars, origvars, nvars) );
614
615 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &order, nvars) );
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 {
633 if( (SCIPvarGetType(vars[order[i]]) != SCIP_VARTYPE_BINARY) && (!SCIPisInfinity(scip, -SCIPvarGetLbOriginal(vars[order[i]])) || !SCIPisInfinity(scip, SCIPvarGetUbOriginal(vars[order[i]]))) )
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
667 SCIPfreeBlockMemoryArray(scip, &order, nvars);
668 SCIPfreeBlockMemoryArray(scip, &vars, nvars);
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;
705 SCIP_RESULT result;
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 );
716 assert( SCIPiisIsSubscipInfeasible(iis) );
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( !silent )
792 if( !feasible || stopiter || timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) )
793 {
795 break;
796 }
797
798 if( dynamicreordering && retcode == SCIP_OKAY )
799 {
800 /* free transform and copy solution if there is one */
801 copysol = NULL;
802 sol = SCIPgetBestSol(scip);
803 if( sol != NULL )
804 {
805 SCIP_CALL( SCIPcreateSolCopyOrig(scip, &copysol, sol) );
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 if( k > 0 )
832 {
833 SCIPdebugMsg(scip, "Added %d constraints by reordering dynamically.\n", k);
834 if( ! silent )
836 }
837 SCIP_CALL( SCIPfreeSol(scip, &copysol) );
838 }
839 }
840 else
841 {
844 }
845
846 ++iteration;
847
848 /* update batchsize */
849 SCIP_CALL( updateBatchsize(scip, initbatchsize, maxbatchsize, iteration, FALSE, batchingfactor, batchingoffset, batchupdateinterval, &batchsize) );
850 }
851
852 /* Release any cons not in the IS */
853 for( i = 0; i < nconss; ++i )
854 {
855 if( !inIS[order[i]] )
856 {
857 SCIP_CALL( SCIPreleaseCons(scip, &conss[order[i]]) );
858 }
859 }
860
861 SCIPfreeBlockMemoryArray(scip, &order, nconss);
862 SCIPfreeBlockMemoryArray(scip, &inIS, nconss);
863 SCIPfreeBlockMemoryArray(scip, &conss, nconss);
864 if( feasible )
866 else
868
869 return SCIP_OKAY;
870}
871
872/** perform a greedy addition or deletion algorithm to obtain an infeasible subsystem (IS).
873 *
874 * This is the generation method for the greedy IIS finder rule.
875 * Depending on the parameter choices, constraints are either greedily added from an empty problem,
876 * or deleted from a complete problem. In the case of constraints being added, this is done until the problem
877 * becomes infeasible, after which one can then begin deleting constraints. In the case of deleting constraints,
878 * this is done until no more constraints (or batches of constraints) can be deleted without making
879 * the problem feasible.
880 */
881static
883 SCIP_IIS* iis, /**< IIS data structure */
884 SCIP_IISFINDERDATA* iisfinderdata, /**< IIS finder data */
885 SCIP_RESULT* result /**< pointer to store the result of the IIS finder run. SCIP_DIDNOTFIND if the algorithm failed, otherwise SCIP_SUCCESS. */
886 )
887{
889 SCIP_Real timelim;
890 SCIP_Longint nodelim;
891 SCIP_Bool removebounds;
892 SCIP_Bool silent;
893 SCIP_Bool alldeletionssolved = TRUE;
894 int nvars;
895 int nconss;
896 int maxbatchsize;
897 int initbatchsize;
898
899 assert( scip != NULL );
900 assert( iisfinderdata != NULL );
901 assert( result != NULL );
902
903 SCIP_CALL( SCIPgetRealParam(scip, "iis/time", &timelim) );
904 SCIP_CALL( SCIPgetLongintParam(scip, "iis/nodes", &nodelim) );
905 SCIP_CALL( SCIPgetBoolParam(scip, "iis/removebounds", &removebounds) );
906 SCIP_CALL( SCIPgetBoolParam(scip, "iis/silent", &silent) );
907
908 nvars = SCIPgetNOrigVars(scip);
909 nconss = SCIPgetNOrigConss(scip);
910 maxbatchsize = MAX(nvars, nconss);
911 initbatchsize = iisfinderdata->initrelbatchsize > 0.0
912 ? (int)ceil(iisfinderdata->initrelbatchsize * maxbatchsize) : MIN(iisfinderdata->initbatchsize, maxbatchsize);
913 maxbatchsize = (int)ceil(iisfinderdata->maxrelbatchsize * maxbatchsize);
914 maxbatchsize = MIN(iisfinderdata->maxbatchsize, maxbatchsize);
915 initbatchsize = MAX(initbatchsize, 1);
916 maxbatchsize = MAX(maxbatchsize, 1);
917
918 *result = SCIP_SUCCESS;
919
920 if( iisfinderdata->additive )
921 {
922 if( !silent )
923 {
924 SCIPdebugMsg(scip, "----- STARTING GREEDY ADDITION ALGORITHM -----\n");
925 }
926 SCIP_CALL( additionFilterBatch(iis, timelim, nodelim, silent, iisfinderdata->timelimperiter,
927 iisfinderdata->nodelimperiter, iisfinderdata->dynamicreordering, initbatchsize, maxbatchsize,
928 iisfinderdata->batchingfactor, iisfinderdata->batchingoffset, iisfinderdata->batchupdateinterval) );
930 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) )
931 return SCIP_OKAY;
932 }
933 else
934 {
935 if( !silent )
936 {
937 SCIPdebugMsg(scip, "----- STARTING GREEDY DELETION ALGORITHM -----\n");
938 }
939 SCIP_CALL( deletionFilterBatch(iis, timelim, nodelim, removebounds, silent, iisfinderdata->timelimperiter,
940 iisfinderdata->nodelimperiter, iisfinderdata->conservative, initbatchsize, maxbatchsize,
941 iisfinderdata->batchingfactor, iisfinderdata->batchingoffset, iisfinderdata->batchupdateinterval,
942 &alldeletionssolved) );
943 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) )
944 return SCIP_OKAY;
945 if( alldeletionssolved && initbatchsize == 1 )
947 }
948
949 if( iisfinderdata->delafteradd && iisfinderdata->additive )
950 {
951 if( !silent )
952 {
953 SCIPdebugMsg(scip, "----- STARTING GREEDY DELETION ALGORITHM FOLLOWING COMPLETED ADDITION ALGORITHM -----\n");
954 }
955 SCIP_CALL( deletionFilterBatch(iis, timelim, nodelim, removebounds, silent, iisfinderdata->timelimperiter,
956 iisfinderdata->nodelimperiter, iisfinderdata->conservative, initbatchsize, maxbatchsize,
957 iisfinderdata->batchingfactor, iisfinderdata->batchingoffset, iisfinderdata->batchupdateinterval,
958 &alldeletionssolved) );
959 if( timelim - SCIPiisGetTime(iis) <= 0 || ( nodelim != -1 && SCIPiisGetNNodes(iis) >= nodelim ) )
960 return SCIP_OKAY;
961 if( alldeletionssolved && initbatchsize == 1 )
963 }
964
965 return SCIP_OKAY;
966}
967
968
969/*
970 * Callback methods of IIS finder
971 */
972
973
974/** copy method for IIS finder plugin (called when SCIP copies plugins) */
975static
976SCIP_DECL_IISFINDERCOPY(iisfinderCopyGreedy)
977{ /*lint --e{715}*/
978 assert(scip != NULL);
979 assert(iisfinder != NULL);
980 assert(strcmp(SCIPiisfinderGetName(iisfinder), IISFINDER_NAME) == 0);
981
982 /* call inclusion method of IIS finder */
984
985 return SCIP_OKAY;
986}
987
988/** destructor of IIS finder to free user data (called when SCIP is exiting) */
989/**! [SnippetIISfinderFreeGreedy] */
990static
991SCIP_DECL_IISFINDERFREE(iisfinderFreeGreedy)
992{ /*lint --e{715}*/
993 SCIP_IISFINDERDATA* iisfinderdata;
994
995 iisfinderdata = SCIPiisfinderGetData(iisfinder);
996
997 SCIPfreeBlockMemory(scip, &iisfinderdata);
998
999 SCIPiisfinderSetData(iisfinder, NULL);
1000
1001 return SCIP_OKAY;
1002}
1003/**! [SnippetIISfinderFreeGreedy] */
1004
1005/** IIS finder generation method of IIS */
1006static
1007SCIP_DECL_IISFINDEREXEC(iisfinderExecGreedy)
1008{ /*lint --e{715}*/
1009 SCIP_IISFINDERDATA* iisfinderdata;
1010
1011 assert(iisfinder != NULL);
1012 assert(result != NULL);
1013
1014 *result = SCIP_DIDNOTFIND;
1015
1016 iisfinderdata = SCIPiisfinderGetData(iisfinder);
1017 assert(iisfinderdata != NULL);
1018
1019 SCIP_CALL( execIISfinderGreedy(iis, iisfinderdata, result) );
1020
1021 return SCIP_OKAY;
1022}
1023
1024
1025/*
1026 * IIS finder specific interface methods
1027 */
1028
1029/** creates the greedy IIS finder and includes it in SCIP */
1031 SCIP* scip /**< SCIP data structure */
1032 )
1033{
1034 SCIP_IISFINDERDATA* iisfinderdata;
1035 SCIP_IISFINDER* iisfinder;
1036
1037 /* create greedy IIS finder data */
1038 SCIP_CALL( SCIPallocBlockMemory(scip, &iisfinderdata) );
1039 BMSclearMemory(iisfinderdata);
1040
1042 iisfinderExecGreedy, iisfinderdata) );
1043
1044 assert(iisfinder != NULL);
1045
1046 /* set non fundamental callbacks via setter functions */
1047 SCIP_CALL( SCIPsetIISfinderCopy(scip, iisfinder, iisfinderCopyGreedy) );
1048 SCIP_CALL( SCIPsetIISfinderFree(scip, iisfinder, iisfinderFreeGreedy) );
1049
1050 /* add greedy IIS finder parameters */
1052 "iis/" IISFINDER_NAME "/timelimperiter",
1053 "time limit of optimization process for each individual subproblem",
1054 &iisfinderdata->timelimperiter, FALSE, DEFAULT_TIMELIMPERITER, 0.0, SCIP_INVALID/10.0, NULL, NULL) );
1055
1057 "iis/" IISFINDER_NAME "/nodelimperiter",
1058 "node limit of optimization process for each individual subproblem",
1059 &iisfinderdata->nodelimperiter, FALSE, DEFAULT_NODELIMPERITER, -1L, SCIP_LONGINT_MAX, NULL, NULL) );
1060
1062 "iis/" IISFINDER_NAME "/additive",
1063 "should an additive constraint approach be used instead of deletion",
1064 &iisfinderdata->additive, FALSE, DEFAULT_ADDITIVE, NULL, NULL) );
1065
1067 "iis/" IISFINDER_NAME "/conservative",
1068 "should an unsolved problem (by e.g. user interrupt, node limit, time limit) be considered feasible when deleting constraints",
1069 &iisfinderdata->conservative, TRUE, DEFAULT_CONSERVATIVE, NULL, NULL) );
1070
1072 "iis/" IISFINDER_NAME "/delafteradd",
1073 "should the deletion routine be performed after the addition routine (in the case of additive)",
1074 &iisfinderdata->delafteradd, TRUE, DEFAULT_DELAFTERADD, NULL, NULL) );
1075
1077 "iis/" IISFINDER_NAME "/dynamicreordering",
1078 "should satisfied constraints outside the batch of an intermediate solve be added during the additive method",
1079 &iisfinderdata->dynamicreordering, TRUE, DEFAULT_DYNAMICREORDERING, NULL, NULL) );
1080
1082 "iis/" IISFINDER_NAME "/initbatchsize",
1083 "the initial batchsize for the first iteration, ignored if initrelbatchsize is positive",
1084 &iisfinderdata->initbatchsize, FALSE, DEFAULT_INITBATCHSIZE, 1, INT_MAX, NULL, NULL) );
1085
1087 "iis/" IISFINDER_NAME "/initrelbatchsize",
1088 "the initial batchsize relative to the original problem for the first iteration (0.0: use initbatchsize)",
1089 &iisfinderdata->initrelbatchsize, FALSE, DEFAULT_INITRELBATCHSIZE, 0.0, 1.0, NULL, NULL) );
1090
1092 "iis/" IISFINDER_NAME "/maxbatchsize",
1093 "the maximum batchsize per iteration",
1094 &iisfinderdata->maxbatchsize, TRUE, DEFAULT_MAXBATCHSIZE, 1, INT_MAX, NULL, NULL) );
1095
1097 "iis/" IISFINDER_NAME "/maxrelbatchsize",
1098 "the maximum batchsize relative to the original problem per iteration",
1099 &iisfinderdata->maxrelbatchsize, TRUE, DEFAULT_MAXRELBATCHSIZE, 0.0, 1.0, NULL, NULL) );
1100
1102 "iis/" IISFINDER_NAME "/batchingfactor",
1103 "the factor with which the batchsize is multiplied in every update",
1104 &iisfinderdata->batchingfactor, TRUE, DEFAULT_BATCHINGFACTOR, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1105
1107 "iis/" IISFINDER_NAME "/batchingoffset",
1108 "the offset which is added to the multiplied batchsize in every update",
1109 &iisfinderdata->batchingoffset, TRUE, DEFAULT_BATCHINGOFFSET, SCIP_REAL_MIN, SCIP_REAL_MAX, NULL, NULL) );
1110
1112 "iis/" IISFINDER_NAME "/batchupdateinterval",
1113 "the number of iterations to run with a constant batchsize before updating (1: always update)",
1114 &iisfinderdata->batchupdateinterval, TRUE, DEFAULT_BATCHUPDATEINTERVAL, 1, INT_MAX, NULL, NULL) );
1115
1116 return SCIP_OKAY;
1117}
1118
1119/** perform the greedy deletion algorithm with singleton batches to obtain an irreducible infeasible subsystem (IIS) */
1121 SCIP_IIS* iis /**< IIS data structure */
1122 )
1123{
1124 SCIP* scip = SCIPiisGetSubscip(iis);
1125 SCIP_Real timelim;
1126 SCIP_Longint nodelim;
1127 SCIP_Bool removebounds;
1128 SCIP_Bool silent;
1129 SCIP_Bool alldeletionssolved = TRUE;
1130 int nvars;
1131 int nconss;
1132 int maxbatchsize;
1133
1134 assert( scip != NULL );
1135
1136 if( !SCIPiisIsSubscipInfeasible(iis) )
1137 {
1138 SCIPerrorMessage("infeasible problem required\n");
1139 return SCIP_INVALIDDATA;
1140 }
1141
1142 nvars = SCIPgetNOrigVars(scip);
1143 nconss = SCIPgetNOrigConss(scip);
1144 maxbatchsize = MAX(nvars, nconss);
1145
1146 SCIP_CALL( SCIPgetRealParam(scip, "iis/time", &timelim) );
1147 SCIP_CALL( SCIPgetLongintParam(scip, "iis/nodes", &nodelim) );
1148 SCIP_CALL( SCIPgetBoolParam(scip, "iis/removebounds", &removebounds) );
1149 SCIP_CALL( SCIPgetBoolParam(scip, "iis/silent", &silent) );
1150
1151 SCIP_CALL( deletionFilterBatch(iis, timelim, nodelim, removebounds, silent,
1154 if( alldeletionssolved && SCIPiisGetTime(iis) < timelim && ( nodelim == -1 || SCIPiisGetNNodes(iis) < nodelim ) )
1156
1157 return SCIP_OKAY;
1158}
#define NULL
Definition: def.h:248
#define SCIP_Longint
Definition: def.h:141
#define SCIP_REAL_MAX
Definition: def.h:158
#define SCIP_INVALID
Definition: def.h:178
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:224
#define SCIP_Real
Definition: def.h:156
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:220
#define SCIP_REAL_MIN
Definition: def.h:159
#define SCIP_LONGINT_MAX
Definition: def.h:142
#define SCIP_CALL(x)
Definition: def.h:355
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip_general.c:562
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:444
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
Definition: scip_message.h:78
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:4316
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:8409
SCIP_Bool SCIPconsIsInProb(SCIP_CONS *cons)
Definition: cons.c:8678
int SCIPconsGetNUses(SCIP_CONS *cons)
Definition: cons.c:8429
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_RANDNUMGEN * SCIPiisGetRandnumgen(SCIP_IIS *iis)
Definition: iisfinder.c:922
SCIP_RETCODE SCIPsetIISfinderCopy(SCIP *scip, SCIP_IISFINDER *iisfinder, SCIP_DECL_IISFINDERCOPY((*iisfindercopy)))
void SCIPiisAddNNodes(SCIP_IIS *iis, SCIP_Longint nnodes)
Definition: iisfinder.c:912
SCIP * SCIPiisGetSubscip(SCIP_IIS *iis)
Definition: iisfinder.c:931
const char * SCIPiisfinderGetName(SCIP_IISFINDER *iisfinder)
Definition: iisfinder.c:311
void SCIPiisSetSubscipIrreducible(SCIP_IIS *iis, SCIP_Bool irreducible)
Definition: iisfinder.c:902
SCIP_Longint SCIPiisGetNNodes(SCIP_IIS *iis)
Definition: iisfinder.c:882
SCIP_IISFINDERDATA * SCIPiisfinderGetData(SCIP_IISFINDER *iisfinder)
Definition: iisfinder.c:625
void SCIPiisfinderSetData(SCIP_IISFINDER *iisfinder, SCIP_IISFINDERDATA *iisfinderdata)
Definition: iisfinder.c:635
SCIP_Real SCIPiisGetTime(SCIP_IIS *iis)
Definition: iisfinder.c:852
void SCIPiisfinderInfoMessage(SCIP_IIS *iis, SCIP_Bool printheaders)
Definition: iisfinder.c:713
SCIP_Bool SCIPiisIsSubscipInfeasible(SCIP_IIS *iis)
Definition: iisfinder.c:862
void SCIPiisSetSubscipInfeasible(SCIP_IIS *iis, SCIP_Bool infeasible)
Definition: iisfinder.c:892
SCIP_RETCODE SCIPincludeIISfinderBasic(SCIP *scip, SCIP_IISFINDER **iisfinder, const char *name, const char *desc, int priority, SCIP_DECL_IISFINDEREXEC((*iisfinderexec)), SCIP_IISFINDERDATA *iisfinderdata)
SCIP_RETCODE SCIPsetIISfinderFree(SCIP *scip, SCIP_IISFINDER *iisfinder, SCIP_DECL_IISFINDERFREE((*iisfinderfree)))
#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:2981
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:1252
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)
Definition: scip_solve.c:3462
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip_solve.c:2635
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:24020
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:23453
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition: var.c:24063
#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)
static SCIP_DECL_IISFINDERFREE(iisfinderFreeGreedy)
#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)
static SCIP_DECL_IISFINDERCOPY(iisfinderCopyGreedy)
static SCIP_DECL_IISFINDEREXEC(iisfinderExecGreedy)
#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_IISfinderData SCIP_IISFINDERDATA
@ 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
Definition: type_retcode.h:52
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_ERROR
Definition: type_retcode.h:43
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_STAGE_PROBLEM
Definition: type_set.h:45
@ 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
@ SCIP_VARTYPE_BINARY
Definition: type_var.h:64