Scippy

SCIP

Solving Constraint Integer Programs

presol_components.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_components.c
17  * @ingroup PRESOLVERS
18  * @brief solve independent components in advance
19  * @author Dieter Weninger
20  * @author Gerald Gamrath
21  *
22  * This presolver looks for independent components at the end of the presolving.
23  * If independent components are found in which a maximum number of discrete variables
24  * is not exceeded, the presolver tries to solve them in advance as subproblems.
25  * Afterwards, if a subproblem was solved to optimality, the corresponding
26  * variables/constraints can be fixed/deleted in the main problem.
27  *
28  * @todo simulation of presolving without solve
29  * @todo solve all components with less than given size, count number of components with nodelimit reached;
30  * if all components could be solved within nodelimit (or all but x), continue solving components in
31  * increasing order until one hit the node limit
32  */
33 
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35 
36 #include <assert.h>
37 
38 #include "scip/presol_components.h"
39 
40 #define PRESOL_NAME "components"
41 #define PRESOL_DESC "components presolver"
42 #define PRESOL_PRIORITY -9200000 /**< priority of the presolver (>= 0: before, < 0: after constraint handlers); combined with propagators */
43 #define PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
44 #define PRESOL_DELAY TRUE /**< should presolver be delayed, if other presolvers found reductions? */
45 
46 #define DEFAULT_WRITEPROBLEMS FALSE /**< should the single components be written as an .lp-file? */
47 #define DEFAULT_MAXINTVARS 500 /**< maximum number of integer (or binary) variables to solve a subproblem directly (-1: no solving) */
48 #define DEFAULT_NODELIMIT 10000LL /**< maximum number of nodes to be solved in subproblems */
49 #define DEFAULT_INTFACTOR 1.0 /**< the weight of an integer variable compared to binary variables */
50 #define DEFAULT_RELDECREASE 0.2 /**< percentage by which the number of variables has to be decreased after the last component solving
51  * to allow running again (1.0: do not run again) */
52 #define DEFAULT_FEASTOLFACTOR 1.0 /**< default value for parameter to increase the feasibility tolerance in all sub-SCIPs */
53 
54 #ifdef SCIP_STATISTIC
55 static int NCATEGORIES = 6;
56 static int CATLIMITS[] = {0,20,50,100,500};
57 #endif
58 
59 /*
60  * Data structures
61  */
62 
63 /** control parameters */
64 struct SCIP_PresolData
65 {
66  SCIP* subscip; /** sub-SCIP used to solve single components */
67  SCIP_Longint nodelimit; /** maximum number of nodes to be solved in subproblems */
68  SCIP_Real intfactor; /** the weight of an integer variable compared to binary variables */
69  SCIP_Real reldecrease; /** percentage by which the number of variables has to be decreased after the last component solving
70  * to allow running again (1.0: do not run again) */
71  SCIP_Real feastolfactor; /** parameter to increase the feasibility tolerance in all sub-SCIPs */
72  SCIP_Bool didsearch; /** did the presolver already search for components? */
73  SCIP_Bool pluginscopied; /** was the copying of the plugins successful? */
74  SCIP_Bool writeproblems; /** should the single components be written as an .lp-file? */
75  int maxintvars; /** maximum number of integer (or binary) variables to solve a subproblem directly (-1: no solving) */
76  int lastnvars; /** number of variables after last run of the presolver */
77 #ifdef SCIP_STATISTIC
78  int* compspercat; /** number of components of the different categories */
79  SCIP_Real subsolvetime; /** total solving time of the subproblems */
80  int nsinglevars; /** number of components with a single variable without constraint */
81 #endif
82 };
83 
84 /*
85  * Statistic methods
86  */
87 
88 #ifdef SCIP_STATISTIC
89 /** initialize data for statistics */
90 static
91 SCIP_RETCODE initStatistics(
92  SCIP* scip, /**< SCIP data structure */
93  SCIP_PRESOLDATA* presoldata /**< presolver data */
94  )
95 {
96  assert(scip != NULL);
97  assert(presoldata != NULL);
98 
99  SCIP_CALL( SCIPallocMemoryArray(scip, &presoldata->compspercat, NCATEGORIES) );
100  BMSclearMemoryArray(presoldata->compspercat, NCATEGORIES);
101 
102  presoldata->nsinglevars = 0;
103  presoldata->subsolvetime = 0.0;
104 
105  return SCIP_OKAY;
106 }
107 
108 /** free data for statistics */
109 static
110 void freeStatistics(
111  SCIP* scip, /**< SCIP data structure */
112  SCIP_PRESOLDATA* presoldata /**< presolver data */
113  )
114 {
115  assert(scip != NULL);
116  assert(presoldata != NULL);
117 
118  SCIPfreeMemoryArray(scip, &presoldata->compspercat);
119 }
120 
121 /** reset data for statistics */
122 static
123 void resetStatistics(
124  SCIP* scip, /**< SCIP data structure */
125  SCIP_PRESOLDATA* presoldata /**< presolver data */
126  )
127 {
128  assert(scip != NULL);
129  assert(presoldata != NULL);
130 
131  BMSclearMemoryArray(presoldata->compspercat, NCATEGORIES);
132 
133  presoldata->nsinglevars = 0;
134  presoldata->subsolvetime = 0.0;
135 }
136 
137 
138 /** statistics: categorize the component with the given number of binary and integer variables */
139 static
140 void updateStatisticsComp(
141  SCIP_PRESOLDATA* presoldata, /**< presolver data */
142  int nbinvars, /**< number of binary variables */
143  int nintvars /**< number of integer variables */
144  )
145 {
146  int ndiscretevars;
147  int i;
148 
149  assert(presoldata != NULL);
150 
151  ndiscretevars = nbinvars + nintvars;
152 
153  /* check into which category the component belongs by looking at the number of discrete variables */
154  for( i = 0; i < (NCATEGORIES - 1); ++i )
155  {
156  if( ndiscretevars <= CATLIMITS[i] )
157  {
158  presoldata->compspercat[i]++;
159  break;
160  }
161  }
162 
163  /* number of discrete variables greater than all limits, so component belongs to last category */
164  if( i == (NCATEGORIES - 1) )
165  presoldata->compspercat[i]++;
166 }
167 
168 /** statistics: increase the number of components with a single variable and no constraints */
169 static
170 void updateStatisticsSingleVar(
171  SCIP_PRESOLDATA* presoldata /**< presolver data */
172  )
173 {
174  assert(presoldata != NULL);
175 
176  presoldata->nsinglevars++;
177 }
178 
179 /** statistics: update the total subproblem solving time */
180 static
181 void updateStatisticsSubsolvetime(
182  SCIP_PRESOLDATA* presoldata, /**< presolver data */
183  SCIP_Real subsolvetime /**< subproblem solving time to add to the statistics */
184  )
185 {
186  assert(presoldata != NULL);
187 
188  presoldata->subsolvetime += subsolvetime;
189 }
190 
191 /** print statistics */
192 static
193 void printStatistics(
194  SCIP_PRESOLDATA* presoldata /**< presolver data */
195  )
196 {
197  int i;
198 
199  assert(presoldata != NULL);
200 
201  printf("############\n");
202  printf("# Connected Components Presolver Statistics:\n");
203 
204  printf("# Categorization:");
205  for( i = 0; i < NCATEGORIES - 1; ++i )
206  {
207  printf("[<= %d: %d]", CATLIMITS[i], presoldata->compspercat[i]);
208  }
209  printf("[> %d: %d]\n", CATLIMITS[NCATEGORIES - 2], presoldata->compspercat[NCATEGORIES - 1]);
210  printf("# Components without constraints: %d\n", presoldata->nsinglevars);
211  printf("# Total subproblem solving time: %.2f\n", presoldata->subsolvetime);
212  printf("############\n");
213 }
214 #endif
215 
216 
217 /*
218  * Local methods
219  */
220 
221 /** copies a connected component consisting of the given constraints and variables into a sub-SCIP
222  * and tries to solve the sub-SCIP to optimality
223  */
224 static
226  SCIP* scip, /**< SCIP data structure */
227  SCIP_PRESOLDATA* presoldata, /**< presolver data */
228  SCIP_HASHMAP* consmap, /**< constraint hashmap used to improve performance */
229  int compnr, /**< number of the component */
230  SCIP_CONS** conss, /**< constraints contained in this component */
231  int nconss, /**< number of constraints contained in this component */
232  SCIP_VAR** vars, /**< variables contained in this component */
233  SCIP_Real* fixvals, /**< array to store the values to fix the variables to */
234  int nvars, /**< number of variables contained in this component */
235  int nbinvars, /**< number of binary variables contained in this component */
236  int nintvars, /**< number of integer variables contained in this component */
237  int* nsolvedprobs, /**< pointer to increase, if the subproblem was solved */
238  int* ndeletedvars, /**< pointer to increase by the number of deleted variables */
239  int* ndeletedconss, /**< pointer to increase by the number of deleted constraints */
240  SCIP_RESULT* result /**< pointer to store the result of the presolving call */
241  )
242 {
243  char name[SCIP_MAXSTRLEN];
244  SCIP* subscip;
245  SCIP_HASHMAP* varmap;
246  SCIP_CONS* newcons;
247  SCIP_Real timelimit;
248  SCIP_Real memorylimit;
249  SCIP_Real feastol;
250  SCIP_Bool success;
251  int i;
252 
253  assert(scip != NULL);
254  assert(presoldata != NULL);
255  assert(conss != NULL);
256  assert(nconss > 0);
257  assert(vars != NULL);
258  assert(nvars > 0);
259  assert(nsolvedprobs != NULL);
260 
261  *result = SCIP_DIDNOTRUN;
262 
263 #ifndef SCIP_DEBUG
264  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "build sub-SCIP for component %d: %d vars (%d bin, %d int, %d cont), %d conss\n",
265  compnr, nvars, nbinvars, nintvars, nvars - nintvars - nbinvars, nconss);
266 #else
267  SCIPdebugMessage("build sub-SCIP for component %d: %d vars (%d bin, %d int, %d cont), %d conss\n",
268  compnr, nvars, nbinvars, nintvars, nvars - nintvars - nbinvars, nconss);
269 #endif
270 
271  /* stop if the problem has too many integer variables; only if the problems should be written we have to build it anyway */
272  if( presoldata->maxintvars != -1 && (nbinvars + presoldata->intfactor * nintvars > presoldata->maxintvars)
273  && !presoldata->writeproblems )
274  {
275 #ifndef SCIP_DEBUG
276  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "--> not created (too many integer variables)\n");
277 #else
278  SCIPdebugMessage("--> not created (too many integer variables)\n");
279 #endif
280 
281  return SCIP_OKAY;
282  }
283 
284  /* check whether there is enough time and memory left */
285  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
286  if( !SCIPisInfinity(scip, timelimit) )
287  timelimit -= SCIPgetSolvingTime(scip);
288  SCIP_CALL( SCIPgetRealParam(scip, "limits/memory", &memorylimit) );
289 
290  /* substract the memory already used by the main SCIP and the estimated memory usage of external software */
291  if( !SCIPisInfinity(scip, memorylimit) )
292  {
293  memorylimit -= SCIPgetMemUsed(scip)/1048576.0;
294  memorylimit -= SCIPgetMemExternEstim(scip)/1048576.0;
295  }
296 
297  /* abort if no time is left or not enough memory to create a copy of SCIP, including external memory usage */
298  if( timelimit <= 0.0 || memorylimit <= (1.0 * nvars / SCIPgetNVars(scip)) * (1.0 * nconss / SCIPgetNConss(scip)) *
299  ((SCIPgetMemUsed(scip) + SCIPgetMemExternEstim(scip))/1048576.0) )
300  {
301  SCIPdebugMessage("--> not created (not enough memory or time left)\n");
302  return SCIP_OKAY;
303  }
304 
305  /* create sub-SCIP */
306  if( presoldata->subscip == NULL )
307  {
308  SCIP_CALL( SCIPcreate(&presoldata->subscip) );
309  subscip = presoldata->subscip;
310 
311  /* copy plugins, we omit pricers (because we do not run if there are active pricers) and dialogs */
312  success = TRUE;
313  SCIP_CALL( SCIPcopyPlugins(scip, subscip, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE,
314  TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, &success) );
315 
316  /* abort if the plugins were not successfully copied */
317  if( !success )
318  {
319  SCIP_CALL( SCIPfree(&presoldata->subscip) );
320  presoldata->subscip = NULL;
321  presoldata->pluginscopied = FALSE;
322 
323  return SCIP_OKAY;
324  }
325  /* copy parameter settings */
326  SCIP_CALL( SCIPcopyParamSettings(scip, subscip) );
327 
328  if( !SCIPisParamFixed(subscip, "limits/solutions") )
329  {
330  SCIP_CALL( SCIPsetIntParam(subscip, "limits/solutions", -1) );
331  }
332  if( !SCIPisParamFixed(subscip, "limits/bestsol") )
333  {
334  SCIP_CALL( SCIPsetIntParam(subscip, "limits/bestsol", -1) );
335  }
336 
337  /* set gap limit to 0 */
338  SCIP_CALL( SCIPsetRealParam(subscip, "limits/gap", 0.0) );
339 
340  /* reduce the effort spent for hash tables */
341  if( !SCIPisParamFixed(subscip, "misc/usevartable") )
342  {
343  SCIP_CALL( SCIPsetBoolParam(subscip, "misc/usevartable", FALSE) );
344  }
345  if( !SCIPisParamFixed(subscip, "misc/useconstable") )
346  {
347  SCIP_CALL( SCIPsetBoolParam(subscip, "misc/useconstable", FALSE) );
348  }
349  if( !SCIPisParamFixed(subscip, "misc/usesmalltables") )
350  {
351  SCIP_CALL( SCIPsetBoolParam(subscip, "misc/usesmalltables", TRUE) );
352  }
353 
354  /* increase feasibility tolerance if asked for */
355  if( !SCIPisEQ(scip, presoldata->feastolfactor, 1.0) )
356  {
357  SCIP_CALL( SCIPgetRealParam(scip, "numerics/feastol", &feastol) );
358  SCIP_CALL( SCIPsetRealParam(subscip, "numerics/feastol", feastol * presoldata->feastolfactor) );
359  }
360 
361  /* do not catch control-C */
362  SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
363 
364 #ifndef SCIP_MORE_DEBUG
365  /* disable output */
366  SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
367 #endif
368  }
369  else
370  {
371  subscip = presoldata->subscip;
372  }
373 
374  /* set time and memory limit for the subproblem */
375  SCIP_CALL( SCIPsetRealParam(subscip, "limits/time", timelimit) );
376  SCIP_CALL( SCIPsetRealParam(subscip, "limits/memory", memorylimit) );
377 
378  /* disable statistic timing inside sub SCIP */
379  SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
380 
381  if( nbinvars + nintvars > 0 )
382  {
383  /* set node limit */
384  SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", presoldata->nodelimit) );
385  }
386  else
387  {
388  /* if we have only continuous variables, solving the root should be enough;
389  * this avoids to spend much time in a nonlinear subscip with only continuous variables */
390  SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", 1LL) );
391  }
392 
393  /* create problem in sub-SCIP */
394  /* get name of the original problem and add "comp_nr" */
395  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_comp_%d", SCIPgetProbName(scip), compnr);
396  SCIP_CALL( SCIPcreateProb(subscip, name, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
397 
398  /* create variable hashmap */
399  SCIP_CALL( SCIPhashmapCreate(&varmap, SCIPblkmem(subscip), 10 * nvars) );
400 
401  for( i = 0; i < nconss; ++i )
402  {
403  /* copy the constraint */
404  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s", SCIPconsGetName(conss[i]));
405  SCIP_CALL( SCIPgetConsCopy(scip, subscip, conss[i], &newcons, SCIPconsGetHdlr(conss[i]), varmap, consmap, name,
406  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, &success) );
407 
408  /* abort if constraint was not successfully copied */
409  if( !success )
410  goto TERMINATE;
411 
412  SCIP_CALL( SCIPaddCons(subscip, newcons) );
413  SCIP_CALL( SCIPreleaseCons(subscip, &newcons) );
414  }
415 
416  /* write the problem, if requested */
417  if( presoldata->writeproblems )
418  {
419  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_comp_%d.cip", SCIPgetProbName(scip), compnr);
420  SCIPdebugMessage("write problem to file %s\n", name);
421  SCIP_CALL( SCIPwriteOrigProblem(subscip, name, NULL, FALSE) );
422  }
423 
424  /* the following asserts are not true, because some aggregations in the original scip instance could not get resolved
425  * inside some constraints, so the copy (subscip) will have also some inactive variables which were copied
426  */
427 #if 0
428  /* there might be less variables in the subscip, because variables might be cancelled out during copying constraint
429  * when transferring variables to active variables
430  */
431  assert(nbinvars >= SCIPgetNBinVars(subscip));
432  assert(nintvars >= SCIPgetNIntVars(subscip));
433 #endif
434 
435  /* In extended debug mode, we want to be informed if the number of variables was reduced during copying.
436  * This might happen, since the components presolver uses SCIPgetConsVars() and then SCIPgetActiveVars() to get the
437  * active representation, while SCIPgetConsCopy() might use SCIPgetProbvarLinearSum() and this might cancel out some
438  * of the active variables and cannot be avoided. However, we want to notice it and check whether the constraint
439  * handler could do something more clever.
440  */
441 #ifdef SCIP_MORE_DEBUG
442  if( nvars > SCIPgetNVars(subscip) )
443  {
444  SCIPinfoMessage(scip, NULL, "copying component %d reduced number of variables: %d -> %d\n", compnr, nvars, SCIPgetNVars(subscip));
445  }
446 #endif
447 
448  if( presoldata->maxintvars == -1 || (SCIPgetNBinVars(subscip) + presoldata->intfactor * SCIPgetNIntVars(subscip) <= presoldata->maxintvars) )
449  {
450  SCIP_RETCODE retcode;
451 
452  /* solve the subproblem */
453  retcode = SCIPsolve(subscip);
454 
455  /* errors in solving the subproblem should not kill the overall solving process;
456  * hence, the return code is caught and a warning is printed, only when more debugging is enabled, SCIP will stop
457  */
458  if( retcode != SCIP_OKAY )
459  {
460 #ifdef SCIP_MORE_DEBUG
461  SCIP_CALL( retcode );
462 #endif
463  SCIPwarningMessage(scip, "Error while solving subproblem in components presolver; sub-SCIP terminated with code <%d>\n", retcode);
464  }
465  else
466  {
467 #ifdef SCIP_MORE_DEBUG
468  SCIP_CALL( SCIPprintStatistics(subscip, NULL) );
469 #endif
470 
471  SCIPstatistic( updateStatisticsSubsolvetime(presoldata, SCIPgetSolvingTime(subscip)) );
472 
473  if( SCIPgetStatus(subscip) == SCIP_STATUS_OPTIMAL )
474  {
475  SCIP_SOL* sol;
476  SCIP_VAR* subvar;
477  SCIP_Bool feasible;
478  SCIP_Bool infeasible;
479  SCIP_Bool fixed;
480 
481  ++(*nsolvedprobs);
482 
483  sol = SCIPgetBestSol(subscip);
484 
485 #ifdef SCIP_DEBUG
486  SCIP_CALL( SCIPcheckSolOrig(subscip, sol, &feasible, TRUE, TRUE) );
487 #else
488  SCIP_CALL( SCIPcheckSolOrig(subscip, sol, &feasible, FALSE, FALSE) );
489 #endif
490 
491  SCIPdebugMessage("--> solved to optimality: time=%.2f, solution is%s feasible\n", SCIPgetSolvingTime(subscip), feasible ? "" : " not");
492 
493  if( feasible )
494  {
495  SCIP_Real glb;
496  SCIP_Real gub;
497 
498  /* get values of variables in the optimal solution */
499  for( i = 0; i < nvars; ++i )
500  {
501  subvar = (SCIP_VAR*)SCIPhashmapGetImage(varmap, vars[i]);
502 
503  /* get global bounds */
504  glb = SCIPvarGetLbGlobal(vars[i]);
505  gub = SCIPvarGetUbGlobal(vars[i]);
506 
507  if( subvar != NULL )
508  {
509  /* get solution value from optimal solution of the component */
510  fixvals[i] = SCIPgetSolVal(subscip, sol, subvar);
511 
512  assert(SCIPisFeasLE(scip, fixvals[i], SCIPvarGetUbLocal(vars[i])));
513  assert(SCIPisFeasGE(scip, fixvals[i], SCIPvarGetLbLocal(vars[i])));
514 
515  /* checking a solution is done with a relative tolerance of feasibility epsilon, if we really want to
516  * change the bounds of the variables by fixing them, the old bounds must not be violated by more than
517  * the absolute epsilon; therefore, we change the fixing values, if needed, and mark that the solution
518  * has to be checked again
519  */
520  if( SCIPisGT(scip, fixvals[i], gub) )
521  {
522  SCIPdebugMessage("variable <%s> fixval: %f violates global upperbound: %f\n",
523  SCIPvarGetName(vars[i]), fixvals[i], gub);
524  fixvals[i] = gub;
525  feasible = FALSE;
526  }
527  else if( SCIPisLT(scip, fixvals[i], glb) )
528  {
529  SCIPdebugMessage("variable <%s> fixval: %f violates global lowerbound: %f\n",
530  SCIPvarGetName(vars[i]), fixvals[i], glb);
531  fixvals[i] = glb;
532  feasible = FALSE;
533  }
534  assert(SCIPisLE(scip, fixvals[i], SCIPvarGetUbLocal(vars[i])));
535  assert(SCIPisGE(scip, fixvals[i], SCIPvarGetLbLocal(vars[i])));
536  }
537  else
538  {
539  /* the variable was not copied, so it was cancelled out of constraints during copying;
540  * thus, the variable is not constrained and we fix it to its best bound
541  */
542  if( SCIPisPositive(scip, SCIPvarGetObj(vars[i])) )
543  fixvals[i] = glb;
544  else if( SCIPisNegative(scip, SCIPvarGetObj(vars[i])) )
545  fixvals[i] = gub;
546  else
547  {
548  fixvals[i] = 0.0;
549  fixvals[i] = MIN(fixvals[i], gub);
550  fixvals[i] = MAX(fixvals[i], glb);
551  }
552  }
553  }
554 
555  /* the solution value of at least one variable is feasible with a relative tolerance of feasibility epsilon,
556  * but infeasible with an absolute tolerance of epsilon; try to set the variables to the bounds and check
557  * solution again (changing the values might now introduce infeasibilities of constraints)
558  */
559  if( !feasible )
560  {
561  SCIP_Real origobj;
562 
563  SCIPdebugMessage("solution violates bounds by more than epsilon, check the corrected solution...\n");
564 
565  origobj = SCIPgetSolOrigObj(subscip, SCIPgetBestSol(subscip));
566 
567  SCIP_CALL( SCIPfreeTransform(subscip) );
568 
569  SCIP_CALL( SCIPcreateOrigSol(subscip, &sol, NULL) );
570 
571  /* get values of variables in the optimal solution */
572  for( i = 0; i < nvars; ++i )
573  {
574  subvar = (SCIP_VAR*)SCIPhashmapGetImage(varmap, vars[i]);
575 
576  SCIP_CALL( SCIPsetSolVal(subscip, sol, subvar, fixvals[i]) );
577  }
578 
579  /* check the solution; integrality and bounds should be fulfilled and do not have to be checked */
580  SCIP_CALL( SCIPcheckSol(subscip, sol, FALSE, FALSE, FALSE, TRUE, &feasible) );
581 
582 #ifndef NDEBUG
583  /* in debug mode, we additionally check integrality and bounds */
584  if( feasible )
585  {
586  SCIP_CALL( SCIPcheckSol(subscip, sol, FALSE, TRUE, TRUE, FALSE, &feasible) );
587  assert(feasible);
588  }
589 #endif
590 
591  SCIPdebugMessage("--> corrected solution is%s feasible\n", feasible ? "" : " not");
592 
593  if( !SCIPisFeasEQ(subscip, SCIPsolGetOrigObj(sol), origobj) )
594  {
595  SCIPdebugMessage("--> corrected solution has a different objective value (old=%16.9g, corrected=%16.9g)\n",
596  origobj, SCIPsolGetOrigObj(sol));
597 
598  feasible = FALSE;
599  }
600 
601  SCIP_CALL( SCIPfreeSol(subscip, &sol) );
602  }
603 
604  /* if the solution is feasible, fix variables and delete constraints of the component */
605  if( feasible )
606  {
607  /* fix variables */
608  for( i = 0; i < nvars; ++i )
609  {
610  assert(SCIPisLE(scip, fixvals[i], SCIPvarGetUbLocal(vars[i])));
611  assert(SCIPisGE(scip, fixvals[i], SCIPvarGetLbLocal(vars[i])));
612  assert(SCIPisLE(scip, fixvals[i], SCIPvarGetUbGlobal(vars[i])));
613  assert(SCIPisGE(scip, fixvals[i], SCIPvarGetLbGlobal(vars[i])));
614 
615  SCIP_CALL( SCIPfixVar(scip, vars[i], fixvals[i], &infeasible, &fixed) );
616  assert(!infeasible);
617  assert(fixed);
618  (*ndeletedvars)++;
619  }
620 
621  /* delete constraints */
622  for( i = 0; i < nconss; ++i )
623  {
624  SCIP_CALL( SCIPdelCons(scip, conss[i]) );
625  (*ndeletedconss)++;
626  }
627  }
628  }
629  }
630  else if( SCIPgetStatus(subscip) == SCIP_STATUS_INFEASIBLE )
631  {
632  *result = SCIP_CUTOFF;
633  }
634  else if( SCIPgetStatus(subscip) == SCIP_STATUS_UNBOUNDED || SCIPgetStatus(subscip) == SCIP_STATUS_INFORUNBD )
635  {
636  /* TODO: store unbounded ray in original SCIP data structure */
637  *result = SCIP_UNBOUNDED;
638  }
639  else
640  {
641  SCIPdebugMessage("--> solving interrupted (status=%d, time=%.2f)\n",
642  SCIPgetStatus(subscip), SCIPgetSolvingTime(subscip));
643 
644  /* transfer global fixings to the original problem; we can only do this, if we did not find a solution in the
645  * subproblem, because otherwise, the primal bound might lead to dual reductions that cannot be transferred to
646  * the original problem without also transferring the possibly suboptimal solution (which is currently not
647  * possible)
648  */
649  if( SCIPgetNSols(subscip) == 0 )
650  {
651  SCIP_Bool infeasible;
652  SCIP_Bool tightened;
653  int ntightened;
654 
655  ntightened = 0;
656 
657  for( i = 0; i < nvars; ++i )
658  {
659  assert( SCIPhashmapExists(varmap, vars[i]) );
660 
661  SCIP_CALL( SCIPtightenVarLb(scip, vars[i], SCIPvarGetLbGlobal((SCIP_VAR*)SCIPhashmapGetImage(varmap, vars[i])), FALSE,
662  &infeasible, &tightened) );
663  assert(!infeasible);
664  if( tightened )
665  ntightened++;
666 
667  SCIP_CALL( SCIPtightenVarUb(scip, vars[i], SCIPvarGetUbGlobal((SCIP_VAR*)SCIPhashmapGetImage(varmap, vars[i])), FALSE,
668  &infeasible, &tightened) );
669  assert(!infeasible);
670  if( tightened )
671  ntightened++;
672  }
673  SCIPdebugMessage("--> tightened %d bounds of variables due to global bounds in the sub-SCIP\n", ntightened);
674  }
675  }
676  }
677  }
678  else
679  {
680  SCIPdebugMessage("--> not solved (too many integer variables)\n");
681  }
682 
683  TERMINATE:
684  SCIPhashmapFree(&varmap);
685 
686  return SCIP_OKAY;
687 }
688 
689 /** loop over constraints, get active variables and fill directed graph */
690 static
692  SCIP* scip, /**< SCIP data structure */
693  SCIP_DIGRAPH* digraph, /**< directed graph */
694  SCIP_CONS** conss, /**< constraints */
695  int nconss, /**< number of constraints */
696  int* firstvaridxpercons, /**< array to store for each constraint the index in the local vars array
697  * of the first variable of the constraint */
698  SCIP_Bool* success /**< flag indicating successful directed graph filling */
699  )
700 {
701  SCIP_VAR** consvars;
702  int requiredsize;
703  int nconsvars;
704  int nvars;
705  int idx1;
706  int idx2;
707  int c;
708  int v;
709 
710  assert(scip != NULL);
711  assert(digraph != NULL);
712  assert(conss != NULL);
713  assert(firstvaridxpercons != NULL);
714  assert(success != NULL);
715 
716  *success = TRUE;
717 
718  nconsvars = 0;
719  requiredsize = 0;
720  nvars = SCIPgetNVars(scip);
721 
722  /* use big buffer for storing active variables per constraint */
723  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nvars) );
724 
725  for( c = 0; c < nconss; ++c )
726  {
727  /* check for reached timelimit */
728  if( (c % 1000 == 0) && SCIPisStopped(scip) )
729  {
730  *success = FALSE;
731  break;
732  }
733 
734  /* get number of variables for this constraint */
735  SCIP_CALL( SCIPgetConsNVars(scip, conss[c], &nconsvars, success) );
736 
737  if( !(*success) )
738  break;
739 
740  if( nconsvars > nvars )
741  {
742  nvars = nconsvars;
743  SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, nvars) );
744  }
745 
746 #ifndef NDEBUG
747  /* clearing variables array to check for consistency */
748  if( nconsvars == nvars )
749  {
750  BMSclearMemoryArray(consvars, nconsvars);
751  }
752  else
753  {
754  assert(nconsvars < nvars);
755  BMSclearMemoryArray(consvars, nconsvars + 1);
756  }
757 #endif
758 
759  /* get variables for this constraint */
760  SCIP_CALL( SCIPgetConsVars(scip, conss[c], consvars, nvars, success) );
761 
762  if( !(*success) )
763  {
764 #ifndef NDEBUG
765  /* it looks strange if returning the number of variables was successful but not returning the variables */
766  SCIPwarningMessage(scip, "constraint <%s> returned number of variables but returning variables failed\n", SCIPconsGetName(conss[c]));
767 #endif
768  break;
769  }
770 
771 #ifndef NDEBUG
772  /* check if returned variables are consistent with the number of variables that were returned */
773  for( v = nconsvars - 1; v >= 0; --v )
774  assert(consvars[v] != NULL);
775  if( nconsvars < nvars )
776  assert(consvars[nconsvars] == NULL);
777 #endif
778 
779  /* transform given variables to active variables */
780  SCIP_CALL( SCIPgetActiveVars(scip, consvars, &nconsvars, nvars, &requiredsize) );
781  assert(requiredsize <= nvars);
782 
783  if( nconsvars > 0 )
784  {
785  idx1 = SCIPvarGetProbindex(consvars[0]);
786  assert(idx1 >= 0);
787 
788  /* save index of the first variable for later component assignment */
789  firstvaridxpercons[c] = idx1;
790 
791  if( nconsvars > 1 )
792  {
793  /* create sparse directed graph
794  * sparse means, to add only those edges necessary for component calculation
795  */
796  for( v = 1; v < nconsvars; ++v )
797  {
798  idx2 = SCIPvarGetProbindex(consvars[v]);
799  assert(idx2 >= 0);
800 
801  /* we add only one directed edge, because the other direction is automatically added for component computation */
802  SCIP_CALL( SCIPdigraphAddArc(digraph, idx1, idx2, NULL) );
803  }
804  }
805  }
806  else
807  firstvaridxpercons[c] = -1;
808  }
809 
810  SCIPfreeBufferArray(scip, &consvars);
811 
812  return SCIP_OKAY;
813 }
814 
815 #ifdef COMPONENTS_PRINT_STRUCTURE
816 
817 static
818 SCIP_RETCODE printStructure(
819  SCIP* scip, /**< SCIP data structure */
820  SCIP_VAR** vars, /**< variables */
821  SCIP_CONS** conss, /**< constraints */
822  int* components, /**< array with component number for every variable */
823  int* conscomponents, /**< array with component number for every constraint */
824  int nvars, /**< number of variables */
825  int nconss, /**< number of constraints */
826  int ncomponents /**< number of components */
827  )
828 {
829  char probname[SCIP_MAXSTRLEN];
830  char outname[SCIP_MAXSTRLEN];
831  char filename[SCIP_MAXSTRLEN];
832  char* name;
833  FILE* file;
834  SCIP_VAR** consvars;
835  SCIP_VAR* var;
836  int* varidx;
837  int* compstartvars;
838  int* compstartconss;
839  int ncalls;
840  int requiredsize;
841  int nconsvars;
842  int i;
843  int c;
844  int v;
845  SCIP_Bool success;
846 
847  SCIP_CALL( SCIPallocBufferArray(scip, &varidx, nvars) );
848  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nvars) );
849  SCIP_CALL( SCIPallocBufferArray(scip, &compstartvars, ncomponents + 1) );
850  SCIP_CALL( SCIPallocBufferArray(scip, &compstartconss, ncomponents + 1) );
851 
853  compstartvars[0] = 0;
854  compstartconss[0] = 0;
855 
856  for( v = 0; v < nvars; ++v )
857  {
858  assert(v == 0 || components[v] == components[v-1] || components[v] == components[v-1]+1);
859  varidx[SCIPvarGetProbindex(vars[v])] = v;
860 
861  if( v > 0 && components[v] == components[v-1] + 1 )
862  {
863  compstartvars[components[v]] = v;
864  }
865  }
866 
867  for( v = 0; v < nconss; ++v )
868  {
869  assert(v == 0 || conscomponents[v] == conscomponents[v-1] || conscomponents[v] == conscomponents[v-1]+1);
870 
871  if( v > 0 && conscomponents[v] == conscomponents[v-1] + 1 )
872  {
873  compstartconss[conscomponents[v]] = v;
874  }
875  }
876 
877  compstartvars[ncomponents] = nvars;
878  compstartconss[ncomponents] = nconss;
879 
880  /* split problem name */
881  (void) SCIPsnprintf(probname, SCIP_MAXSTRLEN, "%s", SCIPgetProbName(scip));
882  SCIPsplitFilename(probname, NULL, &name, NULL, NULL);
883 
884  /* define file name depending on instance name, number of presolver calls and number of components */
885  (void) SCIPsnprintf(outname, SCIP_MAXSTRLEN, "%s_%d_%d", name, ncalls, ncomponents);
886  (void) SCIPsnprintf(filename, SCIP_MAXSTRLEN, "%s.gp", outname);
887 
888  /* open output file */
889  file = fopen(filename, "w");
890  if( file == NULL )
891  {
892  SCIPerrorMessage("cannot create file <%s> for writing\n", filename);
893  SCIPprintSysError(filename);
894  return SCIP_FILECREATEERROR;
895  }
896 
897  /* print header of gnuplot file */
898  SCIPinfoMessage(scip, file, "set terminal pdf\nset output \"%s.pdf\"\nunset xtics\nunset ytics\n\n", outname);
899  SCIPinfoMessage(scip, file, "unset border\nunset key\nset style fill solid 1.0 noborder\nset size ratio -1\n");
900  SCIPinfoMessage(scip, file, "set xrange [0:%d]\nset yrange[%d:0]\n", nvars + 1, nconss + 1);
901 
902  /* write rectangles around blocks */
903  for( i = 0; i < ncomponents; ++i )
904  {
905  assert(compstartvars[i] <= nvars);
906  assert(compstartconss[i] <= nconss);
907  assert(compstartvars[i+1] <= nvars);
908  assert(compstartconss[i+1] <= nconss);
909  SCIPinfoMessage(scip, file, "set object %d rect from %.1f,%.1f to %.1f,%.1f fc rgb \"grey\"\n",
910  i + 1, nvars - compstartvars[i] + 0.5, nconss - compstartconss[i] + 0.5,
911  nvars - compstartvars[i+1] + 0.5, nconss - compstartconss[i+1] + 0.5);
912  }
913 
914  /* write the plot header */
915  SCIPinfoMessage(scip, file, "plot \"-\" using 1:2:3 with circles fc rgb \"black\"\n");
916 
917  /* write data */
918  for( c = 0; c < nconss; ++c )
919  {
920  /* get variables for this constraint */
921  SCIP_CALL( SCIPgetConsNVars(scip, conss[c], &nconsvars, &success) );
922  SCIP_CALL( SCIPgetConsVars(scip, conss[c], consvars, nvars, &success) );
923  assert(success);
924 
925  /* transform given variables to active variables */
926  SCIP_CALL( SCIPgetActiveVars(scip, consvars, &nconsvars, nvars, &requiredsize) );
927  assert(requiredsize <= nvars);
928 
929  for( v = 0; v < nconsvars; ++v )
930  {
931  var = consvars[v];
932  SCIPinfoMessage(scip, file, "%d %d 0.5\n", nvars - varidx[SCIPvarGetProbindex(var)], nconss - c);
933  }
934  }
935 
936  /* write file end */
937  SCIPinfoMessage(scip, file, "e\n");
938 
939  (void) fclose(file);
940 
941  SCIPfreeBufferArray(scip, &compstartconss);
942  SCIPfreeBufferArray(scip, &compstartvars);
943  SCIPfreeBufferArray(scip, &consvars);
944  SCIPfreeBufferArray(scip, &varidx);
945 
946  return SCIP_OKAY;
947 }
948 
949 #endif
950 
951 /** use components to assign variables and constraints to the subscips
952  * and try to solve all subscips having not too many integer variables
953  */
954 static
956  SCIP* scip, /**< SCIP data structure */
957  SCIP_PRESOLDATA* presoldata, /**< presolver data */
958  SCIP_CONS** conss, /**< constraints */
959  SCIP_VAR** vars, /**< variables */
960  SCIP_Real* fixvals, /**< array to store the fixing values */
961  int nconss, /**< number of constraints */
962  int nvars, /**< number of variables */
963  int* components, /**< array with component number for every variable */
964  int ncomponents, /**< number of components */
965  int* firstvaridxpercons, /**< array with index of first variable in vars array for each constraint */
966  int* nsolvedprobs, /**< pointer to store the number of solved subproblems */
967  int* ndeletedvars, /**< pointer to store the number of deleted variables */
968  int* ndeletedconss, /**< pointer to store the number of deleted constraints */
969  SCIP_RESULT* result /**< pointer to store the result of the presolving call */
970  )
971 {
972  SCIP_HASHMAP* consmap;
973  SCIP_CONS** compconss;
974  SCIP_VAR** compvars;
975  SCIP_Real* compfixvals;
976  int* conscomponent;
977  int ncompconss;
978  int ncompvars;
979  int nbinvars;
980  int nintvars;
981  int comp;
982  int compvarsstart;
983  int compconssstart;
984  int v;
985  int c;
986 
987  assert(scip != NULL);
988  assert(presoldata != NULL);
989  assert(conss != NULL);
990  assert(components != NULL);
991  assert(firstvaridxpercons != NULL);
992  assert(nsolvedprobs != NULL);
993  assert(result != NULL);
994 
995  *nsolvedprobs = 0;
996 
997  /* hashmap mapping from original constraints to constraints in the sub-SCIPs (for performance reasons) */
998  SCIP_CALL( SCIPhashmapCreate(&consmap, SCIPblkmem(scip), 10 * SCIPgetNConss(scip)) );
999 
1000  SCIP_CALL( SCIPallocBufferArray(scip, &conscomponent, nconss) );
1001 
1002  /* do the mapping from calculated components per variable to corresponding
1003  * constraints and sort the component-arrays for faster finding the
1004  * actual variables and constraints belonging to one component
1005  */
1006  for( c = 0; c < nconss; c++ )
1007  conscomponent[c] = (firstvaridxpercons[c] == -1 ? -1 : components[firstvaridxpercons[c]]);
1008 
1009  SCIPsortIntPtr(components, (void**)vars, nvars);
1010  SCIPsortIntPtr(conscomponent, (void**)conss, nconss);
1011 
1012 #ifdef COMPONENTS_PRINT_STRUCTURE
1013  SCIP_CALL( printStructure(scip, vars, conss, components, conscomponent, nvars, nconss, ncomponents) );
1014 #endif
1015 
1016  compvarsstart = 0;
1017  compconssstart = 0;
1018 
1019  while( compconssstart < nconss && conscomponent[compconssstart] == -1 )
1020  ++compconssstart;
1021 
1022  /* loop over all components */
1023  for( comp = 0; comp < ncomponents && !SCIPisStopped(scip); comp++ )
1024  {
1025  nbinvars = 0;
1026  nintvars = 0;
1027 
1028  /* count variables present in this component and categorize them */
1029  for( v = compvarsstart; v < nvars && components[v] == comp; ++v )
1030  {
1031  /* check whether variable is of binary or integer type */
1032  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
1033  nbinvars++;
1034  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_INTEGER )
1035  nintvars++;
1036  }
1037 
1038  /* count constraints present in this component */
1039  c = compconssstart;
1040  while( c < nconss && conscomponent[c] == comp )
1041  ++c;
1042 
1043  /* collect some statistical information */
1044  SCIPstatistic( updateStatisticsComp(presoldata, nbinvars, nintvars) );
1045 
1046  compvars = &(vars[compvarsstart]);
1047  compfixvals = &(fixvals[compvarsstart]);
1048  compconss = &(conss[compconssstart]);
1049  ncompvars = v - compvarsstart;
1050  ncompconss = c - compconssstart;
1051  compvarsstart = v;
1052  compconssstart = c;
1053 
1054  /* the dual fixing presolver will take care of the case ncompconss == 0 */
1055  assert(ncompconss > 0 || ncompvars == 1);
1056 
1057  /* we do not want to solve the component, if it is the last unsolved one */
1058  if( ncompconss > 0 && ncompvars < SCIPgetNVars(scip) )
1059  {
1060  SCIP_RESULT subscipresult;
1061 
1062  assert(ncompconss > 0);
1063 
1064  /* in extended debug mode, we want to be informed about components with single constraints;
1065  * this is only for noticing this case and possibly handling it within the constraint handler
1066  */
1067 #ifdef SCIP_MORE_DEBUG
1068  if( ncompconss == 1 )
1069  {
1070  SCIPinfoMessage(scip, NULL, "presol component detected component with a single constraint:\n");
1071  SCIP_CALL( SCIPprintCons(scip, compconss[0], NULL) );
1072  SCIPinfoMessage(scip, NULL, ";\n");
1073  }
1074 #endif
1075 
1076  /* build subscip for one component and try to solve it */
1077  SCIP_CALL( copyAndSolveComponent(scip, presoldata, consmap, comp, compconss, ncompconss, compvars,
1078  compfixvals, ncompvars, nbinvars, nintvars, nsolvedprobs, ndeletedvars, ndeletedconss,
1079  &subscipresult) );
1080 
1081  if( subscipresult == SCIP_CUTOFF || subscipresult == SCIP_UNBOUNDED )
1082  {
1083  *result = subscipresult;
1084  break;
1085  }
1086 
1087  if( !presoldata->pluginscopied )
1088  break;
1089  }
1090  }
1091 
1092  if( presoldata->subscip != NULL )
1093  {
1094  SCIP_CALL( SCIPfree(&presoldata->subscip) );
1095  presoldata->subscip = NULL;
1096  }
1097 
1098  SCIPfreeBufferArray(scip, &conscomponent);
1099  SCIPhashmapFree(&consmap);
1100 
1101  return SCIP_OKAY;
1102 }
1103 
1104 /** performs presolving by searching for components */
1105 static
1107  SCIP* scip, /**< SCIP main data structure */
1108  SCIP_PRESOL* presol, /**< the presolver itself */
1109  int* nfixedvars, /**< counter to increase by the number of fixed variables */
1110  int* ndelconss, /**< counter to increase by the number of deleted constrains */
1111  SCIP_RESULT* result /**< pointer to store the result of the presolving call */
1112  )
1113 {
1114  SCIP_PRESOLDATA* presoldata;
1115  SCIP_CONS** conss;
1116  SCIP_CONS** tmpconss;
1117  SCIP_Bool success;
1118  int nconss;
1119  int ntmpconss;
1120  int nvars;
1121  int ncomponents;
1122  int ndeletedconss;
1123  int ndeletedvars;
1124  int nsolvedprobs;
1125  int c;
1126 
1127  assert(scip != NULL);
1128  assert(presol != NULL);
1129  assert(result != NULL);
1130 
1131  *result = SCIP_DIDNOTRUN;
1132 
1133  if( SCIPgetStage(scip) != SCIP_STAGE_PRESOLVING || SCIPinProbing(scip) )
1134  return SCIP_OKAY;
1135 
1136  /* do not run, if not all variables are explicitly known */
1137  if( SCIPgetNActivePricers(scip) > 0 )
1138  return SCIP_OKAY;
1139 
1140  presoldata = SCIPpresolGetData(presol);
1141  assert(presoldata != NULL);
1142 
1143  nvars = SCIPgetNVars(scip);
1144 
1145  /* we do not want to run, if there are no variables left */
1146  if( nvars == 0 )
1147  return SCIP_OKAY;
1148 
1149  /* the presolver should be executed only if it didn't run so far or the number of variables was significantly reduced
1150  * since tha last run
1151  */
1152  if( (presoldata->didsearch && nvars > (1 - presoldata->reldecrease) * presoldata->lastnvars) )
1153  return SCIP_OKAY;
1154 
1155  /* if we were not able to copy all plugins, we cannot run the components presolver */
1156  if( !presoldata->pluginscopied )
1157  return SCIP_OKAY;
1158 
1159  /* only call the component presolver, if presolving would be stopped otherwise */
1160  if( !SCIPisPresolveFinished(scip) )
1161  return SCIP_OKAY;
1162 
1163  /* check for a reached timelimit */
1164  if( SCIPisStopped(scip) )
1165  return SCIP_OKAY;
1166 
1167  SCIPstatistic( resetStatistics(scip, presoldata) );
1168 
1169  *result = SCIP_DIDNOTFIND;
1170  presoldata->didsearch = TRUE;
1171 
1172  ncomponents = 0;
1173  ndeletedvars = 0;
1174  ndeletedconss = 0;
1175  nsolvedprobs = 0;
1176 
1177  /* collect checked constraints for component presolving */
1178  ntmpconss = SCIPgetNConss(scip);
1179  tmpconss = SCIPgetConss(scip);
1180  SCIP_CALL( SCIPallocBufferArray(scip, &conss, ntmpconss) );
1181  nconss = 0;
1182  for( c = 0; c < ntmpconss; c++ )
1183  {
1184  if( SCIPconsIsChecked(tmpconss[c]) )
1185  {
1186  conss[nconss] = tmpconss[c];
1187  nconss++;
1188  }
1189  }
1190 
1191  if( nvars > 1 && nconss > 1 )
1192  {
1193  SCIP_DIGRAPH* digraph;
1194  SCIP_VAR** vars;
1195  SCIP_Real* fixvals;
1196  int* firstvaridxpercons;
1197  int* varlocks;
1198  int v;
1199 
1200  /* copy variables into a local array */
1201  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
1202  SCIP_CALL( SCIPallocBufferArray(scip, &fixvals, nvars) );
1203  SCIP_CALL( SCIPallocBufferArray(scip, &firstvaridxpercons, nconss) );
1204  SCIP_CALL( SCIPallocBufferArray(scip, &varlocks, nvars) );
1205  BMScopyMemoryArray(vars, SCIPgetVars(scip), nvars);
1206 
1207  /* count number of varlocks for each variable (up + down locks) and multiply it by 2;
1208  * that value is used as an estimate of the number of arcs incident to the variable's node in the digraph
1209  */
1210  for( v = 0; v < nvars; ++v )
1211  varlocks[v] = 4 * (SCIPvarGetNLocksDown(vars[v]) + SCIPvarGetNLocksUp(vars[v]));
1212 
1213  /* create and fill directed graph */
1214  SCIP_CALL( SCIPdigraphCreate(&digraph, nvars) );
1215  SCIP_CALL( SCIPdigraphSetSizes(digraph, varlocks) );
1216  SCIP_CALL( fillDigraph(scip, digraph, conss, nconss, firstvaridxpercons, &success) );
1217 
1218  if( success )
1219  {
1220  int* components;
1221 
1222  SCIP_CALL( SCIPallocBufferArray(scip, &components, nvars) );
1223 
1224  /* compute independent components */
1225  SCIP_CALL( SCIPdigraphComputeUndirectedComponents(digraph, 1, components, &ncomponents) );
1226 
1227  SCIPdebugMessage("presol components found %d undirected components\n", ncomponents);
1228 
1229  /* We want to sort the components in increasing size (number of variables).
1230  * Therefore, we now get the number of variables for each component, and rename the components
1231  * such that for i < j, component i has no more variables than component j.
1232  * @todo Perhaps sort the components by the number of binary/integer variables?
1233  */
1234  if( ncomponents > 0 )
1235  {
1236  int* compsize;
1237  int* permu;
1238  int* compvars;
1239  int ncompvars;
1240  int nbinvars;
1241  int nintvars;
1242  int ncontvars;
1243 
1244  SCIP_CALL( SCIPallocBufferArray(scip, &compsize, ncomponents) );
1245  SCIP_CALL( SCIPallocBufferArray(scip, &permu, ncomponents) );
1246 
1247  /* get number of variables in the components */
1248  for( c = 0; c < ncomponents; ++c )
1249  {
1250  SCIPdigraphGetComponent(digraph, c, &compvars, &ncompvars);
1251  permu[c] = c;
1252  nbinvars = 0;
1253  nintvars = 0;
1254 
1255  for( v = 0; v < ncompvars; ++v )
1256  {
1257  /* check whether variable is of binary or integer type */
1258  if( SCIPvarGetType(vars[compvars[v]]) == SCIP_VARTYPE_BINARY )
1259  nbinvars++;
1260  else if( SCIPvarGetType(vars[compvars[v]]) == SCIP_VARTYPE_INTEGER )
1261  nintvars++;
1262  }
1263  ncontvars = ncompvars - nintvars - nbinvars;
1264  compsize[c] = (int)((1000 * (nbinvars + presoldata->intfactor * nintvars) + (950.0 * ncontvars)/nvars));
1265  }
1266 
1267  /* get permutation of component numbers such that the size of the components is increasing */
1268  SCIPsortIntInt(compsize, permu, ncomponents);
1269 
1270  /* now, we need the reverse direction, i.e., for each component number, we store its new number
1271  * such that the components are sorted; for this, we abuse the compsize array
1272  */
1273  for( c = 0; c < ncomponents; ++c )
1274  compsize[permu[c]] = c;
1275 
1276  /* for each variable, replace the old component number by the new one */
1277  for( c = 0; c < nvars; ++c )
1278  components[c] = compsize[components[c]];
1279 
1280  /* create subproblems from independent components and solve them in dependence of their size */
1281  SCIP_CALL( splitProblem(scip, presoldata, conss, vars, fixvals, nconss, nvars, components, ncomponents, firstvaridxpercons,
1282  &nsolvedprobs, &ndeletedvars, &ndeletedconss, result) );
1283 
1284  (*nfixedvars) += ndeletedvars;
1285  (*ndelconss) += ndeletedconss;
1286 
1287  SCIPfreeBufferArray(scip, &permu);
1288  SCIPfreeBufferArray(scip, &compsize);
1289  }
1290 
1291  SCIPfreeBufferArray(scip, &components);
1292  }
1293 
1294  SCIPdigraphFree(&digraph);
1295 
1296  SCIPfreeBufferArray(scip, &varlocks);
1297  SCIPfreeBufferArray(scip, &firstvaridxpercons);
1298  SCIPfreeBufferArray(scip, &fixvals);
1299  SCIPfreeBufferArray(scip, &vars);
1300  }
1301 
1302  SCIPfreeBufferArray(scip, &conss);
1303 
1304  /* update result to SCIP_SUCCESS, if reductions were found;
1305  * if result was set to infeasible or unbounded before, leave it as it is
1306  */
1307  if( (ndeletedvars > 0 || ndeletedconss > 0) && ((*result) == SCIP_DIDNOTFIND) )
1308  *result = SCIP_SUCCESS;
1309 
1310  /* print statistics */
1311  SCIPstatistic( printStatistics(presoldata) );
1312 
1313  SCIPdebugMessage("%d components, %d solved, %d deleted constraints, %d deleted variables, result = %d\n",
1314  ncomponents, nsolvedprobs, ndeletedconss, ndeletedvars, *result);
1315 #ifdef NDEBUG
1316  SCIPstatisticMessage("%d components, %d solved, %d deleted constraints, %d deleted variables, result = %d\n",
1317  ncomponents, nsolvedprobs, ndeletedconss, ndeletedvars, *result);
1318 #endif
1319 
1320  presoldata->lastnvars = SCIPgetNVars(scip);
1321 
1322  return SCIP_OKAY;
1323 }
1324 
1325 
1326 /*
1327  * Callback methods of presolver
1328  */
1329 
1330 /** destructor of presolver to free user data (called when SCIP is exiting) */
1331 static
1332 SCIP_DECL_PRESOLFREE(presolFreeComponents)
1333 { /*lint --e{715}*/
1334  SCIP_PRESOLDATA* presoldata;
1335 
1336  /* free presolver data */
1337  presoldata = SCIPpresolGetData(presol);
1338  assert(presoldata != NULL);
1339 
1340  SCIPfreeMemory(scip, &presoldata);
1341  SCIPpresolSetData(presol, NULL);
1342 
1343  return SCIP_OKAY;
1344 }
1345 
1346 /** initialization method of presolver (called after problem was transformed) */
1347 static
1348 SCIP_DECL_PRESOLINIT(presolInitComponents)
1349 { /*lint --e{715}*/
1350  SCIP_PRESOLDATA* presoldata;
1351 
1352  /* free presolver data */
1353  presoldata = SCIPpresolGetData(presol);
1354  assert(presoldata != NULL);
1355 
1356  /* initialize statistics */
1357  SCIPstatistic( SCIP_CALL( initStatistics(scip, presoldata) ) );
1358 
1359  presoldata->subscip = NULL;
1360  presoldata->didsearch = FALSE;
1361  presoldata->pluginscopied = TRUE;
1362 
1363  return SCIP_OKAY;
1364 }
1365 
1366 #ifdef SCIP_STATISTIC
1367 /** deinitialization method of presolver (called before transformed problem is freed) */
1368 static
1369 SCIP_DECL_PRESOLEXIT(presolExitComponents)
1370 { /*lint --e{715}*/
1371  SCIP_PRESOLDATA* presoldata;
1372 
1373  /* free presolver data */
1374  presoldata = SCIPpresolGetData(presol);
1375  assert(presoldata != NULL);
1376 
1377  SCIPstatistic( freeStatistics(scip, presoldata) );
1378 
1379  return SCIP_OKAY;
1380 }
1381 #endif
1382 
1383 
1384 /** execution method of presolver */
1385 static
1386 SCIP_DECL_PRESOLEXEC(presolExecComponents)
1387 { /*lint --e{715}*/
1388 
1389  SCIP_CALL( presolComponents(scip, presol, nfixedvars, ndelconss, result) );
1390 
1391  return SCIP_OKAY;
1392 }
1393 
1394 
1395 /*
1396  * presolver specific interface methods
1397  */
1398 
1399 /** creates the components presolver and includes it in SCIP */
1401  SCIP* scip /**< SCIP data structure */
1402  )
1403 {
1404  SCIP_PRESOLDATA* presoldata;
1405  SCIP_PRESOL* presol;
1406 
1407  /* create components presolver data */
1408  SCIP_CALL( SCIPallocMemory(scip, &presoldata) );
1409 
1410  /* include presolver */
1412  PRESOL_DELAY, presolExecComponents, presoldata) );
1413 
1414  /* currently, the components presolver is not copied; if a copy callback is added, we need to avoid recursion
1415  * by one of the following means:
1416  * - turn off the components presolver in SCIPsetSubscipsOff()
1417  * - call SCIPsetSubscipsOff() for the component sub-SCIP
1418  * - disable the components presolver in the components sub-SCIP
1419  */
1420  SCIP_CALL( SCIPsetPresolCopy(scip, presol, NULL) );
1421  SCIP_CALL( SCIPsetPresolFree(scip, presol, presolFreeComponents) );
1422  SCIP_CALL( SCIPsetPresolInit(scip, presol, presolInitComponents) );
1423  SCIPstatistic( SCIP_CALL( SCIPsetPresolExit(scip, presol, presolExitComponents) ) );
1424 
1425  /* add presolver parameters */
1427  "presolving/components/writeproblems",
1428  "should the single components be written as an .lp-file?",
1429  &presoldata->writeproblems, FALSE, DEFAULT_WRITEPROBLEMS, NULL, NULL) );
1430  SCIP_CALL( SCIPaddIntParam(scip,
1431  "presolving/components/maxintvars",
1432  "maximum number of integer (or binary) variables to solve a subproblem directly (-1: unlimited)",
1433  &presoldata->maxintvars, FALSE, DEFAULT_MAXINTVARS, -1, INT_MAX, NULL, NULL) );
1435  "presolving/components/nodelimit",
1436  "maximum number of nodes to be solved in subproblems",
1437  &presoldata->nodelimit, FALSE, DEFAULT_NODELIMIT, -1LL, SCIP_LONGINT_MAX, NULL, NULL) );
1439  "presolving/components/intfactor",
1440  "the weight of an integer variable compared to binary variables",
1441  &presoldata->intfactor, FALSE, DEFAULT_INTFACTOR, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1443  "presolving/components/reldecrease",
1444  "percentage by which the number of variables has to be decreased after the last component solving to allow running again (1.0: do not run again)",
1445  &presoldata->reldecrease, FALSE, DEFAULT_RELDECREASE, 0.0, 1.0, NULL, NULL) );
1447  "presolving/components/feastolfactor",
1448  "factor to increase the feasibility tolerance of the main SCIP in all sub-SCIPs, default value 1.0",
1449  &presoldata->feastolfactor, TRUE, DEFAULT_FEASTOLFACTOR, 0.0, 1000000.0, NULL, NULL) );
1450 
1451  return SCIP_OKAY;
1452 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:51
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip.c:20784
void SCIPpresolSetData(SCIP_PRESOL *presol, SCIP_PRESOLDATA *presoldata)
Definition: presol.c:474
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38254
SCIP_RETCODE SCIPincludePresolComponents(SCIP *scip)
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
Definition: scip.c:36923
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:10071
struct SCIP_PresolData SCIP_PRESOLDATA
Definition: type_presol.h:37
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:15788
SCIP_RETCODE SCIPgetConsVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int varssize, SCIP_Bool *success)
Definition: scip.c:23975
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip.c:897
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
Definition: scip.c:38360
#define PRESOL_DELAY
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:10913
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip.c:1206
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip.c:10026
#define SCIP_MAXSTRLEN
Definition: def.h:196
int SCIPpresolGetNCalls(SCIP_PRESOL *presol)
Definition: presol.c:757
SCIP_RETCODE SCIPdigraphComputeUndirectedComponents(SCIP_DIGRAPH *digraph, int minsize, int *components, int *ncomponents)
Definition: misc.c:5788
static SCIP_DECL_PRESOLFREE(presolFreeComponents)
#define NULL
Definition: lpi_spx.cpp:129
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:16426
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1111
SCIP_RETCODE SCIPsetPresolCopy(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLCOPY((*presolcopy)))
Definition: scip.c:5948
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:16380
#define PRESOL_PRIORITY
void SCIPsplitFilename(char *filename, char **path, char **name, char **extension, char **compression)
Definition: misc.c:7768
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition: scip.c:31639
#define DEFAULT_WRITEPROBLEMS
#define FALSE
Definition: def.h:52
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:1864
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
Definition: scip.c:37596
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition: scip.c:3869
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:10116
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:7579
#define TRUE
Definition: def.h:51
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:7577
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_RETCODE SCIPdigraphSetSizes(SCIP_DIGRAPH *digraph, int *sizes)
Definition: misc.c:5450
#define SCIPstatisticMessage
Definition: pub_message.h:104
SCIP_RETCODE SCIPsetRealParam(SCIP *scip, const char *name, SCIP_Real value)
Definition: scip.c:3914
SCIP_RETCODE SCIPgetConsCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_CONS *sourcecons, SCIP_CONS **targetcons, SCIP_CONSHDLR *sourceconshdlr, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *name, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode, SCIP_Bool global, SCIP_Bool *success)
Definition: scip.c:2212
int SCIPgetNActivePricers(SCIP *scip)
Definition: scip.c:4761
SCIP_RETCODE SCIPfreeTransform(SCIP *scip)
Definition: scip.c:13827
static SCIP_RETCODE copyAndSolveComponent(SCIP *scip, SCIP_PRESOLDATA *presoldata, SCIP_HASHMAP *consmap, int compnr, SCIP_CONS **conss, int nconss, SCIP_VAR **vars, SCIP_Real *fixvals, int nvars, int nbinvars, int nintvars, int *nsolvedprobs, int *ndeletedvars, int *ndeletedconss, SCIP_RESULT *result)
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.c:3442
#define DEFAULT_INTFACTOR
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip.c:31775
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:19214
static SCIP_DECL_PRESOLEXEC(presolExecComponents)
void SCIPdigraphGetComponent(SCIP_DIGRAPH *digraph, int compidx, int **nodes, int *nnodes)
Definition: misc.c:5977
static SCIP_RETCODE splitProblem(SCIP *scip, SCIP_PRESOLDATA *presoldata, SCIP_CONS **conss, SCIP_VAR **vars, SCIP_Real *fixvals, int nconss, int nvars, int *components, int ncomponents, int *firstvaridxpercons, int *nsolvedprobs, int *ndeletedvars, int *ndeletedconss, SCIP_RESULT *result)
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:16227
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:1923
#define SCIP_LONGINT_MAX
Definition: def.h:108
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip.c:23934
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip.c:22651
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:19215
SCIP_RETCODE SCIPcheckSolOrig(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *feasible, SCIP_Bool printreason, SCIP_Bool completely)
Definition: scip.c:33227
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:31855
#define DEFAULT_NODELIMIT
int SCIPgetNSols(SCIP *scip)
Definition: scip.c:32432
SCIP_PRESOLDATA * SCIPpresolGetData(SCIP_PRESOL *presol)
Definition: presol.c:464
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.c:3388
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:1966
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.c:3414
void SCIPsortIntPtr(int *intarray, void **ptrarray, int len)
SCIP_RETCODE SCIPdigraphCreate(SCIP_DIGRAPH **digraph, int nnodes)
Definition: misc.c:5326
#define PRESOL_DESC
int SCIPgetNConss(SCIP *scip)
Definition: scip.c:11109
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38273
SCIP_RETCODE SCIPcopyParamSettings(SCIP *sourcescip, SCIP *targetscip)
Definition: scip.c:3005
SCIP_RETCODE SCIPcheckSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *feasible)
Definition: scip.c:33181
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
Definition: scip.c:38421
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:19159
#define SCIPerrorMessage
Definition: pub_message.h:45
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:19221
static SCIP_RETCODE presolComponents(SCIP *scip, SCIP_PRESOL *presol, int *nfixedvars, int *ndelconss, SCIP_RESULT *result)
void SCIPsortIntInt(int *intarray1, int *intarray2, int len)
SCIP_RETCODE SCIPsetPresolInit(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLINIT((*presolinit)))
Definition: scip.c:5980
static SCIP_DECL_PRESOLINIT(presolInitComponents)
#define SCIP_DECL_PRESOLEXIT(x)
Definition: type_presol.h:70
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38292
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip.c:37940
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:7557
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38648
SCIP_PRESOL * SCIPfindPresol(SCIP *scip, const char *name)
Definition: scip.c:6044
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:1882
SCIP_RETCODE SCIPcreateProb(SCIP *scip, const char *name, SCIP_DECL_PROBDELORIG((*probdelorig)), SCIP_DECL_PROBTRANS((*probtrans)), SCIP_DECL_PROBDELTRANS((*probdeltrans)), SCIP_DECL_PROBINITSOL((*probinitsol)), SCIP_DECL_PROBEXITSOL((*probexitsol)), SCIP_DECL_PROBCOPY((*probcopy)), SCIP_PROBDATA *probdata)
Definition: scip.c:8453
#define DEFAULT_RELDECREASE
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3214
#define SCIP_CALL(x)
Definition: def.h:258
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip.c:755
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip.c:29454
SCIP_RETCODE SCIPdigraphAddArc(SCIP_DIGRAPH *digraph, int startnode, int endnode, void *data)
Definition: misc.c:5544
SCIP_RETCODE SCIPgetActiveVars(SCIP *scip, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: scip.c:15706
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38311
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:18371
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:16436
SCIP_Bool SCIPisPresolveFinished(SCIP *scip)
Definition: scip.c:1020
#define SCIP_Bool
Definition: def.h:49
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip.c:3824
SCIP_RETCODE SCIPsetPresolFree(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLFREE((*presolfree)))
Definition: scip.c:5964
void SCIPprintSysError(const char *message)
Definition: misc.c:7515
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip.c:790
SCIP_Real SCIPsolGetOrigObj(SCIP_SOL *sol)
Definition: sol.c:2129
SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
Definition: scip.c:3550
#define MAX(x, y)
Definition: tclique_def.h:75
components presolver
SCIP_Longint SCIPgetMemUsed(SCIP *scip)
Definition: scip.c:37975
SCIP_RETCODE SCIPsetPresolExit(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLEXIT((*presolexit)))
Definition: scip.c:5996
#define SCIPfreeMemoryArray(scip, ptr)
Definition: scip.h:19178
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:102
#define SCIPallocMemoryArray(scip, ptr, num)
Definition: scip.h:19161
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip.c:1256
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38330
#define DEFAULT_MAXINTVARS
#define SCIP_REAL_MAX
Definition: def.h:124
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:10850
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip.c:13596
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:15953
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:19176
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:16370
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip.c:682
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1239
SCIP_CONS ** SCIPgetConss(SCIP *scip)
Definition: scip.c:11155
int SCIPgetNIntVars(SCIP *scip)
Definition: scip.c:10161
SCIP_RETCODE SCIPcreateOrigSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip.c:31072
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38686
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16072
SCIP_RETCODE SCIPwriteOrigProblem(SCIP *scip, const char *filename, const char *extension, SCIP_Bool genericnames)
Definition: scip.c:8926
#define SCIPstatistic(x)
Definition: pub_message.h:101
SCIP_RETCODE SCIPgetConsNVars(SCIP *scip, SCIP_CONS *cons, int *nvars, SCIP_Bool *success)
Definition: scip.c:24019
#define SCIP_Real
Definition: def.h:123
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:7736
#define DEFAULT_FEASTOLFACTOR
#define PRESOL_MAXROUNDS
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:18477
#define MIN(x, y)
Definition: memory.c:59
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38724
const char * SCIPgetProbName(SCIP *scip)
Definition: scip.c:9314
#define SCIP_Longint
Definition: def.h:107
#define PRESOL_NAME
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition: scip.c:3779
SCIP_RETCODE SCIPcopyPlugins(SCIP *sourcescip, SCIP *targetscip, SCIP_Bool copyreaders, SCIP_Bool copypricers, SCIP_Bool copyconshdlrs, SCIP_Bool copyconflicthdlrs, SCIP_Bool copypresolvers, SCIP_Bool copyrelaxators, SCIP_Bool copyseparators, SCIP_Bool copypropagators, SCIP_Bool copyheuristics, SCIP_Bool copyeventhdlrs, SCIP_Bool copynodeselectors, SCIP_Bool copybranchrules, SCIP_Bool copydisplays, SCIP_Bool copydialogs, SCIP_Bool copynlpis, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
Definition: scip.c:1422
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition: scip.c:3638
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:98
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
Definition: scip.c:38409
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition: scip.c:32531
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.c:3470
void SCIPdigraphFree(SCIP_DIGRAPH **digraph)
Definition: misc.c:5472
static SCIP_RETCODE fillDigraph(SCIP *scip, SCIP_DIGRAPH *digraph, SCIP_CONS **conss, int nconss, int *firstvaridxpercons, SCIP_Bool *success)
SCIP_RETCODE SCIPincludePresolBasic(SCIP *scip, SCIP_PRESOL **presolptr, const char *name, const char *desc, int priority, int maxrounds, SCIP_Bool delay, SCIP_DECL_PRESOLEXEC((*presolexec)), SCIP_PRESOLDATA *presoldata)
Definition: scip.c:5913
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3159
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip.c:31403
SCIP_Longint SCIPgetMemExternEstim(SCIP *scip)
Definition: scip.c:37988