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-2016 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_TIMING SCIP_PRESOLTIMING_EXHAUSTIVE /* timing of the presolver (fast, medium, or exhaustive) */
45 
46 #define DEFAULT_WRITEPROBLEMS FALSE /**< should the single components be written as an .cip-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 .cip-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  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_comp_%d.set", SCIPgetProbName(scip), compnr);
424  SCIPdebugMessage("write settings to file %s\n", name);
425  SCIP_CALL( SCIPwriteParams(subscip, name, TRUE, TRUE) );
426  }
427 
428  /* the following asserts are not true, because some aggregations in the original scip instance could not get resolved
429  * inside some constraints, so the copy (subscip) will have also some inactive variables which were copied
430  */
431 #if 0
432  /* there might be less variables in the subscip, because variables might be cancelled out during copying constraint
433  * when transferring variables to active variables
434  */
435  assert(nbinvars >= SCIPgetNBinVars(subscip));
436  assert(nintvars >= SCIPgetNIntVars(subscip));
437 #endif
438 
439  /* In extended debug mode, we want to be informed if the number of variables was reduced during copying.
440  * This might happen, since the components presolver uses SCIPgetConsVars() and then SCIPgetActiveVars() to get the
441  * active representation, while SCIPgetConsCopy() might use SCIPgetProbvarLinearSum() and this might cancel out some
442  * of the active variables and cannot be avoided. However, we want to notice it and check whether the constraint
443  * handler could do something more clever.
444  */
445 #ifdef SCIP_MORE_DEBUG
446  if( nvars > SCIPgetNVars(subscip) )
447  {
448  SCIPinfoMessage(scip, NULL, "copying component %d reduced number of variables: %d -> %d\n", compnr, nvars, SCIPgetNVars(subscip));
449  }
450 #endif
451 
452  if( presoldata->maxintvars == -1 || (SCIPgetNBinVars(subscip) + presoldata->intfactor * SCIPgetNIntVars(subscip) <= presoldata->maxintvars) )
453  {
454  SCIP_RETCODE retcode;
455 
456  /* solve the subproblem */
457  retcode = SCIPsolve(subscip);
458 
459  /* errors in solving the subproblem should not kill the overall solving process;
460  * hence, the return code is caught and a warning is printed, only when more debugging is enabled, SCIP will stop
461  */
462  if( retcode != SCIP_OKAY )
463  {
464 #ifdef SCIP_MORE_DEBUG
465  SCIP_CALL( retcode );
466 #endif
467  SCIPwarningMessage(scip, "Error while solving subproblem in components presolver; sub-SCIP terminated with code <%d>\n", retcode);
468  }
469  else
470  {
471 #ifdef SCIP_MORE_DEBUG
472  SCIP_CALL( SCIPprintStatistics(subscip, NULL) );
473 #endif
474 
475  SCIPstatistic( updateStatisticsSubsolvetime(presoldata, SCIPgetSolvingTime(subscip)) );
476 
477  if( SCIPgetStatus(subscip) == SCIP_STATUS_OPTIMAL )
478  {
479  SCIP_SOL* sol;
480  SCIP_VAR* subvar;
481  SCIP_Bool feasible;
482  SCIP_Bool infeasible;
483  SCIP_Bool fixed;
484 
485  ++(*nsolvedprobs);
486 
487  sol = SCIPgetBestSol(subscip);
488 
489 #ifdef SCIP_DEBUG
490  SCIP_CALL( SCIPcheckSolOrig(subscip, sol, &feasible, TRUE, TRUE) );
491 #else
492  SCIP_CALL( SCIPcheckSolOrig(subscip, sol, &feasible, FALSE, FALSE) );
493 #endif
494 
495  SCIPdebugMessage("--> solved to optimality: time=%.2f, solution is%s feasible\n", SCIPgetSolvingTime(subscip), feasible ? "" : " not");
496 
497  if( feasible )
498  {
499  SCIP_Real glb;
500  SCIP_Real gub;
501 
502  /* get values of variables in the optimal solution */
503  for( i = 0; i < nvars; ++i )
504  {
505  subvar = (SCIP_VAR*)SCIPhashmapGetImage(varmap, vars[i]);
506 
507  /* get global bounds */
508  glb = SCIPvarGetLbGlobal(vars[i]);
509  gub = SCIPvarGetUbGlobal(vars[i]);
510 
511  if( subvar != NULL )
512  {
513  /* get solution value from optimal solution of the component */
514  fixvals[i] = SCIPgetSolVal(subscip, sol, subvar);
515 
516  assert(SCIPisFeasLE(scip, fixvals[i], SCIPvarGetUbLocal(vars[i])));
517  assert(SCIPisFeasGE(scip, fixvals[i], SCIPvarGetLbLocal(vars[i])));
518 
519  /* checking a solution is done with a relative tolerance of feasibility epsilon, if we really want to
520  * change the bounds of the variables by fixing them, the old bounds must not be violated by more than
521  * the absolute epsilon; therefore, we change the fixing values, if needed, and mark that the solution
522  * has to be checked again
523  */
524  if( SCIPisGT(scip, fixvals[i], gub) )
525  {
526  SCIPdebugMessage("variable <%s> fixval: %f violates global upperbound: %f\n",
527  SCIPvarGetName(vars[i]), fixvals[i], gub);
528  fixvals[i] = gub;
529  feasible = FALSE;
530  }
531  else if( SCIPisLT(scip, fixvals[i], glb) )
532  {
533  SCIPdebugMessage("variable <%s> fixval: %f violates global lowerbound: %f\n",
534  SCIPvarGetName(vars[i]), fixvals[i], glb);
535  fixvals[i] = glb;
536  feasible = FALSE;
537  }
538  assert(SCIPisLE(scip, fixvals[i], SCIPvarGetUbLocal(vars[i])));
539  assert(SCIPisGE(scip, fixvals[i], SCIPvarGetLbLocal(vars[i])));
540  }
541  else
542  {
543  /* the variable was not copied, so it was cancelled out of constraints during copying;
544  * thus, the variable is not constrained and we fix it to its best bound
545  */
546  if( SCIPisPositive(scip, SCIPvarGetObj(vars[i])) )
547  fixvals[i] = glb;
548  else if( SCIPisNegative(scip, SCIPvarGetObj(vars[i])) )
549  fixvals[i] = gub;
550  else
551  {
552  fixvals[i] = 0.0;
553  fixvals[i] = MIN(fixvals[i], gub);
554  fixvals[i] = MAX(fixvals[i], glb);
555  }
556  }
557  }
558 
559  /* the solution value of at least one variable is feasible with a relative tolerance of feasibility epsilon,
560  * but infeasible with an absolute tolerance of epsilon; try to set the variables to the bounds and check
561  * solution again (changing the values might now introduce infeasibilities of constraints)
562  */
563  if( !feasible )
564  {
565  SCIP_Real origobj;
566 
567  SCIPdebugMessage("solution violates bounds by more than epsilon, check the corrected solution...\n");
568 
569  origobj = SCIPgetSolOrigObj(subscip, SCIPgetBestSol(subscip));
570 
571  SCIP_CALL( SCIPfreeTransform(subscip) );
572 
573  SCIP_CALL( SCIPcreateOrigSol(subscip, &sol, NULL) );
574 
575  /* get values of variables in the optimal solution */
576  for( i = 0; i < nvars; ++i )
577  {
578  subvar = (SCIP_VAR*)SCIPhashmapGetImage(varmap, vars[i]);
579 
580  SCIP_CALL( SCIPsetSolVal(subscip, sol, subvar, fixvals[i]) );
581  }
582 
583  /* check the solution; integrality and bounds should be fulfilled and do not have to be checked */
584  SCIP_CALL( SCIPcheckSol(subscip, sol, FALSE, FALSE, FALSE, TRUE, &feasible) );
585 
586 #ifndef NDEBUG
587  /* in debug mode, we additionally check integrality and bounds */
588  if( feasible )
589  {
590  SCIP_CALL( SCIPcheckSol(subscip, sol, FALSE, TRUE, TRUE, FALSE, &feasible) );
591  assert(feasible);
592  }
593 #endif
594 
595  SCIPdebugMessage("--> corrected solution is%s feasible\n", feasible ? "" : " not");
596 
597  if( !SCIPisFeasEQ(subscip, SCIPsolGetOrigObj(sol), origobj) )
598  {
599  SCIPdebugMessage("--> corrected solution has a different objective value (old=%16.9g, corrected=%16.9g)\n",
600  origobj, SCIPsolGetOrigObj(sol));
601 
602  feasible = FALSE;
603  }
604 
605  SCIP_CALL( SCIPfreeSol(subscip, &sol) );
606  }
607 
608  /* if the solution is feasible, fix variables and delete constraints of the component */
609  if( feasible )
610  {
611  /* fix variables */
612  for( i = 0; i < nvars; ++i )
613  {
614  assert(SCIPisLE(scip, fixvals[i], SCIPvarGetUbLocal(vars[i])));
615  assert(SCIPisGE(scip, fixvals[i], SCIPvarGetLbLocal(vars[i])));
616  assert(SCIPisLE(scip, fixvals[i], SCIPvarGetUbGlobal(vars[i])));
617  assert(SCIPisGE(scip, fixvals[i], SCIPvarGetLbGlobal(vars[i])));
618 
619  SCIP_CALL( SCIPfixVar(scip, vars[i], fixvals[i], &infeasible, &fixed) );
620  assert(!infeasible);
621  assert(fixed);
622  (*ndeletedvars)++;
623  }
624 
625  /* delete constraints */
626  for( i = 0; i < nconss; ++i )
627  {
628  SCIP_CALL( SCIPdelCons(scip, conss[i]) );
629  (*ndeletedconss)++;
630  }
631  }
632  }
633  }
634  else if( SCIPgetStatus(subscip) == SCIP_STATUS_INFEASIBLE )
635  {
636  *result = SCIP_CUTOFF;
637  }
638  else if( SCIPgetStatus(subscip) == SCIP_STATUS_UNBOUNDED || SCIPgetStatus(subscip) == SCIP_STATUS_INFORUNBD )
639  {
640  /* TODO: store unbounded ray in original SCIP data structure */
641  *result = SCIP_UNBOUNDED;
642  }
643  else
644  {
645  SCIPdebugMessage("--> solving interrupted (status=%d, time=%.2f)\n",
646  SCIPgetStatus(subscip), SCIPgetSolvingTime(subscip));
647 
648  /* transfer global fixings to the original problem; we can only do this, if we did not find a solution in the
649  * subproblem, because otherwise, the primal bound might lead to dual reductions that cannot be transferred to
650  * the original problem without also transferring the possibly suboptimal solution (which is currently not
651  * possible)
652  */
653  if( SCIPgetNSols(subscip) == 0 )
654  {
655  SCIP_Bool infeasible;
656  SCIP_Bool tightened;
657  int ntightened;
658 
659  ntightened = 0;
660 
661  for( i = 0; i < nvars; ++i )
662  {
663  assert( SCIPhashmapExists(varmap, vars[i]) );
664 
665  SCIP_CALL( SCIPtightenVarLb(scip, vars[i], SCIPvarGetLbGlobal((SCIP_VAR*)SCIPhashmapGetImage(varmap, vars[i])), FALSE,
666  &infeasible, &tightened) );
667  assert(!infeasible);
668  if( tightened )
669  ntightened++;
670 
671  SCIP_CALL( SCIPtightenVarUb(scip, vars[i], SCIPvarGetUbGlobal((SCIP_VAR*)SCIPhashmapGetImage(varmap, vars[i])), FALSE,
672  &infeasible, &tightened) );
673  assert(!infeasible);
674  if( tightened )
675  ntightened++;
676  }
677  SCIPdebugMessage("--> tightened %d bounds of variables due to global bounds in the sub-SCIP\n", ntightened);
678  }
679  }
680  }
681  }
682  else
683  {
684  SCIPdebugMessage("--> not solved (too many integer variables)\n");
685  }
686 
687  TERMINATE:
688  SCIPhashmapFree(&varmap);
689 
690  return SCIP_OKAY;
691 }
692 
693 /** loop over constraints, get active variables and fill directed graph */
694 static
696  SCIP* scip, /**< SCIP data structure */
697  SCIP_DIGRAPH* digraph, /**< directed graph */
698  SCIP_CONS** conss, /**< constraints */
699  int nconss, /**< number of constraints */
700  int* firstvaridxpercons, /**< array to store for each constraint the index in the local vars array
701  * of the first variable of the constraint */
702  SCIP_Bool* success /**< flag indicating successful directed graph filling */
703  )
704 {
705  SCIP_VAR** consvars;
706  int requiredsize;
707  int nconsvars;
708  int nvars;
709  int idx1;
710  int idx2;
711  int c;
712  int v;
713 
714  assert(scip != NULL);
715  assert(digraph != NULL);
716  assert(conss != NULL);
717  assert(firstvaridxpercons != NULL);
718  assert(success != NULL);
719 
720  *success = TRUE;
721 
722  nconsvars = 0;
723  requiredsize = 0;
724  nvars = SCIPgetNVars(scip);
725 
726  /* use big buffer for storing active variables per constraint */
727  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nvars) );
728 
729  for( c = 0; c < nconss; ++c )
730  {
731  /* check for reached timelimit */
732  if( (c % 1000 == 0) && SCIPisStopped(scip) )
733  {
734  *success = FALSE;
735  break;
736  }
737 
738  /* get number of variables for this constraint */
739  SCIP_CALL( SCIPgetConsNVars(scip, conss[c], &nconsvars, success) );
740 
741  if( !(*success) )
742  break;
743 
744  if( nconsvars > nvars )
745  {
746  nvars = nconsvars;
747  SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, nvars) );
748  }
749 
750 #ifndef NDEBUG
751  /* clearing variables array to check for consistency */
752  if( nconsvars == nvars )
753  {
754  BMSclearMemoryArray(consvars, nconsvars);
755  }
756  else
757  {
758  assert(nconsvars < nvars);
759  BMSclearMemoryArray(consvars, nconsvars + 1);
760  }
761 #endif
762 
763  /* get variables for this constraint */
764  SCIP_CALL( SCIPgetConsVars(scip, conss[c], consvars, nvars, success) );
765 
766  if( !(*success) )
767  {
768 #ifndef NDEBUG
769  /* it looks strange if returning the number of variables was successful but not returning the variables */
770  SCIPwarningMessage(scip, "constraint <%s> returned number of variables but returning variables failed\n", SCIPconsGetName(conss[c]));
771 #endif
772  break;
773  }
774 
775 #ifndef NDEBUG
776  /* check if returned variables are consistent with the number of variables that were returned */
777  for( v = nconsvars - 1; v >= 0; --v )
778  assert(consvars[v] != NULL);
779  if( nconsvars < nvars )
780  assert(consvars[nconsvars] == NULL);
781 #endif
782 
783  /* transform given variables to active variables */
784  SCIP_CALL( SCIPgetActiveVars(scip, consvars, &nconsvars, nvars, &requiredsize) );
785  assert(requiredsize <= nvars);
786 
787  if( nconsvars > 0 )
788  {
789  idx1 = SCIPvarGetProbindex(consvars[0]);
790  assert(idx1 >= 0);
791 
792  /* save index of the first variable for later component assignment */
793  firstvaridxpercons[c] = idx1;
794 
795  if( nconsvars > 1 )
796  {
797  /* create sparse directed graph
798  * sparse means, to add only those edges necessary for component calculation
799  */
800  for( v = 1; v < nconsvars; ++v )
801  {
802  idx2 = SCIPvarGetProbindex(consvars[v]);
803  assert(idx2 >= 0);
804 
805  /* we add only one directed edge, because the other direction is automatically added for component computation */
806  SCIP_CALL( SCIPdigraphAddArc(digraph, idx1, idx2, NULL) );
807  }
808  }
809  }
810  else
811  firstvaridxpercons[c] = -1;
812  }
813 
814  SCIPfreeBufferArray(scip, &consvars);
815 
816  return SCIP_OKAY;
817 }
818 
819 #ifdef COMPONENTS_PRINT_STRUCTURE
820 
821 static
822 SCIP_RETCODE printStructure(
823  SCIP* scip, /**< SCIP data structure */
824  SCIP_VAR** vars, /**< variables */
825  SCIP_CONS** conss, /**< constraints */
826  int* components, /**< array with component number for every variable */
827  int* conscomponents, /**< array with component number for every constraint */
828  int nvars, /**< number of variables */
829  int nconss, /**< number of constraints */
830  int ncomponents /**< number of components */
831  )
832 {
833  char probname[SCIP_MAXSTRLEN];
834  char outname[SCIP_MAXSTRLEN];
835  char filename[SCIP_MAXSTRLEN];
836  char* name;
837  FILE* file;
838  SCIP_VAR** consvars;
839  SCIP_VAR* var;
840  int* varidx;
841  int* compstartvars;
842  int* compstartconss;
843  int ncalls;
844  int requiredsize;
845  int nconsvars;
846  int i;
847  int c;
848  int v;
849  SCIP_Bool success;
850 
851  SCIP_CALL( SCIPallocBufferArray(scip, &varidx, nvars) );
852  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nvars) );
853  SCIP_CALL( SCIPallocBufferArray(scip, &compstartvars, ncomponents + 1) );
854  SCIP_CALL( SCIPallocBufferArray(scip, &compstartconss, ncomponents + 1) );
855 
857  compstartvars[0] = 0;
858  compstartconss[0] = 0;
859 
860  for( v = 0; v < nvars; ++v )
861  {
862  assert(v == 0 || components[v] == components[v-1] || components[v] == components[v-1]+1);
863  varidx[SCIPvarGetProbindex(vars[v])] = v;
864 
865  if( v > 0 && components[v] == components[v-1] + 1 )
866  {
867  compstartvars[components[v]] = v;
868  }
869  }
870 
871  for( v = 0; v < nconss; ++v )
872  {
873  assert(v == 0 || conscomponents[v] == conscomponents[v-1] || conscomponents[v] == conscomponents[v-1]+1);
874 
875  if( v > 0 && conscomponents[v] == conscomponents[v-1] + 1 )
876  {
877  compstartconss[conscomponents[v]] = v;
878  }
879  }
880 
881  compstartvars[ncomponents] = nvars;
882  compstartconss[ncomponents] = nconss;
883 
884  /* split problem name */
885  (void) SCIPsnprintf(probname, SCIP_MAXSTRLEN, "%s", SCIPgetProbName(scip));
886  SCIPsplitFilename(probname, NULL, &name, NULL, NULL);
887 
888  /* define file name depending on instance name, number of presolver calls and number of components */
889  (void) SCIPsnprintf(outname, SCIP_MAXSTRLEN, "%s_%d_%d", name, ncalls, ncomponents);
890  (void) SCIPsnprintf(filename, SCIP_MAXSTRLEN, "%s.gp", outname);
891 
892  /* open output file */
893  file = fopen(filename, "w");
894  if( file == NULL )
895  {
896  SCIPerrorMessage("cannot create file <%s> for writing\n", filename);
897  SCIPprintSysError(filename);
898  return SCIP_FILECREATEERROR;
899  }
900 
901  /* print header of gnuplot file */
902  SCIPinfoMessage(scip, file, "set terminal pdf\nset output \"%s.pdf\"\nunset xtics\nunset ytics\n\n", outname);
903  SCIPinfoMessage(scip, file, "unset border\nunset key\nset style fill solid 1.0 noborder\nset size ratio -1\n");
904  SCIPinfoMessage(scip, file, "set xrange [0:%d]\nset yrange[%d:0]\n", nvars + 1, nconss + 1);
905 
906  /* write rectangles around blocks */
907  for( i = 0; i < ncomponents; ++i )
908  {
909  assert(compstartvars[i] <= nvars);
910  assert(compstartconss[i] <= nconss);
911  assert(compstartvars[i+1] <= nvars);
912  assert(compstartconss[i+1] <= nconss);
913  SCIPinfoMessage(scip, file, "set object %d rect from %.1f,%.1f to %.1f,%.1f fc rgb \"grey\"\n",
914  i + 1, nvars - compstartvars[i] + 0.5, nconss - compstartconss[i] + 0.5,
915  nvars - compstartvars[i+1] + 0.5, nconss - compstartconss[i+1] + 0.5);
916  }
917 
918  /* write the plot header */
919  SCIPinfoMessage(scip, file, "plot \"-\" using 1:2:3 with circles fc rgb \"black\"\n");
920 
921  /* write data */
922  for( c = 0; c < nconss; ++c )
923  {
924  /* get variables for this constraint */
925  SCIP_CALL( SCIPgetConsNVars(scip, conss[c], &nconsvars, &success) );
926  SCIP_CALL( SCIPgetConsVars(scip, conss[c], consvars, nvars, &success) );
927  assert(success);
928 
929  /* transform given variables to active variables */
930  SCIP_CALL( SCIPgetActiveVars(scip, consvars, &nconsvars, nvars, &requiredsize) );
931  assert(requiredsize <= nvars);
932 
933  for( v = 0; v < nconsvars; ++v )
934  {
935  var = consvars[v];
936  SCIPinfoMessage(scip, file, "%d %d 0.5\n", nvars - varidx[SCIPvarGetProbindex(var)], nconss - c);
937  }
938  }
939 
940  /* write file end */
941  SCIPinfoMessage(scip, file, "e\n");
942 
943  (void) fclose(file);
944 
945  SCIPfreeBufferArray(scip, &compstartconss);
946  SCIPfreeBufferArray(scip, &compstartvars);
947  SCIPfreeBufferArray(scip, &consvars);
948  SCIPfreeBufferArray(scip, &varidx);
949 
950  return SCIP_OKAY;
951 }
952 
953 #endif
954 
955 /** use components to assign variables and constraints to the subscips
956  * and try to solve all subscips having not too many integer variables
957  */
958 static
960  SCIP* scip, /**< SCIP data structure */
961  SCIP_PRESOLDATA* presoldata, /**< presolver data */
962  SCIP_CONS** conss, /**< constraints */
963  SCIP_VAR** vars, /**< variables */
964  SCIP_Real* fixvals, /**< array to store the fixing values */
965  int nconss, /**< number of constraints */
966  int nvars, /**< number of variables */
967  int* components, /**< array with component number for every variable */
968  int ncomponents, /**< number of components */
969  int* firstvaridxpercons, /**< array with index of first variable in vars array for each constraint */
970  int* nsolvedprobs, /**< pointer to store the number of solved subproblems */
971  int* ndeletedvars, /**< pointer to store the number of deleted variables */
972  int* ndeletedconss, /**< pointer to store the number of deleted constraints */
973  SCIP_RESULT* result /**< pointer to store the result of the presolving call */
974  )
975 {
976  SCIP_HASHMAP* consmap;
977  SCIP_CONS** compconss;
978  SCIP_VAR** compvars;
979  SCIP_Real* compfixvals;
980  int* conscomponent;
981  int ncompconss;
982  int ncompvars;
983  int nbinvars;
984  int nintvars;
985  int comp;
986  int compvarsstart;
987  int compconssstart;
988  int nfreevars = 0;
989  int v;
990  int c;
991 
992  assert(scip != NULL);
993  assert(presoldata != NULL);
994  assert(conss != NULL);
995  assert(components != NULL);
996  assert(firstvaridxpercons != NULL);
997  assert(nsolvedprobs != NULL);
998  assert(result != NULL);
999 
1000  *nsolvedprobs = 0;
1001 
1002  /* hashmap mapping from original constraints to constraints in the sub-SCIPs (for performance reasons) */
1003  SCIP_CALL( SCIPhashmapCreate(&consmap, SCIPblkmem(scip), 10 * SCIPgetNConss(scip)) );
1004 
1005  SCIP_CALL( SCIPallocBufferArray(scip, &conscomponent, nconss) );
1006 
1007  /* do the mapping from calculated components per variable to corresponding
1008  * constraints and sort the component-arrays for faster finding the
1009  * actual variables and constraints belonging to one component
1010  */
1011  for( c = 0; c < nconss; c++ )
1012  conscomponent[c] = (firstvaridxpercons[c] == -1 ? -1 : components[firstvaridxpercons[c]]);
1013 
1014  SCIPsortIntPtr(components, (void**)vars, nvars);
1015  SCIPsortIntPtr(conscomponent, (void**)conss, nconss);
1016 
1017 #ifdef COMPONENTS_PRINT_STRUCTURE
1018  SCIP_CALL( printStructure(scip, vars, conss, components, conscomponent, nvars, nconss, ncomponents) );
1019 #endif
1020 
1021  compvarsstart = 0;
1022  compconssstart = 0;
1023 
1024  while( compconssstart < nconss && conscomponent[compconssstart] == -1 )
1025  ++compconssstart;
1026 
1027  /* loop over all components */
1028  for( comp = 0; comp < ncomponents && !SCIPisStopped(scip); comp++ )
1029  {
1030  nbinvars = 0;
1031  nintvars = 0;
1032 
1033  /* count variables present in this component and categorize them */
1034  for( v = compvarsstart; v < nvars && components[v] == comp; ++v )
1035  {
1036  /* check whether variable is of binary or integer type */
1037  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
1038  nbinvars++;
1039  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_INTEGER )
1040  nintvars++;
1041  }
1042 
1043  /* count constraints present in this component */
1044  c = compconssstart;
1045  while( c < nconss && conscomponent[c] == comp )
1046  ++c;
1047 
1048  /* collect some statistical information */
1049  SCIPstatistic( updateStatisticsComp(presoldata, nbinvars, nintvars) );
1050 
1051  compvars = &(vars[compvarsstart]);
1052  compfixvals = &(fixvals[compvarsstart]);
1053  compconss = &(conss[compconssstart]);
1054  ncompvars = v - compvarsstart;
1055  ncompconss = c - compconssstart;
1056  compvarsstart = v;
1057  compconssstart = c;
1058 
1059  /* the dual fixing presolver will take care of the case ncompconss == 0 */
1060  assert(ncompconss > 0 || ncompvars == 1);
1061 
1062  if( ncompconss == 0 )
1063  nfreevars += ncompvars;
1064 
1065  /* we do not want to solve the component, if it is the last unsolved one */
1066  if( ncompconss > 0 && ncompvars + nfreevars < SCIPgetNVars(scip) )
1067  {
1068  SCIP_RESULT subscipresult;
1069 
1070  assert(ncompconss > 0);
1071 
1072  /* in extended debug mode, we want to be informed about components with single constraints;
1073  * this is only for noticing this case and possibly handling it within the constraint handler
1074  */
1075 #ifdef SCIP_MORE_DEBUG
1076  if( ncompconss == 1 )
1077  {
1078  SCIPinfoMessage(scip, NULL, "presol component detected component with a single constraint:\n");
1079  SCIP_CALL( SCIPprintCons(scip, compconss[0], NULL) );
1080  SCIPinfoMessage(scip, NULL, ";\n");
1081  }
1082 #endif
1083 
1084  /* build subscip for one component and try to solve it */
1085  SCIP_CALL( copyAndSolveComponent(scip, presoldata, consmap, comp, compconss, ncompconss, compvars,
1086  compfixvals, ncompvars, nbinvars, nintvars, nsolvedprobs, ndeletedvars, ndeletedconss,
1087  &subscipresult) );
1088 
1089  if( subscipresult == SCIP_CUTOFF || subscipresult == SCIP_UNBOUNDED )
1090  {
1091  *result = subscipresult;
1092  break;
1093  }
1094 
1095  if( !presoldata->pluginscopied )
1096  break;
1097  }
1098  }
1099 
1100  if( presoldata->subscip != NULL )
1101  {
1102  SCIP_CALL( SCIPfree(&presoldata->subscip) );
1103  presoldata->subscip = NULL;
1104  }
1105 
1106  SCIPfreeBufferArray(scip, &conscomponent);
1107  SCIPhashmapFree(&consmap);
1108 
1109  return SCIP_OKAY;
1110 }
1111 
1112 /** performs presolving by searching for components */
1113 static
1115  SCIP* scip, /**< SCIP main data structure */
1116  SCIP_PRESOL* presol, /**< the presolver itself */
1117  int* nfixedvars, /**< counter to increase by the number of fixed variables */
1118  int* ndelconss, /**< counter to increase by the number of deleted constrains */
1119  SCIP_RESULT* result /**< pointer to store the result of the presolving call */
1120  )
1121 {
1122  SCIP_PRESOLDATA* presoldata;
1123  SCIP_CONS** conss;
1124  SCIP_CONS** tmpconss;
1125  SCIP_Bool success;
1126  int nconss;
1127  int ntmpconss;
1128  int nvars;
1129  int ncomponents;
1130  int ndeletedconss;
1131  int ndeletedvars;
1132  int nsolvedprobs;
1133  int c;
1134 
1135  assert(scip != NULL);
1136  assert(presol != NULL);
1137  assert(result != NULL);
1138 
1139  *result = SCIP_DIDNOTRUN;
1140 
1141  if( SCIPgetStage(scip) != SCIP_STAGE_PRESOLVING || SCIPinProbing(scip) )
1142  return SCIP_OKAY;
1143 
1144  /* do not run, if not all variables are explicitly known */
1145  if( SCIPgetNActivePricers(scip) > 0 )
1146  return SCIP_OKAY;
1147 
1148  presoldata = SCIPpresolGetData(presol);
1149  assert(presoldata != NULL);
1150 
1151  nvars = SCIPgetNVars(scip);
1152 
1153  /* we do not want to run, if there are no variables left */
1154  if( nvars == 0 )
1155  return SCIP_OKAY;
1156 
1157  /* the presolver should be executed only if it didn't run so far or the number of variables was significantly reduced
1158  * since tha last run
1159  */
1160  if( (presoldata->didsearch && nvars > (1 - presoldata->reldecrease) * presoldata->lastnvars) )
1161  return SCIP_OKAY;
1162 
1163  /* if we were not able to copy all plugins, we cannot run the components presolver */
1164  if( !presoldata->pluginscopied )
1165  return SCIP_OKAY;
1166 
1167  /* only call the component presolver, if presolving would be stopped otherwise */
1168  if( !SCIPisPresolveFinished(scip) )
1169  return SCIP_OKAY;
1170 
1171  /* check for a reached timelimit */
1172  if( SCIPisStopped(scip) )
1173  return SCIP_OKAY;
1174 
1175  SCIPstatistic( resetStatistics(scip, presoldata) );
1176 
1177  *result = SCIP_DIDNOTFIND;
1178  presoldata->didsearch = TRUE;
1179 
1180  ncomponents = 0;
1181  ndeletedvars = 0;
1182  ndeletedconss = 0;
1183  nsolvedprobs = 0;
1184 
1185  /* collect checked constraints for component presolving */
1186  ntmpconss = SCIPgetNConss(scip);
1187  tmpconss = SCIPgetConss(scip);
1188  SCIP_CALL( SCIPallocBufferArray(scip, &conss, ntmpconss) );
1189  nconss = 0;
1190  for( c = 0; c < ntmpconss; c++ )
1191  {
1192  if( SCIPconsIsChecked(tmpconss[c]) )
1193  {
1194  conss[nconss] = tmpconss[c];
1195  nconss++;
1196  }
1197  }
1198 
1199  if( nvars > 1 && nconss > 1 )
1200  {
1201  SCIP_DIGRAPH* digraph;
1202  SCIP_VAR** vars;
1203  SCIP_Real* fixvals;
1204  int* firstvaridxpercons;
1205  int* varlocks;
1206  int v;
1207 
1208  /* copy variables into a local array */
1209  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
1210  SCIP_CALL( SCIPallocBufferArray(scip, &fixvals, nvars) );
1211  SCIP_CALL( SCIPallocBufferArray(scip, &firstvaridxpercons, nconss) );
1212  SCIP_CALL( SCIPallocBufferArray(scip, &varlocks, nvars) );
1213  BMScopyMemoryArray(vars, SCIPgetVars(scip), nvars);
1214 
1215  /* count number of varlocks for each variable (up + down locks) and multiply it by 2;
1216  * that value is used as an estimate of the number of arcs incident to the variable's node in the digraph
1217  */
1218  for( v = 0; v < nvars; ++v )
1219  varlocks[v] = 4 * (SCIPvarGetNLocksDown(vars[v]) + SCIPvarGetNLocksUp(vars[v]));
1220 
1221  /* create and fill directed graph */
1222  SCIP_CALL( SCIPdigraphCreate(&digraph, nvars) );
1223  SCIP_CALL( SCIPdigraphSetSizes(digraph, varlocks) );
1224  SCIP_CALL( fillDigraph(scip, digraph, conss, nconss, firstvaridxpercons, &success) );
1225 
1226  if( success )
1227  {
1228  int* components;
1229 
1230  SCIP_CALL( SCIPallocBufferArray(scip, &components, nvars) );
1231 
1232  /* compute independent components */
1233  SCIP_CALL( SCIPdigraphComputeUndirectedComponents(digraph, 1, components, &ncomponents) );
1234 
1235  SCIPdebugMessage("presol components found %d undirected components\n", ncomponents);
1236 
1237  /* We want to sort the components in increasing size (number of variables).
1238  * Therefore, we now get the number of variables for each component, and rename the components
1239  * such that for i < j, component i has no more variables than component j.
1240  * @todo Perhaps sort the components by the number of binary/integer variables?
1241  */
1242  if( ncomponents > 0 )
1243  {
1244  int* compsize;
1245  int* permu;
1246  int* compvars;
1247  int ncompvars;
1248  int nbinvars;
1249  int nintvars;
1250  int ncontvars;
1251 
1252  SCIP_CALL( SCIPallocBufferArray(scip, &compsize, ncomponents) );
1253  SCIP_CALL( SCIPallocBufferArray(scip, &permu, ncomponents) );
1254 
1255  /* get number of variables in the components */
1256  for( c = 0; c < ncomponents; ++c )
1257  {
1258  SCIPdigraphGetComponent(digraph, c, &compvars, &ncompvars);
1259  permu[c] = c;
1260  nbinvars = 0;
1261  nintvars = 0;
1262 
1263  for( v = 0; v < ncompvars; ++v )
1264  {
1265  /* check whether variable is of binary or integer type */
1266  if( SCIPvarGetType(vars[compvars[v]]) == SCIP_VARTYPE_BINARY )
1267  nbinvars++;
1268  else if( SCIPvarGetType(vars[compvars[v]]) == SCIP_VARTYPE_INTEGER )
1269  nintvars++;
1270  }
1271  ncontvars = ncompvars - nintvars - nbinvars;
1272  compsize[c] = (int)((1000 * (nbinvars + presoldata->intfactor * nintvars) + (950.0 * ncontvars)/nvars));
1273  }
1274 
1275  /* get permutation of component numbers such that the size of the components is increasing */
1276  SCIPsortIntInt(compsize, permu, ncomponents);
1277 
1278  /* now, we need the reverse direction, i.e., for each component number, we store its new number
1279  * such that the components are sorted; for this, we abuse the compsize array
1280  */
1281  for( c = 0; c < ncomponents; ++c )
1282  compsize[permu[c]] = c;
1283 
1284  /* for each variable, replace the old component number by the new one */
1285  for( c = 0; c < nvars; ++c )
1286  components[c] = compsize[components[c]];
1287 
1288  /* create subproblems from independent components and solve them in dependence of their size */
1289  SCIP_CALL( splitProblem(scip, presoldata, conss, vars, fixvals, nconss, nvars, components, ncomponents, firstvaridxpercons,
1290  &nsolvedprobs, &ndeletedvars, &ndeletedconss, result) );
1291 
1292  (*nfixedvars) += ndeletedvars;
1293  (*ndelconss) += ndeletedconss;
1294 
1295  SCIPfreeBufferArray(scip, &permu);
1296  SCIPfreeBufferArray(scip, &compsize);
1297  }
1298 
1299  SCIPfreeBufferArray(scip, &components);
1300  }
1301 
1302  SCIPdigraphFree(&digraph);
1303 
1304  SCIPfreeBufferArray(scip, &varlocks);
1305  SCIPfreeBufferArray(scip, &firstvaridxpercons);
1306  SCIPfreeBufferArray(scip, &fixvals);
1307  SCIPfreeBufferArray(scip, &vars);
1308  }
1309 
1310  SCIPfreeBufferArray(scip, &conss);
1311 
1312  /* update result to SCIP_SUCCESS, if reductions were found;
1313  * if result was set to infeasible or unbounded before, leave it as it is
1314  */
1315  if( (ndeletedvars > 0 || ndeletedconss > 0) && ((*result) == SCIP_DIDNOTFIND) )
1316  *result = SCIP_SUCCESS;
1317 
1318  /* print statistics */
1319  SCIPstatistic( printStatistics(presoldata) );
1320 
1321  SCIPdebugMessage("%d components, %d solved, %d deleted constraints, %d deleted variables, result = %d\n",
1322  ncomponents, nsolvedprobs, ndeletedconss, ndeletedvars, *result);
1323 #ifdef NDEBUG
1324  SCIPstatisticMessage("%d components, %d solved, %d deleted constraints, %d deleted variables, result = %d\n",
1325  ncomponents, nsolvedprobs, ndeletedconss, ndeletedvars, *result);
1326 #endif
1327 
1328  presoldata->lastnvars = SCIPgetNVars(scip);
1329 
1330  return SCIP_OKAY;
1331 }
1332 
1333 
1334 /*
1335  * Callback methods of presolver
1336  */
1337 
1338 /** destructor of presolver to free user data (called when SCIP is exiting) */
1339 static
1340 SCIP_DECL_PRESOLFREE(presolFreeComponents)
1341 { /*lint --e{715}*/
1342  SCIP_PRESOLDATA* presoldata;
1343 
1344  /* free presolver data */
1345  presoldata = SCIPpresolGetData(presol);
1346  assert(presoldata != NULL);
1347 
1348  SCIPfreeMemory(scip, &presoldata);
1349  SCIPpresolSetData(presol, NULL);
1350 
1351  return SCIP_OKAY;
1352 }
1353 
1354 /** initialization method of presolver (called after problem was transformed) */
1355 static
1356 SCIP_DECL_PRESOLINIT(presolInitComponents)
1357 { /*lint --e{715}*/
1358  SCIP_PRESOLDATA* presoldata;
1359 
1360  /* free presolver data */
1361  presoldata = SCIPpresolGetData(presol);
1362  assert(presoldata != NULL);
1363 
1364  /* initialize statistics */
1365  SCIPstatistic( SCIP_CALL( initStatistics(scip, presoldata) ) );
1366 
1367  presoldata->subscip = NULL;
1368  presoldata->didsearch = FALSE;
1369  presoldata->pluginscopied = TRUE;
1370 
1371  return SCIP_OKAY;
1372 }
1373 
1374 #ifdef SCIP_STATISTIC
1375 /** deinitialization method of presolver (called before transformed problem is freed) */
1376 static
1377 SCIP_DECL_PRESOLEXIT(presolExitComponents)
1378 { /*lint --e{715}*/
1379  SCIP_PRESOLDATA* presoldata;
1380 
1381  /* free presolver data */
1382  presoldata = SCIPpresolGetData(presol);
1383  assert(presoldata != NULL);
1384 
1385  SCIPstatistic( freeStatistics(scip, presoldata) );
1386 
1387  return SCIP_OKAY;
1388 }
1389 #endif
1390 
1391 
1392 /** execution method of presolver */
1393 static
1394 SCIP_DECL_PRESOLEXEC(presolExecComponents)
1395 { /*lint --e{715}*/
1396 
1397  SCIP_CALL( presolComponents(scip, presol, nfixedvars, ndelconss, result) );
1398 
1399  return SCIP_OKAY;
1400 }
1401 
1402 
1403 /*
1404  * presolver specific interface methods
1405  */
1406 
1407 /** creates the components presolver and includes it in SCIP */
1409  SCIP* scip /**< SCIP data structure */
1410  )
1411 {
1412  SCIP_PRESOLDATA* presoldata;
1413  SCIP_PRESOL* presol;
1414 
1415  /* create components presolver data */
1416  SCIP_CALL( SCIPallocMemory(scip, &presoldata) );
1417 
1418  /* include presolver */
1420  PRESOL_TIMING, presolExecComponents, presoldata) );
1421 
1422  /* currently, the components presolver is not copied; if a copy callback is added, we need to avoid recursion
1423  * by one of the following means:
1424  * - turn off the components presolver in SCIPsetSubscipsOff()
1425  * - call SCIPsetSubscipsOff() for the component sub-SCIP
1426  * - disable the components presolver in the components sub-SCIP
1427  */
1428  SCIP_CALL( SCIPsetPresolCopy(scip, presol, NULL) );
1429  SCIP_CALL( SCIPsetPresolFree(scip, presol, presolFreeComponents) );
1430  SCIP_CALL( SCIPsetPresolInit(scip, presol, presolInitComponents) );
1431  SCIPstatistic( SCIP_CALL( SCIPsetPresolExit(scip, presol, presolExitComponents) ) );
1432 
1433  /* add presolver parameters */
1435  "presolving/components/writeproblems",
1436  "should the single components be written as an .cip-file?",
1437  &presoldata->writeproblems, FALSE, DEFAULT_WRITEPROBLEMS, NULL, NULL) );
1438  SCIP_CALL( SCIPaddIntParam(scip,
1439  "presolving/components/maxintvars",
1440  "maximum number of integer (or binary) variables to solve a subproblem directly (-1: unlimited)",
1441  &presoldata->maxintvars, FALSE, DEFAULT_MAXINTVARS, -1, INT_MAX, NULL, NULL) );
1443  "presolving/components/nodelimit",
1444  "maximum number of nodes to be solved in subproblems",
1445  &presoldata->nodelimit, FALSE, DEFAULT_NODELIMIT, -1LL, SCIP_LONGINT_MAX, NULL, NULL) );
1447  "presolving/components/intfactor",
1448  "the weight of an integer variable compared to binary variables",
1449  &presoldata->intfactor, FALSE, DEFAULT_INTFACTOR, 0.0, SCIP_REAL_MAX, NULL, NULL) );
1451  "presolving/components/reldecrease",
1452  "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)",
1453  &presoldata->reldecrease, FALSE, DEFAULT_RELDECREASE, 0.0, 1.0, NULL, NULL) );
1455  "presolving/components/feastolfactor",
1456  "factor to increase the feasibility tolerance of the main SCIP in all sub-SCIPs, default value 1.0",
1457  &presoldata->feastolfactor, TRUE, DEFAULT_FEASTOLFACTOR, 0.0, 1000000.0, NULL, NULL) );
1458 
1459  return SCIP_OKAY;
1460 }
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:22777
void SCIPpresolSetData(SCIP_PRESOL *presol, SCIP_PRESOLDATA *presoldata)
Definition: presol.c:476
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41572
SCIP_RETCODE SCIPincludePresolComponents(SCIP *scip)
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
Definition: scip.c:40329
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:10698
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:20526
struct SCIP_PresolData SCIP_PRESOLDATA
Definition: type_presol.h:37
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16443
SCIP_RETCODE SCIPgetConsVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int varssize, SCIP_Bool *success)
Definition: scip.c:26278
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip.c:908
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:20589
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
Definition: scip.c:41648
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:11540
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip.c:1248
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip.c:10653
#define SCIP_MAXSTRLEN
Definition: def.h:201
int SCIPpresolGetNCalls(SCIP_PRESOL *presol)
Definition: presol.c:771
SCIP_RETCODE SCIPdigraphComputeUndirectedComponents(SCIP_DIGRAPH *digraph, int minsize, int *components, int *ncomponents)
Definition: misc.c:6077
static SCIP_DECL_PRESOLFREE(presolFreeComponents)
#define NULL
Definition: lpi_spx.cpp:130
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17113
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1125
SCIP_RETCODE SCIPsetPresolCopy(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLCOPY((*presolcopy)))
Definition: scip.c:6226
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17067
#define PRESOL_PRIORITY
void SCIPsplitFilename(char *filename, char **path, char **name, char **extension, char **compression)
Definition: misc.c:8363
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition: scip.c:34843
#define SCIPfreeMemoryArray(scip, ptr)
Definition: scip.h:20544
#define DEFAULT_WRITEPROBLEMS
#define SCIPallocMemoryArray(scip, ptr, num)
Definition: scip.h:20528
#define FALSE
Definition: def.h:56
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:2057
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
Definition: scip.c:41009
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition: scip.c:4046
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:10743
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:8174
#define TRUE
Definition: def.h:55
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:7640
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_RETCODE SCIPdigraphSetSizes(SCIP_DIGRAPH *digraph, int *sizes)
Definition: misc.c:5720
#define SCIPstatisticMessage
Definition: pub_message.h:104
#define SCIP_CALL(x)
Definition: def.h:266
SCIP_RETCODE SCIPsetRealParam(SCIP *scip, const char *name, SCIP_Real value)
Definition: scip.c:4109
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:2365
int SCIPgetNActivePricers(SCIP *scip)
Definition: scip.c:5017
SCIP_RETCODE SCIPfreeTransform(SCIP *scip)
Definition: scip.c:15373
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:3601
#define DEFAULT_INTFACTOR
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip.c:34983
static SCIP_DECL_PRESOLEXEC(presolExecComponents)
void SCIPdigraphGetComponent(SCIP_DIGRAPH *digraph, int compidx, int **nodes, int *nnodes)
Definition: misc.c:6266
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:85
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:16905
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:2116
#define SCIP_LONGINT_MAX
Definition: def.h:113
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip.c:26237
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip.c:24949
SCIP_RETCODE SCIPcheckSolOrig(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *feasible, SCIP_Bool printreason, SCIP_Bool completely)
Definition: scip.c:36470
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:35066
#define DEFAULT_NODELIMIT
int SCIPgetNSols(SCIP *scip)
Definition: scip.c:35668
SCIP_PRESOLDATA * SCIPpresolGetData(SCIP_PRESOL *presol)
Definition: presol.c:466
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:3547
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:2159
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:3573
void SCIPsortIntPtr(int *intarray, void **ptrarray, int len)
SCIP_RETCODE SCIPdigraphCreate(SCIP_DIGRAPH **digraph, int nnodes)
Definition: misc.c:5596
#define PRESOL_DESC
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:20542
int SCIPgetNConss(SCIP *scip)
Definition: scip.c:11736
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41585
SCIP_RETCODE SCIPcopyParamSettings(SCIP *sourcescip, SCIP *targetscip)
Definition: scip.c:3164
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:36424
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
Definition: scip.c:41709
SCIP_RETCODE SCIPwriteParams(SCIP *scip, const char *filename, SCIP_Bool comments, SCIP_Bool onlychanged)
Definition: scip.c:4295
#define SCIPerrorMessage
Definition: pub_message.h:45
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:6258
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:41598
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip.c:41353
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:7620
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41907
SCIP_PRESOL * SCIPfindPresol(SCIP *scip, const char *name)
Definition: scip.c:6322
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:2075
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:9019
#define DEFAULT_RELDECREASE
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3204
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip.c:766
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip.c:32131
SCIP_RETCODE SCIPdigraphAddArc(SCIP_DIGRAPH *digraph, int startnode, int endnode, void *data)
Definition: misc.c:5814
SCIP_RETCODE SCIPgetActiveVars(SCIP *scip, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize)
Definition: scip.c:17465
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41611
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:20193
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17123
SCIP_Bool SCIPisPresolveFinished(SCIP *scip)
Definition: scip.c:1034
#define SCIP_Bool
Definition: def.h:53
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip.c:4001
SCIP_RETCODE SCIPsetPresolFree(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLFREE((*presolfree)))
Definition: scip.c:6242
void SCIPprintSysError(const char *message)
Definition: misc.c:8110
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip.c:801
SCIP_Real SCIPsolGetOrigObj(SCIP_SOL *sol)
Definition: sol.c:2189
SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
Definition: scip.c:3709
#define MAX(x, y)
Definition: tclique_def.h:75
components presolver
SCIP_Longint SCIPgetMemUsed(SCIP *scip)
Definition: scip.c:41396
SCIP_RETCODE SCIPsetPresolExit(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLEXIT((*presolexit)))
Definition: scip.c:6274
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:89
#define SCIPstatistic(x)
Definition: pub_message.h:101
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip.c:1298
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41624
#define DEFAULT_MAXINTVARS
#define SCIP_REAL_MAX
Definition: def.h:128
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:11477
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip.c:14503
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:16608
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20585
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17057
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip.c:692
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1281
SCIP_CONS ** SCIPgetConss(SCIP *scip)
Definition: scip.c:11782
int SCIPgetNIntVars(SCIP *scip)
Definition: scip.c:10788
SCIP_RETCODE SCIPcreateOrigSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip.c:34218
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41933
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16750
SCIP_RETCODE SCIPwriteOrigProblem(SCIP *scip, const char *filename, const char *extension, SCIP_Bool genericnames)
Definition: scip.c:9507
SCIP_RETCODE SCIPgetConsNVars(SCIP *scip, SCIP_CONS *cons, int *nvars, SCIP_Bool *success)
Definition: scip.c:26322
#define SCIP_Real
Definition: def.h:127
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:7799
#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:20299
#define MIN(x, y)
Definition: memory.c:67
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41959
const char * SCIPgetProbName(SCIP *scip)
Definition: scip.c:9941
#define SCIP_Longint
Definition: def.h:112
#define PRESOL_TIMING
#define PRESOL_NAME
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition: scip.c:3938
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:20597
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:1510
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition: scip.c:3797
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
Definition: scip.c:41697
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition: scip.c:35767
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:3629
void SCIPdigraphFree(SCIP_DIGRAPH **digraph)
Definition: misc.c:5742
static SCIP_RETCODE fillDigraph(SCIP *scip, SCIP_DIGRAPH *digraph, SCIP_CONS **conss, int nconss, int *firstvaridxpercons, SCIP_Bool *success)
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3149
SCIP_RETCODE SCIPincludePresolBasic(SCIP *scip, SCIP_PRESOL **presolptr, const char *name, const char *desc, int priority, int maxrounds, SCIP_PRESOLTIMING timing, SCIP_DECL_PRESOLEXEC((*presolexec)), SCIP_PRESOLDATA *presoldata)
Definition: scip.c:6191
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip.c:34607
SCIP_Longint SCIPgetMemExternEstim(SCIP *scip)
Definition: scip.c:41409