Scippy

SCIP

Solving Constraint Integer Programs

presol.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-2014 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file presol.c
17  * @brief methods for presolvers
18  * @author Tobias Achterberg
19  * @author Timo Berthold
20  */
21 
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
23 
24 #include <assert.h>
25 #include <string.h>
26 
27 #include "scip/def.h"
28 #include "blockmemshell/memory.h"
29 #include "scip/set.h"
30 #include "scip/clock.h"
31 #include "scip/paramset.h"
32 #include "scip/scip.h"
33 #include "scip/pub_misc.h"
34 #include "scip/presol.h"
35 
36 #include "scip/struct_presol.h"
37 
38 
39 
40 /*
41  * presolver methods
42  */
43 
44 /** compares two presolvers w. r. to their priority */
45 SCIP_DECL_SORTPTRCOMP(SCIPpresolComp)
46 { /*lint --e{715}*/
47  return ((SCIP_PRESOL*)elem2)->priority - ((SCIP_PRESOL*)elem1)->priority;
48 }
49 
50 /** comparison method for sorting presolvers w.r.t. to their name */
51 SCIP_DECL_SORTPTRCOMP(SCIPpresolCompName)
52 {
53  return strcmp(SCIPpresolGetName((SCIP_PRESOL*)elem1), SCIPpresolGetName((SCIP_PRESOL*)elem2));
54 }
55 
56 /** method to call, when the priority of a presolver was changed */
57 static
58 SCIP_DECL_PARAMCHGD(paramChgdPresolPriority)
59 { /*lint --e{715}*/
60  SCIP_PARAMDATA* paramdata;
61 
62  paramdata = SCIPparamGetData(param);
63  assert(paramdata != NULL);
64 
65  /* use SCIPsetPresolPriority() to mark the presols unsorted */
66  SCIP_CALL( SCIPsetPresolPriority(scip, (SCIP_PRESOL*)paramdata, SCIPparamGetInt(param)) ); /*lint !e740*/
67 
68  return SCIP_OKAY;
69 }
70 
71 /** copies the given presolver to a new scip */
73  SCIP_PRESOL* presol, /**< presolver */
74  SCIP_SET* set /**< SCIP_SET of SCIP to copy to */
75  )
76 {
77  assert(presol != NULL);
78  assert(set != NULL);
79  assert(set->scip != NULL);
80 
81  if( presol->presolcopy != NULL )
82  {
83  SCIPdebugMessage("including presolver %s in subscip %p\n", SCIPpresolGetName(presol), (void*)set->scip);
84  SCIP_CALL( presol->presolcopy(set->scip, presol) );
85  }
86  return SCIP_OKAY;
87 }
88 
89 /** creates a presolver */
91  SCIP_PRESOL** presol, /**< pointer to store presolver */
92  SCIP_SET* set, /**< global SCIP settings */
93  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */
94  BMS_BLKMEM* blkmem, /**< block memory for parameter settings */
95  const char* name, /**< name of presolver */
96  const char* desc, /**< description of presolver */
97  int priority, /**< priority of the presolver (>= 0: before, < 0: after constraint handlers) */
98  int maxrounds, /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
99  SCIP_Bool delay, /**< should presolver be delayed, if other presolvers found reductions? */
100  SCIP_DECL_PRESOLCOPY ((*presolcopy)), /**< copy method of presolver or NULL if you don't want to copy your plugin into sub-SCIPs */
101  SCIP_DECL_PRESOLFREE ((*presolfree)), /**< destructor of presolver to free user data (called when SCIP is exiting) */
102  SCIP_DECL_PRESOLINIT ((*presolinit)), /**< initialization method of presolver (called after problem was transformed) */
103  SCIP_DECL_PRESOLEXIT ((*presolexit)), /**< deinitialization method of presolver (called before transformed problem is freed) */
104  SCIP_DECL_PRESOLINITPRE((*presolinitpre)),/**< presolving initialization method of presolver (called when presolving is about to begin) */
105  SCIP_DECL_PRESOLEXITPRE((*presolexitpre)),/**< presolving deinitialization method of presolver (called after presolving has been finished) */
106  SCIP_DECL_PRESOLEXEC ((*presolexec)), /**< execution method of presolver */
107  SCIP_PRESOLDATA* presoldata /**< presolver data */
108  )
109 {
111  char paramdesc[SCIP_MAXSTRLEN];
112 
113  assert(presol != NULL);
114  assert(name != NULL);
115  assert(desc != NULL);
116 
117  SCIP_ALLOC( BMSallocMemory(presol) );
118  SCIP_ALLOC( BMSduplicateMemoryArray(&(*presol)->name, name, strlen(name)+1) );
119  SCIP_ALLOC( BMSduplicateMemoryArray(&(*presol)->desc, desc, strlen(desc)+1) );
120  (*presol)->presolcopy = presolcopy;
121  (*presol)->presolfree = presolfree;
122  (*presol)->presolinit = presolinit;
123  (*presol)->presolexit = presolexit;
124  (*presol)->presolinitpre = presolinitpre;
125  (*presol)->presolexitpre = presolexitpre;
126  (*presol)->presolexec = presolexec;
127  (*presol)->presoldata = presoldata;
128  SCIP_CALL( SCIPclockCreate(&(*presol)->setuptime, SCIP_CLOCKTYPE_DEFAULT) );
129  SCIP_CALL( SCIPclockCreate(&(*presol)->presolclock, SCIP_CLOCKTYPE_DEFAULT) );
130  (*presol)->wasdelayed = FALSE;
131  (*presol)->initialized = FALSE;
132 
133  /* add parameters */
134  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "presolving/%s/priority", name);
135  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of presolver <%s>", name);
136  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc,
137  &(*presol)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4,
138  paramChgdPresolPriority, (SCIP_PARAMDATA*)(*presol)) ); /*lint !e740*/
139 
140  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "presolving/%s/maxrounds", name);
141  SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname,
142  "maximal number of presolving rounds the presolver participates in (-1: no limit)",
143  &(*presol)->maxrounds, FALSE, maxrounds, -1, INT_MAX, NULL, NULL) ); /*lint !e740*/
144 
145  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "presolving/%s/delay", name);
146  SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname,
147  "should presolver be delayed, if other presolvers found reductions?",
148  &(*presol)->delay, TRUE, delay, NULL, NULL) ); /*lint !e740*/
149 
150  return SCIP_OKAY;
151 }
152 
153 /** frees memory of presolver */
155  SCIP_PRESOL** presol, /**< pointer to presolver data structure */
156  SCIP_SET* set /**< global SCIP settings */
157  )
158 {
159  assert(presol != NULL);
160  assert(*presol != NULL);
161  assert(!(*presol)->initialized);
162  assert(set != NULL);
163 
164  /* call destructor of presolver */
165  if( (*presol)->presolfree != NULL )
166  {
167  SCIP_CALL( (*presol)->presolfree(set->scip, *presol) );
168  }
169 
170  SCIPclockFree(&(*presol)->presolclock);
171  SCIPclockFree(&(*presol)->setuptime);
172  BMSfreeMemoryArray(&(*presol)->name);
173  BMSfreeMemoryArray(&(*presol)->desc);
174  BMSfreeMemory(presol);
175 
176  return SCIP_OKAY;
177 }
178 
179 /** initializes presolver */
181  SCIP_PRESOL* presol, /**< presolver */
182  SCIP_SET* set /**< global SCIP settings */
183  )
184 {
185  assert(presol != NULL);
186  assert(set != NULL);
187 
188  if( presol->initialized )
189  {
190  SCIPerrorMessage("presolver <%s> already initialized\n", presol->name);
191  return SCIP_INVALIDCALL;
192  }
193 
194  if( set->misc_resetstat )
195  {
196  SCIPclockReset(presol->setuptime);
197  SCIPclockReset(presol->presolclock);
198 
199  presol->lastnfixedvars = 0;
200  presol->lastnaggrvars = 0;
201  presol->lastnchgvartypes = 0;
202  presol->lastnchgbds = 0;
203  presol->lastnaddholes = 0;
204  presol->lastndelconss = 0;
205  presol->lastnaddconss = 0;
206  presol->lastnupgdconss = 0;
207  presol->lastnchgcoefs = 0;
208  presol->lastnchgsides = 0;
209  presol->nfixedvars = 0;
210  presol->naggrvars = 0;
211  presol->nchgvartypes = 0;
212  presol->nchgbds = 0;
213  presol->naddholes = 0;
214  presol->ndelconss = 0;
215  presol->naddconss = 0;
216  presol->nupgdconss = 0;
217  presol->nchgcoefs = 0;
218  presol->nchgsides = 0;
219  presol->ncalls = 0;
220  presol->wasdelayed = FALSE;
221  }
222 
223  /* call initialization method of presolver */
224  if( presol->presolinit != NULL )
225  {
226  /* start timing */
227  SCIPclockStart(presol->setuptime, set);
228 
229  SCIP_CALL( presol->presolinit(set->scip, presol) );
230 
231  /* stop timing */
232  SCIPclockStop(presol->setuptime, set);
233  }
234  presol->initialized = TRUE;
235 
236  return SCIP_OKAY;
237 }
238 
239 /** deinitializes presolver */
241  SCIP_PRESOL* presol, /**< presolver */
242  SCIP_SET* set /**< global SCIP settings */
243  )
244 {
245  assert(presol != NULL);
246  assert(set != NULL);
247 
248  if( !presol->initialized )
249  {
250  SCIPerrorMessage("presolver <%s> not initialized\n", presol->name);
251  return SCIP_INVALIDCALL;
252  }
253 
254  /* call deinitialization method of presolver */
255  if( presol->presolexit != NULL )
256  {
257  /* start timing */
258  SCIPclockStart(presol->setuptime, set);
259 
260  SCIP_CALL( presol->presolexit(set->scip, presol) );
261 
262  /* stop timing */
263  SCIPclockStop(presol->setuptime, set);
264  }
265  presol->initialized = FALSE;
266 
267  return SCIP_OKAY;
268 }
269 
270 /** informs presolver that the presolving process is being started */
272  SCIP_PRESOL* presol, /**< presolver */
273  SCIP_SET* set /**< global SCIP settings */
274  )
275 {
276  assert(presol != NULL);
277  assert(set != NULL);
278 
279  presol->lastnfixedvars = 0;
280  presol->lastnaggrvars = 0;
281  presol->lastnchgvartypes = 0;
282  presol->lastnchgbds = 0;
283  presol->lastnaddholes = 0;
284  presol->lastndelconss = 0;
285  presol->lastnaddconss = 0;
286  presol->lastnupgdconss = 0;
287  presol->lastnchgcoefs = 0;
288  presol->lastnchgsides = 0;
289  presol->wasdelayed = FALSE;
290 
291  /* call presolving initialization method of presolver */
292  if( presol->presolinitpre != NULL )
293  {
294  /* start timing */
295  SCIPclockStart(presol->setuptime, set);
296 
297  SCIP_CALL( presol->presolinitpre(set->scip, presol) );
298 
299  /* stop timing */
300  SCIPclockStop(presol->setuptime, set);
301  }
302 
303  return SCIP_OKAY;
304 }
305 
306 /** informs presolver that the presolving process is finished */
308  SCIP_PRESOL* presol, /**< presolver */
309  SCIP_SET* set /**< global SCIP settings */
310  )
311 {
312  assert(presol != NULL);
313  assert(set != NULL);
314 
315  /* call presolving deinitialization method of presolver */
316  if( presol->presolexitpre != NULL )
317  {
318  /* start timing */
319  SCIPclockStart(presol->setuptime, set);
320 
321  SCIP_CALL( presol->presolexitpre(set->scip, presol) );
322 
323  /* stop timing */
324  SCIPclockStop(presol->setuptime, set);
325  }
326 
327  return SCIP_OKAY;
328 }
329 
330 /** executes presolver */
332  SCIP_PRESOL* presol, /**< presolver */
333  SCIP_SET* set, /**< global SCIP settings */
334  SCIP_Bool execdelayed, /**< execute presolver even if it is marked to be delayed */
335  int nrounds, /**< number of presolving rounds already done */
336  int* nfixedvars, /**< pointer to total number of variables fixed of all presolvers */
337  int* naggrvars, /**< pointer to total number of variables aggregated of all presolvers */
338  int* nchgvartypes, /**< pointer to total number of variable type changes of all presolvers */
339  int* nchgbds, /**< pointer to total number of variable bounds tightened of all presolvers */
340  int* naddholes, /**< pointer to total number of domain holes added of all presolvers */
341  int* ndelconss, /**< pointer to total number of deleted constraints of all presolvers */
342  int* naddconss, /**< pointer to total number of added constraints of all presolvers */
343  int* nupgdconss, /**< pointer to total number of upgraded constraints of all presolvers */
344  int* nchgcoefs, /**< pointer to total number of changed coefficients of all presolvers */
345  int* nchgsides, /**< pointer to total number of changed left/right hand sides of all presolvers */
346  SCIP_RESULT* result /**< pointer to store the result of the callback method */
347  )
348 {
349  int nnewfixedvars;
350  int nnewaggrvars;
351  int nnewchgvartypes;
352  int nnewchgbds;
353  int nnewaddholes;
354  int nnewdelconss;
355  int nnewaddconss;
356  int nnewupgdconss;
357  int nnewchgcoefs;
358  int nnewchgsides;
359 
360  assert(presol != NULL);
361  assert(presol->presolexec != NULL);
362  assert(set != NULL);
363  assert(nfixedvars != NULL);
364  assert(naggrvars != NULL);
365  assert(nchgvartypes != NULL);
366  assert(nchgbds != NULL);
367  assert(naddholes != NULL);
368  assert(ndelconss != NULL);
369  assert(naddconss != NULL);
370  assert(nupgdconss != NULL);
371  assert(nchgcoefs != NULL);
372  assert(nchgsides != NULL);
373  assert(result != NULL);
374 
375  *result = SCIP_DIDNOTRUN;
376 
377  /* check number of presolving rounds */
378  if( presol->maxrounds >= 0 && nrounds >= presol->maxrounds && !presol->wasdelayed )
379  return SCIP_OKAY;
380 
381  /* calculate the number of changes since last call */
382  nnewfixedvars = *nfixedvars - presol->lastnfixedvars;
383  nnewaggrvars = *naggrvars - presol->lastnaggrvars;
384  nnewchgvartypes = *nchgvartypes - presol->lastnchgvartypes;
385  nnewchgbds = *nchgbds - presol->lastnchgbds;
386  nnewaddholes = *naddholes - presol->lastnaddholes;
387  nnewdelconss = *ndelconss - presol->lastndelconss;
388  nnewaddconss = *naddconss - presol->lastnaddconss;
389  nnewupgdconss = *nupgdconss - presol->lastnupgdconss;
390  nnewchgcoefs = *nchgcoefs - presol->lastnchgcoefs;
391  nnewchgsides = *nchgsides - presol->lastnchgsides;
392 
393  /* remember the number of changes prior to the call of the presolver */
394  presol->lastnfixedvars = *nfixedvars;
395  presol->lastnaggrvars = *naggrvars;
396  presol->lastnchgvartypes = *nchgvartypes;
397  presol->lastnchgbds = *nchgbds;
398  presol->lastnaddholes = *naddholes;
399  presol->lastndelconss = *ndelconss;
400  presol->lastnaddconss = *naddconss;
401  presol->lastnupgdconss = *nupgdconss;
402  presol->lastnchgcoefs = *nchgcoefs;
403  presol->lastnchgsides = *nchgsides;
404 
405  /* check, if presolver should be delayed */
406  if( !presol->delay || execdelayed )
407  {
408  SCIPdebugMessage("calling presolver <%s>\n", presol->name);
409 
410  /* start timing */
411  SCIPclockStart(presol->presolclock, set);
412 
413  /* call external method */
414  SCIP_CALL( presol->presolexec(set->scip, presol, nrounds,
415  nnewfixedvars, nnewaggrvars, nnewchgvartypes, nnewchgbds, nnewaddholes,
416  nnewdelconss, nnewaddconss, nnewupgdconss, nnewchgcoefs, nnewchgsides,
417  nfixedvars, naggrvars, nchgvartypes, nchgbds, naddholes,
418  ndelconss, naddconss, nupgdconss, nchgcoefs, nchgsides, result) );
419 
420  /* stop timing */
421  SCIPclockStop(presol->presolclock, set);
422 
423  /* add/count the new changes */
424  presol->nfixedvars += *nfixedvars - presol->lastnfixedvars;
425  presol->naggrvars += *naggrvars - presol->lastnaggrvars;
426  presol->nchgvartypes += *nchgvartypes - presol->lastnchgvartypes;
427  presol->nchgbds += *nchgbds - presol->lastnchgbds;
428  presol->naddholes += *naddholes - presol->lastnaddholes;
429  presol->ndelconss += *ndelconss - presol->lastndelconss;
430  presol->naddconss += *naddconss - presol->lastnaddconss;
431  presol->nupgdconss += *nupgdconss - presol->lastnupgdconss;
432  presol->nchgcoefs += *nchgcoefs - presol->lastnchgcoefs;
433  presol->nchgsides += *nchgsides - presol->lastnchgsides;
434 
435  /* check result code of callback method */
436  if( *result != SCIP_CUTOFF
437  && *result != SCIP_UNBOUNDED
438  && *result != SCIP_SUCCESS
439  && *result != SCIP_DIDNOTFIND
440  && *result != SCIP_DIDNOTRUN
441  && *result != SCIP_DELAYED )
442  {
443  SCIPerrorMessage("presolver <%s> returned invalid result <%d>\n", presol->name, *result);
444  return SCIP_INVALIDRESULT;
445  }
446 
447  /* increase the number of calls, if the presolver tried to find reductions */
448  if( *result != SCIP_DIDNOTRUN && *result != SCIP_DELAYED )
449  ++(presol->ncalls);
450  }
451  else
452  {
453  SCIPdebugMessage("presolver <%s> was delayed\n", presol->name);
454  *result = SCIP_DELAYED;
455  }
456 
457  /* remember whether presolver was delayed */
458  presol->wasdelayed = (*result == SCIP_DELAYED);
459 
460  return SCIP_OKAY;
461 }
462 
463 /** gets user data of presolver */
465  SCIP_PRESOL* presol /**< presolver */
466  )
467 {
468  assert(presol != NULL);
469 
470  return presol->presoldata;
471 }
472 
473 /** sets user data of presolver; user has to free old data in advance! */
475  SCIP_PRESOL* presol, /**< presolver */
476  SCIP_PRESOLDATA* presoldata /**< new presolver user data */
477  )
478 {
479  assert(presol != NULL);
480 
481  presol->presoldata = presoldata;
482 }
483 
484 /** sets copy method of presolver */
486  SCIP_PRESOL* presol, /**< presolver */
487  SCIP_DECL_PRESOLCOPY ((*presolcopy)) /**< copy method of presolver or NULL if you don't want to copy your plugin into sub-SCIPs */
488  )
489 {
490  assert(presol != NULL);
491 
492  presol->presolcopy = presolcopy;
493 }
494 
495 /** sets destructor method of presolver */
497  SCIP_PRESOL* presol, /**< presolver */
498  SCIP_DECL_PRESOLFREE ((*presolfree)) /**< destructor of presolver */
499  )
500 {
501  assert(presol != NULL);
502 
503  presol->presolfree = presolfree;
504 }
505 
506 /** sets initialization method of presolver */
508  SCIP_PRESOL* presol, /**< presolver */
509  SCIP_DECL_PRESOLINIT ((*presolinit)) /**< initialize presolver */
510  )
511 {
512  assert(presol != NULL);
513 
514  presol->presolinit = presolinit;
515 }
516 
517 /** sets deinitialization method of presolver */
519  SCIP_PRESOL* presol, /**< presolver */
520  SCIP_DECL_PRESOLEXIT ((*presolexit)) /**< deinitialize presolver */
521  )
522 {
523  assert(presol != NULL);
524 
525  presol->presolexit = presolexit;
526 }
527 
528 /** sets solving process initialization method of presolver */
530  SCIP_PRESOL* presol, /**< presolver */
531  SCIP_DECL_PRESOLINITPRE ((*presolinitpre))/**< solving process initialization method of presolver */
532  )
533 {
534  assert(presol != NULL);
535 
536  presol->presolinitpre = presolinitpre;
537 }
538 
539 /** sets solving process deinitialization method of presolver */
541  SCIP_PRESOL* presol, /**< presolver */
542  SCIP_DECL_PRESOLEXITPRE ((*presolexitpre))/**< solving process deinitialization method of presolver */
543  )
544 {
545  assert(presol != NULL);
546 
547  presol->presolexitpre = presolexitpre;
548 }
549 
550 /** gets name of presolver */
551 const char* SCIPpresolGetName(
552  SCIP_PRESOL* presol /**< presolver */
553  )
554 {
555  assert(presol != NULL);
556 
557  return presol->name;
558 }
559 
560 /** gets description of presolver */
561 const char* SCIPpresolGetDesc(
562  SCIP_PRESOL* presol /**< presolver */
563  )
564 {
565  assert(presol != NULL);
566 
567  return presol->desc;
568 }
569 
570 /** gets priority of presolver */
572  SCIP_PRESOL* presol /**< presolver */
573  )
574 {
575  assert(presol != NULL);
576 
577  return presol->priority;
578 }
579 
580 /** sets priority of presolver */
582  SCIP_PRESOL* presol, /**< presolver */
583  SCIP_SET* set, /**< global SCIP settings */
584  int priority /**< new priority of the presolver */
585  )
586 {
587  assert(presol != NULL);
588  assert(set != NULL);
589 
590  presol->priority = priority;
591  set->presolssorted = FALSE;
592 }
593 
594 /** should presolver be delayed, if other presolvers found reductions? */
596  SCIP_PRESOL* presol /**< presolver */
597  )
598 {
599  assert(presol != NULL);
600 
601  return presol->delay;
602 }
603 
604 /** was presolver delayed at the last call? */
606  SCIP_PRESOL* presol /**< presolver */
607  )
608 {
609  assert(presol != NULL);
610 
611  return presol->wasdelayed;
612 }
613 
614 /** is presolver initialized? */
616  SCIP_PRESOL* presol /**< presolver */
617  )
618 {
619  assert(presol != NULL);
620 
621  return presol->initialized;
622 }
623 
624 /** gets time in seconds used in this presolver for setting up for next stages */
626  SCIP_PRESOL* presol /**< presolver */
627  )
628 {
629  assert(presol != NULL);
630 
631  return SCIPclockGetTime(presol->setuptime);
632 }
633 
634 /** gets time in seconds used in this presolver */
636  SCIP_PRESOL* presol /**< presolver */
637  )
638 {
639  assert(presol != NULL);
640 
641  return SCIPclockGetTime(presol->presolclock);
642 }
643 
644 /** gets number of variables fixed in presolver */
646  SCIP_PRESOL* presol /**< presolver */
647  )
648 {
649  assert(presol != NULL);
650 
651  return presol->nfixedvars;
652 }
653 
654 /** gets number of variables aggregated in presolver */
656  SCIP_PRESOL* presol /**< presolver */
657  )
658 {
659  assert(presol != NULL);
660 
661  return presol->naggrvars;
662 }
663 
664 /** gets number of variable types changed in presolver */
666  SCIP_PRESOL* presol /**< presolver */
667  )
668 {
669  assert(presol != NULL);
670 
671  return presol->nchgvartypes;
672 }
673 
674 /** gets number of bounds changed in presolver */
676  SCIP_PRESOL* presol /**< presolver */
677  )
678 {
679  assert(presol != NULL);
680 
681  return presol->nchgbds;
682 }
683 
684 /** gets number of holes added to domains of variables in presolver */
686  SCIP_PRESOL* presol /**< presolver */
687  )
688 {
689  assert(presol != NULL);
690 
691  return presol->naddholes;
692 }
693 
694 /** gets number of constraints deleted in presolver */
696  SCIP_PRESOL* presol /**< presolver */
697  )
698 {
699  assert(presol != NULL);
700 
701  return presol->ndelconss;
702 }
703 
704 /** gets number of constraints added in presolver */
706  SCIP_PRESOL* presol /**< presolver */
707  )
708 {
709  assert(presol != NULL);
710 
711  return presol->naddconss;
712 }
713 
714 /** gets number of constraints upgraded in presolver */
716  SCIP_PRESOL* presol /**< presolver */
717  )
718 {
719  assert(presol != NULL);
720 
721  return presol->nupgdconss;
722 }
723 
724 /** gets number of coefficients changed in presolver */
726  SCIP_PRESOL* presol /**< presolver */
727  )
728 {
729  assert(presol != NULL);
730 
731  return presol->nchgcoefs;
732 }
733 
734 /** gets number of constraint sides changed in presolver */
736  SCIP_PRESOL* presol /**< presolver */
737  )
738 {
739  assert(presol != NULL);
740 
741  return presol->nchgsides;
742 }
743 
744 /** gets number of times the presolver was called and tried to find reductions */
746  SCIP_PRESOL* presol /**< presolver */
747  )
748 {
749  assert(presol != NULL);
750 
751  return presol->ncalls;
752 }
753