Scippy

SCIP

Solving Constraint Integer Programs

heur_vbounds.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 heur_vbounds.c
17  * @brief LNS heuristic uses the variable lower and upper bounds to determine the search neighborhood
18  * @author Timo Berthold
19  * @author Stefan Heinz
20  * @author Jens Schulz
21  */
22 
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
24 
25 #include <assert.h>
26 #include <string.h>
27 
28 #include "scip/scip.h"
29 #include "scip/scipdefplugins.h"
30 #include "scip/heur_vbounds.h"
31 
32 
33 #define HEUR_NAME "vbounds"
34 #define HEUR_DESC "LNS heuristic uses the variable lower and upper bounds to determine the search neighborhood"
35 #define HEUR_DISPCHAR 'V'
36 #define HEUR_PRIORITY -1106000
37 #define HEUR_FREQ -1
38 #define HEUR_FREQOFS 0
39 #define HEUR_MAXDEPTH -1
40 #define HEUR_TIMING SCIP_HEURTIMING_BEFORENODE
41 #define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
42 
43 #define DEFAULT_MAXNODES 5000LL /* maximum number of nodes to regard in the subproblem */
44 #define DEFAULT_MINFIXINGRATE 0.5 /* minimum percentage of integer variables that have to be fixed */
45 #define DEFAULT_MINIMPROVE 0.01 /* factor by which vbounds heuristic should at least improve the incumbent */
46 #define DEFAULT_MINNODES 500LL /* minimum number of nodes to regard in the subproblem */
47 #define DEFAULT_NODESOFS 500LL /* number of nodes added to the contingent of the total nodes */
48 #define DEFAULT_NODESQUOT 0.1 /* subproblem nodes in relation to nodes of the original problem */
49 #define DEFAULT_MAXPROPROUNDS 2 /* maximum number of propagation rounds during probing */
50 #define DEFAULT_COPYCUTS TRUE /**< should all active cuts from the cutpool of the original scip be copied to
51  * constraints of the subscip
52  */
53 
54 
55 /*
56  * Data structures
57  */
58 
59 /** primal heuristic data */
60 struct SCIP_HeurData
61 {
62  SCIP_VAR** lbvars; /**< topological sorted variables with respect to the variable lower bound */
63  SCIP_VAR** ubvars; /**< topological sorted variables with respect to the variable upper bound */
64  SCIP_VAR** impvars; /**< topological sorted variables with respect to the variable lower and upper
65  * bound and with a corresponding improving objective coefficient */
66  int nlbvars; /**< number of variables in variable lower bound array */
67  int nubvars; /**< number of variables in variable upper bound array */
68  int nlbimpvars; /**< number of variables in variable improving lower bound array */
69  int nubimpvars; /**< number of variables in variable improving upper bound array */
70 
71  SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
72  SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
73  SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
74  SCIP_Longint usednodes; /**< nodes already used by vbounds heuristic in earlier calls */
75  SCIP_Real minfixingrate; /**< minimum percentage of integer variables that have to be fixed */
76  SCIP_Real minimprove; /**< factor by which vbounds heuristic should at least improve the incumbent */
77  SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
78  int maxproprounds; /**< maximum number of propagation rounds during probing */
79  SCIP_Bool initialized; /**< are the candidate list initialized? */
80  SCIP_Bool applicable; /**< is the heuristic applicable? */
81  SCIP_Bool copycuts; /**< should all active cuts from cutpool be copied to constraints in
82  * subproblem?
83  */
84 };
85 
86 /*
87  * Hash map callback methods
88  */
89 
90 /** hash key retrieval function for variables */
91 static
92 SCIP_DECL_HASHGETKEY(hashGetKeyVar)
93 { /*lint --e{715}*/
94  return elem;
95 }
96 
97 /** returns TRUE iff the indices of both variables are equal */
98 static
99 SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
100 { /*lint --e{715}*/
101  if( key1 == key2 )
102  return TRUE;
103  return FALSE;
104 }
105 
106 /** returns the hash value of the key */
107 static
108 SCIP_DECL_HASHKEYVAL(hashKeyValVar)
109 { /*lint --e{715}*/
110  assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
111  return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
112 }
113 
114 
115 /*
116  * Local methods
117  */
118 
119 /** reset heuristic data structure */
120 static
121 void heurdataReset(
122  SCIP_HEURDATA* heurdata /**< structure containing heurdata */
123  )
124 {
125  heurdata->lbvars = NULL;
126  heurdata->ubvars = NULL;
127  heurdata->impvars = NULL;
128  heurdata->nlbvars = 0;
129  heurdata->nubvars = 0;
130  heurdata->nlbimpvars = 0;
131  heurdata->nubimpvars = 0;
132  heurdata->initialized = FALSE;
133  heurdata->applicable = FALSE;
134 }
135 
136 /** gets the requested variables bounds */
137 static
138 void getVariableBounds(
139  SCIP_VAR* var, /**< variable to get the variable bounds from */
140  SCIP_VAR*** vbvars, /**< pointer to store the variable bound array */
141  int* nvbvars, /**< pointer to store the number of variable bounds */
142  SCIP_Bool lowerbound /**< variable lower bounds? (otherwise variable upper bound) */
143  )
144 {
145  if( lowerbound )
146  {
147  /* get variable lower bounds */
148  (*vbvars) = SCIPvarGetVlbVars(var);
149  (*nvbvars) = SCIPvarGetNVlbs(var);
150  }
151  else
152  {
153  /* get variable upper bounds */
154  (*vbvars) = SCIPvarGetVubVars(var);
155  (*nvbvars) = SCIPvarGetNVubs(var);
156  }
157 }
158 
159 /** perform depth-first-search from the given variable using the variable lower or upper bounds of the variable */
160 static
162  SCIP* scip, /**< SCIP data structure */
163  SCIP_VAR* var, /**< variable to start the depth-first-search */
164  SCIP_HASHMAP* varPosMap, /**< mapping a variable to its position in the (used) variable array, or NULL */
165  SCIP_VAR** usedvars, /**< array of variables which are involved in the propagation, or NULL */
166  int* nusedvars, /**< number of variables which are involved in the propagation, or NULL */
167  SCIP_HASHTABLE* connected, /**< hash table storing if a node was already visited */
168  SCIP_VAR** sortedvars, /**< array that will contain the topological sorted variables */
169  int* nsortedvars, /**< pointer to store the number of already collects variables in the sorted variables array */
170  SCIP_Bool lowerbound /**< depth-first-search with respect to the variable lower bounds, otherwise variable upper bound */
171  )
172 {
173  SCIP_VAR** vbvars;
174  SCIP_VAR* vbvar;
175  SCIP_Real scalar;
176  SCIP_Real constant;
177  int nvbvars;
178  int v;
179 
180  assert(scip != NULL);
181  assert(var != NULL);
182  assert(varPosMap == NULL || (varPosMap != NULL && usedvars != NULL && nusedvars != NULL));
183  assert(sortedvars != NULL);
184  assert(nsortedvars != NULL);
185  assert(*nsortedvars >= 0);
186  assert(SCIPvarGetProbindex(var) > -1);
187  assert(SCIPhashtableExists(connected, var));
188 
189  /* mark variable as visited, remove variable from hash table */
190  SCIP_CALL( SCIPhashtableRemove(connected, var) );
191 
192  /* get variable bounds */
193  getVariableBounds(var, &vbvars, &nvbvars, lowerbound);
194 
195  SCIPdebugMessage("variable <%s> has %d variable %s bounds\n", SCIPvarGetName(var), nvbvars,
196  lowerbound ? "lower" : "upper");
197 
198  for( v = 0; v < nvbvars; ++v )
199  {
200  vbvar = vbvars[v];
201  assert(vbvar != NULL);
202 
203  scalar = 1.0;
204  constant = 0.0;
205 
206  /* transform variable bound variable to an active variable if possible */
207  SCIP_CALL( SCIPgetProbvarSum(scip, &vbvar, &scalar, &constant) );
208 
209  /* we could not resolve the variable bound variable to one active variable, therefore, ignore this variable bound */
210  if( !SCIPvarIsActive(vbvar) )
211  continue;
212 
213  /* insert variable bound variable into the hash table since they are involved in later propagation */
214  if( varPosMap != NULL && !SCIPhashmapExists(varPosMap, vbvar) )
215  {
216  SCIPdebugMessage("insert variable <%s> with position %d into the hash map\n", SCIPvarGetName(vbvar), *nusedvars);
217  SCIP_CALL( SCIPhashmapInsert(varPosMap, vbvar, (void*)(size_t)(*nusedvars)) );
218  usedvars[*nusedvars] = vbvar;
219  (*nusedvars)++;
220  }
221 
222  /* check if the variable bound variable was already visited */
223  if( SCIPhashtableExists(connected, vbvar) )
224  {
225  /* recursively call depth-first-search */
226  SCIP_CALL( depthFirstSearch(scip, vbvar, varPosMap, usedvars, nusedvars, connected, sortedvars, nsortedvars, lowerbound) );
227  }
228  }
229 
230  /* store variable in the sorted variable array */
231  sortedvars[(*nsortedvars)] = var;
232  (*nsortedvars)++;
233 
234  /* insert variable bound variable into the hash table since they are involve in the later propagation */
235  if( varPosMap != NULL && !SCIPhashmapExists(varPosMap, var) )
236  {
237  SCIPdebugMessage("insert variable <%s> with position %d into the hash map\n", SCIPvarGetName(var), *nusedvars);
238  SCIP_CALL( SCIPhashmapInsert(varPosMap, var, (void*) (size_t)(*nusedvars)) );
239  usedvars[*nusedvars] = var;
240  (*nusedvars)++;
241  }
242 
243  return SCIP_OKAY;
244 }
245 
246 /** create a topological sorted variable array of the given variables and stores if (needed) the involved variables into
247  * the corresponding variable array and hash map
248  *
249  * @note: for all arrays and the hash map (if requested) you need to allocate enough memory before calling this method
250  */
251 static
253  SCIP* scip, /**< SCIP data structure */
254  SCIP_VAR** vars, /**< variable which we want sort */
255  int nvars, /**< number of variables */
256  SCIP_HASHMAP* varPosMap, /**< mapping a variable to its position in the (used) variable array, or NULL */
257  SCIP_VAR** usedvars, /**< array of variables which are involved in the propagation, or NULL */
258  int* nusedvars, /**< number of variables which are involved in the propagation, or NULL */
259  SCIP_VAR** topovars, /**< array where the topological sorted variables are stored */
260  int* ntopovars, /**< pointer to store the number of topological sorted variables */
261  SCIP_Bool lowerbound /**< topological sorted with respect to the variable lower bounds, otherwise variable upper bound */
262  )
263 {
264  SCIP_VAR** sortedvars;
265  SCIP_VAR** vbvars;
266  SCIP_VAR* var;
267  SCIP_HASHTABLE* connected;
268  int nvbvars;
269  int hashsize;
270  int i;
271  int v;
272 
273  assert(scip != NULL);
274  assert(vars != NULL || nvars == 0);
275  assert(varPosMap == NULL || (varPosMap != NULL && usedvars != NULL && nusedvars != NULL));
276  assert(topovars != NULL);
277  assert(ntopovars != NULL);
278 
279  SCIPdebugMessage("create topological sorted variable array with respect to variables %s bounds\n",
280  lowerbound ? "lower" : "upper");
281 
282  if( nvars == 0 )
283  return SCIP_OKAY;
284 
285  assert(vars != NULL);
286 
287  /* allocate buffer array */
288  SCIP_CALL( SCIPallocBufferArray(scip, &sortedvars, nvars) );
289 
290  hashsize = SCIPcalcHashtableSize(5 * nvars);
291 
292  /* create hash table for variables which are (still) connected */
293  SCIP_CALL( SCIPhashtableCreate(&connected, SCIPblkmem(scip), hashsize, SCIPvarGetHashkey, SCIPvarIsHashkeyEq, SCIPvarGetHashkeyVal, NULL) );
294 
295  /* detect isolated variables; mark all variables which have at least one entering or leaving arc as connected */
296  for( v = 0; v < nvars; ++v )
297  {
298  var = vars[v];
299  assert(var != NULL);
300 
301  if( !SCIPvarIsActive(var) )
302  continue;
303 
304  /* get variable bounds */
305  getVariableBounds(var, &vbvars, &nvbvars, lowerbound);
306 
307  if( nvbvars > 0 && !SCIPhashtableExists(connected, var) )
308  {
309  SCIP_CALL( SCIPhashtableInsert(connected, var) );
310  }
311 
312  for( i = 0; i < nvbvars; ++i )
313  {
314  if( !SCIPvarIsActive(vbvars[i]) )
315  continue;
316 
317  /* there is a leaving arc, hence, the variable/node is connected */
318  assert(vbvars[i] != NULL);
319  if( !SCIPhashtableExists(connected, vbvars[i]) )
320  {
321  SCIP_CALL( SCIPhashtableInsert(connected, vbvars[i]) );
322  }
323  }
324  }
325 
326  /* loop over all "connected" variable and find for each connected component a "almost" topological sorted version */
327  for( v = 0; v < nvars; ++v )
328  {
329  if( SCIPhashtableExists(connected, vars[v]) )
330  {
331  int nsortedvars;
332 
333  SCIPdebugMessage("start depth-first-search with variable <%s>\n", SCIPvarGetName(vars[v]));
334 
335  /* use depth first search to get a "almost" topological sorted variables for the connected component which
336  * includes vars[v]
337  */
338  nsortedvars = 0;
339  SCIP_CALL( depthFirstSearch(scip, vars[v], varPosMap, usedvars, nusedvars, connected, sortedvars, &nsortedvars, lowerbound) );
340 
341  SCIPdebugMessage("detected connected component of size <%d>\n", nsortedvars);
342 
343  /* copy variables */
344  for( i = 0; i < nsortedvars; ++i )
345  {
346  topovars[(*ntopovars)] = sortedvars[i];
347  (*ntopovars)++;
348  }
349  }
350  }
351 
352  assert(*ntopovars <= nvars);
353  SCIPdebugMessage("topological sorted array contains %d of %d variables (variable %s bound)\n",
354  *ntopovars, nvars, lowerbound ? "lower" : "upper");
355 
356  /* free hash table */
357  SCIPhashtableFree(&connected);
358 
359  /* free buffer memory */
360  SCIPfreeBufferArray(scip, &sortedvars);
361 
362  return SCIP_OKAY;
363 }
364 
365 /** initialize candidate lists */
366 static
368  SCIP* scip, /**< original SCIP data structure */
369  SCIP_HEURDATA* heurdata /**< structure containing heurdata */
370  )
371 {
372  SCIP_VAR** allvars;
373  SCIP_VAR** vars;
374  SCIP_VAR** lbvars;
375  SCIP_VAR** ubvars;
376  SCIP_VAR** impvars;
377  SCIP_HASHTABLE* collectedvars;
378  int nallvars;
379  int nvars;
380  int nlbvars;
381  int nubvars;
382  int nlbimpvars;
383  int nubimpvars;
384  int v;
385 
386  SCIPdebugMessage("initialize variable bound heuristic (%s)\n", SCIPgetProbName(scip));
387 
388  allvars = SCIPgetVars(scip);
389  nallvars = SCIPgetNVars(scip);
390  nvars = 0;
391  nlbvars = 0;
392  nubvars = 0;
393  nlbimpvars = 0;
394  nubimpvars = 0;
395 
396  /* allocate memory for the arrays of the heurdata */
397  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nallvars) );
398  SCIP_CALL( SCIPallocBufferArray(scip, &lbvars, nallvars) );
399  SCIP_CALL( SCIPallocBufferArray(scip, &ubvars, nallvars) );
400  SCIP_CALL( SCIPallocBufferArray(scip, &impvars, nallvars) );
401 
402  /* create the topological sorted variable array with respect to the variable lower bounds */
403  SCIP_CALL( createTopoSortedVars(scip, allvars, nallvars, NULL, vars, &nvars, lbvars, &nlbvars, TRUE) );
404 
405  /* create the topological sorted variable array with respect to the variable upper bounds */
406  SCIP_CALL( createTopoSortedVars(scip, allvars, nallvars, NULL, vars, &nvars, ubvars, &nubvars, FALSE) );
407 
408  /* create hash table for variables which are already collected */
409  SCIP_CALL( SCIPhashtableCreate(&collectedvars, SCIPblkmem(scip), SCIPcalcHashtableSize(nallvars), hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
410 
411  /* collect variables which improve the objective by fixing them to suggested bound */
412  for( v = 0; v < nlbvars; ++v )
413  {
414  if( SCIPisGE(scip, SCIPvarGetObj(lbvars[v]), 0.0) )
415  {
416  SCIP_CALL( SCIPhashtableInsert(collectedvars, lbvars[v]) );
417  assert(nlbimpvars < nallvars);
418  impvars[nlbimpvars] = lbvars[v];
419  nlbimpvars++;
420  }
421  }
422 
423  for( v = 0; v < nubvars; ++v )
424  {
425  if( SCIPisLE(scip, SCIPvarGetObj(ubvars[v]), 0.0) && !SCIPhashtableExists(collectedvars, ubvars[v]) )
426  {
427  assert(nlbimpvars + nubimpvars < nallvars);
428  impvars[nlbimpvars + nubimpvars] = ubvars[v];
429  nubimpvars++;
430  }
431  }
432 
433  /* free hash table */
434  SCIPhashtableFree(&collectedvars);
435 
436  /* check if the candidate lists contain enough candidates */
437  if( nlbvars >= heurdata->minfixingrate * nallvars )
438  {
439  SCIP_CALL( SCIPduplicateMemoryArray(scip, &heurdata->lbvars, lbvars, nlbvars) );
440  heurdata->nlbvars = nlbvars;
441  heurdata->applicable = TRUE;
442 
443  /* capture variable candidate list */
444  for( v = 0; v < nlbvars; ++v )
445  {
446  SCIP_CALL( SCIPcaptureVar(scip, heurdata->lbvars[v]) );
447  }
448  }
449  if( nubvars >= heurdata->minfixingrate * nallvars )
450  {
451  SCIP_CALL( SCIPduplicateMemoryArray(scip, &heurdata->ubvars, ubvars, nubvars) );
452  heurdata->nubvars = nubvars;
453  heurdata->applicable = TRUE;
454 
455  /* capture variable candidate list */
456  for( v = 0; v < nubvars; ++v )
457  {
458  SCIP_CALL( SCIPcaptureVar(scip, heurdata->ubvars[v]) );
459  }
460  }
461  if( nlbvars > nlbimpvars && nubvars > nubimpvars && nlbimpvars + nubimpvars >= heurdata->minfixingrate * nallvars )
462  {
463  assert(nlbimpvars < INT_MAX - nubimpvars);
464  SCIP_CALL( SCIPduplicateMemoryArray(scip, &heurdata->impvars, impvars, nlbimpvars + nubimpvars) );
465  heurdata->nlbimpvars = nlbimpvars;
466  heurdata->nubimpvars = nubimpvars;
467  heurdata->applicable = TRUE;
468 
469  /* capture variable candidate list */
470  for( v = 0; v < nlbimpvars + nubimpvars; ++v )
471  {
472  SCIP_CALL( SCIPcaptureVar(scip, heurdata->impvars[v]) );
473  }
474  }
475 
476  /* free buffer arrays */
477  SCIPfreeBufferArray(scip, &impvars);
478  SCIPfreeBufferArray(scip, &ubvars);
479  SCIPfreeBufferArray(scip, &lbvars);
480  SCIPfreeBufferArray(scip, &vars);
481 
482  /* initialize data */
483  heurdata->usednodes = 0;
484  heurdata->initialized = TRUE;
485 
486  SCIPstatisticMessage("lbvars %.3g, ubvars %.3g, impvars %.3g (%s)\n",
487  (nlbvars * 100.0) / nallvars, (nubvars * 100.0) / nallvars,
488  ((nlbimpvars + nubimpvars) * 100.0) / nallvars, SCIPgetProbName(scip));
489 
490  return SCIP_OKAY;
491 }
492 
493 /** apply variable bound fixing during probing */
494 static
496  SCIP* scip, /**< original SCIP data structure */
497  SCIP_HEURDATA* heurdata, /**< structure containing heurdata */
498  SCIP_VAR** vars, /**< variables to fix during probing */
499  int nlbvars, /**< number of variables to use the lower bound */
500  int nubvars, /**< number of variables to use the upper bound */
501  SCIP_SOL* sol, /**< working solution */
502  SCIP_Bool* infeasible, /**< pointer to store whether problem is infeasible */
503  SCIP_RESULT* result /**< pointer to store the result (solution found) */
504  )
505 {
506  SCIP_Bool success;
507  int v;
508 
509  /* for each variable in topological order: start at best bound (MINIMIZE: neg coeff --> ub, pos coeff: lb) */
510  for( v = 0; v < nlbvars + nubvars && !(*infeasible); ++v )
511  {
512  /* only check integer or binary variables */
513  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
514  continue;
515 
516  /* skip variables which are already fixed */
517  if( SCIPvarGetLbLocal(vars[v]) + 0.5 > SCIPvarGetUbLocal(vars[v]) )
518  continue;
519 
520  if( v < nlbvars )
521  {
522  /* fix variable to lower bound */
523  SCIP_CALL( SCIPfixVarProbing(scip, vars[v], SCIPvarGetLbLocal(vars[v])) );
524  SCIPdebugMessage("fixing %d: variable <%s> to lower bound <%g> (%d pseudo cands)\n",
525  v, SCIPvarGetName(vars[v]), SCIPvarGetLbLocal(vars[v]), SCIPgetNPseudoBranchCands(scip));
526  }
527  else
528  {
529  /* fix variable to lower bound */
530  SCIP_CALL( SCIPfixVarProbing(scip, vars[v], SCIPvarGetUbLocal(vars[v])) );
531  SCIPdebugMessage("fixing %d: variable <%s> to upper bound <%g> (%d pseudo cands)\n",
532  v, SCIPvarGetName(vars[v]), SCIPvarGetUbLocal(vars[v]), SCIPgetNPseudoBranchCands(scip));
533  }
534 
535  /* check if problem is already infeasible */
536  SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, infeasible, NULL) );
537 
538  if( !(*infeasible) )
539  {
540  /* create solution from probing run and try to round it */
541  SCIP_CALL( SCIPlinkCurrentSol(scip, sol) );
542  SCIP_CALL( SCIProundSol(scip, sol, &success) );
543 
544  if( success )
545  {
546  SCIPdebugMessage("vbound heuristic found roundable primal solution: obj=%g\n", SCIPgetSolOrigObj(scip, sol));
547 
548  /* try to add solution to SCIP */
549  SCIP_CALL( SCIPtrySol(scip, sol, FALSE, FALSE, FALSE, TRUE, &success) );
550 
551  /* check, if solution was feasible and good enough */
552  if( success )
553  {
554  SCIPdebugMessage(" -> solution was feasible and good enough\n");
555  *result = SCIP_FOUNDSOL;
556 
557  if( SCIPisStopped(scip) )
558  break;
559  }
560  }
561  }
562  }
563 
564  SCIPdebugMessage("probing ended with %sfeasible problem\n", (*infeasible) ? "in" : "");
565 
566  return SCIP_OKAY;
567 }
568 
569 /** creates a new solution for the original problem by copying the solution of the subproblem */
570 static
572  SCIP* scip, /**< original SCIP data structure */
573  SCIP* subscip, /**< SCIP structure of the subproblem */
574  SCIP_VAR** subvars, /**< the variables of the subproblem */
575  SCIP_SOL* newsol, /**< working solution */
576  SCIP_SOL* subsol, /**< solution of the subproblem */
577  SCIP_Bool* success /**< used to store whether new solution was found or not */
578  )
579 {
580  SCIP_VAR** vars; /* the original problem's variables */
581  int nvars;
582  SCIP_Real* subsolvals; /* solution values of the subproblem */
583 
584  assert( scip != NULL );
585  assert( subscip != NULL );
586  assert( subvars != NULL );
587  assert( subsol != NULL );
588 
589  /* get variables' data */
590  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
591 
592  /* sub-SCIP may have more variables than the number of active (transformed) variables in the main SCIP
593  * since constraint copying may have required the copy of variables that are fixed in the main SCIP
594  */
595  assert( nvars <= SCIPgetNOrigVars(subscip) );
596 
597  SCIP_CALL( SCIPallocBufferArray(scip, &subsolvals, nvars) );
598 
599  /* copy the solution */
600  SCIP_CALL( SCIPgetSolVals(subscip, subsol, nvars, subvars, subsolvals) );
601 
602  SCIP_CALL( SCIPsetSolVals(scip, newsol, nvars, vars, subsolvals) );
603 
604  /* try to add new solution to scip and free it immediately */
605  SCIP_CALL( SCIPtrySol(scip, newsol, FALSE, TRUE, TRUE, TRUE, success) );
606 
607  SCIPfreeBufferArray(scip, &subsolvals);
608 
609  return SCIP_OKAY;
610 }
611 
612 /** main procedure of the vbounds heuristic */
613 static
615  SCIP* scip, /**< original SCIP data structure */
616  SCIP_HEUR* heur, /**< heuristic */
617  SCIP_HEURDATA* heurdata, /**< heuristic data structure */
618  SCIP_VAR** probvars, /**< variables to fix during probing */
619  int nlbvars, /**< number of variables to use the lower bound */
620  int nubvars, /**< number of variables to use the upper bound */
621  SCIP_RESULT* result /**< pointer to store the result */
622  )
623 {
624  SCIP_VAR** vars;
625  SCIP_SOL* newsol;
626  SCIP_Real timelimit; /* timelimit for the subproblem */
627  SCIP_Real memorylimit;
628  SCIP_Longint nstallnodes; /* number of stalling nodes for the subproblem */
629  SCIP_Bool infeasible;
630  int nvars;
631 
632  assert(heur != NULL);
633  assert(heurdata != NULL);
634 
635  /* initialize default values */
636  infeasible = FALSE;
637 
638  /* get variable data of original problem */
639  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
640 
641  if( nlbvars + nubvars < nvars * heurdata->minfixingrate )
642  return SCIP_OKAY;
643 
644  assert(nlbvars + nubvars > 0);
645 
646  /* calculate the maximal number of branching nodes until heuristic is aborted */
647  nstallnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
648 
649  /* reward variable bounds heuristic if it succeeded often */
650  nstallnodes = (SCIP_Longint)(nstallnodes * 3.0 * (SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur) + 1.0));
651  nstallnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-MIP as 100 nodes */
652  nstallnodes += heurdata->nodesofs;
653 
654  /* determine the node limit for the current process */
655  nstallnodes -= heurdata->usednodes;
656  nstallnodes = MIN(nstallnodes, heurdata->maxnodes);
657 
658  /* check whether we have enough nodes left to call subproblem solving */
659  if( nstallnodes < heurdata->minnodes )
660  {
661  SCIPdebugMessage("skipping "HEUR_NAME": nstallnodes=%"SCIP_LONGINT_FORMAT", minnodes=%"SCIP_LONGINT_FORMAT"\n", nstallnodes, heurdata->minnodes);
662  return SCIP_OKAY;
663  }
664 
665  if( SCIPisStopped(scip) )
666  return SCIP_OKAY;
667 
668  SCIPdebugMessage("apply variable bounds heuristic at node %lld on %d variable lower bound and %d variable upper bounds\n",
669  SCIPnodeGetNumber(SCIPgetCurrentNode(scip)), nlbvars, nubvars);
670 
671  /* start probing */
672  SCIP_CALL( SCIPstartProbing(scip) );
673 
674  /* create temporary solution */
675  SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) );
676 
677  /* apply the variable fixings */
678  SCIP_CALL( applyVboundsFixings(scip, heurdata, probvars, nlbvars, nubvars, newsol, &infeasible, result) );
679 
680  /* if a solution has been found --> fix all other variables by subscip if necessary */
681  if( !infeasible )
682  {
683  SCIP* subscip;
684  SCIP_VAR** subvars;
685  SCIP_HASHMAP* varmap;
686  SCIP_Bool valid;
687  int i;
688 
689  valid = FALSE;
690 
691  /* create subproblem */
692  SCIP_CALL( SCIPcreate(&subscip) );
693 
694  /* create the variable mapping hash map */
695  SCIP_CALL( SCIPhashmapCreate(&varmap, SCIPblkmem(subscip), SCIPcalcHashtableSize(5 * nvars)) );
696 
697  SCIP_CALL( SCIPcopy(scip, subscip, varmap, NULL, "_vbounds", FALSE, FALSE, TRUE, &valid) );
698 
699  if( heurdata->copycuts )
700  {
701  /* copies all active cuts from cutpool of sourcescip to linear constraints in targetscip */
702  SCIP_CALL( SCIPcopyCuts(scip, subscip, varmap, NULL, FALSE, NULL) );
703  }
704 
705  SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
706 
707  for( i = 0; i < nvars; i++ )
708  subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmap, vars[i]);
709 
710  /* free hash map */
711  SCIPhashmapFree(&varmap);
712 
713  /* do not abort subproblem on CTRL-C */
714  SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
715 
716  /* disable output to console */
717  SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
718 
719  /* check whether there is enough time and memory left */
720  SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
721  if( !SCIPisInfinity(scip, timelimit) )
722  timelimit -= SCIPgetSolvingTime(scip);
723  SCIP_CALL( SCIPgetRealParam(scip, "limits/memory", &memorylimit) );
724 
725  /* substract the memory already used by the main SCIP and the estimated memory usage of external software */
726  if( !SCIPisInfinity(scip, memorylimit) )
727  {
728  memorylimit -= SCIPgetMemUsed(scip)/1048576.0;
729  memorylimit -= SCIPgetMemExternEstim(scip)/1048576.0;
730  }
731 
732  /* abort if no time is left or not enough memory to create a copy of SCIP, including external memory usage */
733  if( timelimit <= 0.0 || memorylimit <= 2.0*SCIPgetMemExternEstim(scip)/1048576.0 )
734  {
735  /* free subproblem */
736  SCIPfreeBufferArray(scip, &subvars);
737  SCIP_CALL( SCIPfree(&subscip) );
738 
739  goto TERMINATE;
740  }
741 
742  /* disable statistic timing inside sub SCIP */
743  SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
744 
745  /* set limits for the subproblem */
746  SCIP_CALL( SCIPsetLongintParam(subscip, "limits/stallnodes", nstallnodes) );
747  SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", heurdata->maxnodes) );
748  SCIP_CALL( SCIPsetRealParam(subscip, "limits/time", timelimit) );
749  SCIP_CALL( SCIPsetRealParam(subscip, "limits/memory", memorylimit) );
750 
751  /* forbid call of heuristics and separators solving sub-CIPs */
752  SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
753 
754  /* disable cutting plane separation */
756 
757  /* disable expensive presolving */
759 
760 #ifdef SCIP_DEBUG
761  /* for debugging vbounds heuristic, enable MIP output */
762  SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
763  SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 100000000) );
764 #endif
765 
766  /* employ a limit on the number of enforcement rounds in the quadratic constraint handlers; this fixes the issue that
767  * sometimes the quadratic constraint handler needs hundreds or thousands of enforcement rounds to determine the
768  * feasibility status of a single node without fractional branching candidates by separation (namely for uflquad
769  * instances); however, the solution status of the sub-SCIP might get corrupted by this; hence no decutions shall be
770  * made for the original SCIP
771  */
772  if( SCIPfindConshdlr(subscip, "quadratic") != NULL && !SCIPisParamFixed(subscip, "constraints/quadratic/enfolplimit") )
773  {
774  SCIP_CALL( SCIPsetIntParam(subscip, "constraints/quadratic/enfolplimit", 10) );
775  }
776 
777  /* if there is already a solution, add an objective cutoff */
778  if( SCIPgetNSols(scip) > 0 )
779  {
780  SCIP_Real upperbound;
781  SCIP_Real minimprove;
782  SCIP_Real cutoff;
783 
784  minimprove = heurdata->minimprove;
785  cutoff = SCIPinfinity(scip);
786  assert( !SCIPisInfinity(scip,SCIPgetUpperbound(scip)) );
787 
788  upperbound = SCIPgetUpperbound(scip) - SCIPsumepsilon(scip);
789 
790  if( !SCIPisInfinity(scip,-1.0*SCIPgetLowerbound(scip)) )
791  {
792  cutoff = (1-minimprove)*SCIPgetUpperbound(scip) + minimprove*SCIPgetLowerbound(scip);
793  }
794  else
795  {
796  if( SCIPgetUpperbound ( scip ) >= 0 )
797  cutoff = ( 1 - minimprove ) * SCIPgetUpperbound ( scip );
798  else
799  cutoff = ( 1 + minimprove ) * SCIPgetUpperbound ( scip );
800  }
801  cutoff = MIN(upperbound, cutoff);
802  SCIP_CALL( SCIPsetObjlimit(subscip, cutoff) );
803  }
804 
805  /* solve the subproblem */
806  /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
807  * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
808  */
809 #ifdef NDEBUG
810  {
811  SCIP_RETCODE retstat;
812  retstat = SCIPpresolve(subscip);
813  if( retstat != SCIP_OKAY )
814  {
815  SCIPwarningMessage(scip, "Error while presolving subMIP in vbounds heuristic; sub-SCIP terminated with code <%d>\n", retstat);
816  }
817  }
818 #else
819  SCIP_CALL( SCIPpresolve(subscip) );
820 #endif
821 
822  SCIPdebugMessage("vbounds heuristic presolved subproblem: %d vars, %d cons\n", SCIPgetNVars(subscip), SCIPgetNConss(subscip));
823 
824  /* after presolving, we should have at least reached a certain fixing rate over ALL variables (including continuous)
825  * to ensure that not only the MIP but also the LP relaxation is easy enough
826  */
827  if( ( nvars - SCIPgetNVars(subscip) ) / (SCIP_Real)nvars >= heurdata->minfixingrate / 2.0 )
828  {
829  SCIP_SOL** subsols;
830  SCIP_Bool success;
831  int nsubsols;
832 
833  SCIPdebugMessage("solving subproblem: nstallnodes=%"SCIP_LONGINT_FORMAT", maxnodes=%"SCIP_LONGINT_FORMAT"\n", nstallnodes, heurdata->maxnodes);
834 
835 #ifdef NDEBUG
836  {
837  SCIP_RETCODE retstat;
838  retstat = SCIPsolve(subscip);
839  if( retstat != SCIP_OKAY )
840  {
841  SCIPwarningMessage(scip, "Error while solving subMIP in vbounds heuristic; sub-SCIP terminated with code <%d>\n",retstat);
842  }
843  }
844 #else
845  SCIP_CALL( SCIPsolve(subscip) );
846 #endif
847 
848  /* check, whether a solution was found; due to numerics, it might happen that not all solutions are feasible ->
849  * try all solutions until one was accepted
850  */
851  nsubsols = SCIPgetNSols(subscip);
852  subsols = SCIPgetSols(subscip);
853  success = FALSE;
854 
855  for( i = 0; i < nsubsols && !success; ++i )
856  {
857  SCIP_CALL( createNewSol(scip, subscip, subvars, newsol, subsols[i], &success) );
858  }
859  if( success )
860  *result = SCIP_FOUNDSOL;
861  }
862 
863 #ifdef SCIP_DEBUG
864  SCIP_CALL( SCIPprintStatistics(subscip, NULL) );
865 #endif
866 
867  /* free subproblem */
868  SCIPfreeBufferArray(scip, &subvars);
869  SCIP_CALL( SCIPfree(&subscip) );
870  }
871 
872  TERMINATE:
873  /* free solution */
874  SCIP_CALL( SCIPfreeSol(scip, &newsol) );
875 
876  /* exit probing mode */
877  SCIP_CALL( SCIPendProbing(scip) );
878 
879  return SCIP_OKAY;
880 }
881 
882 
883 /*
884  * Callback methods of primal heuristic
885  */
886 
887 /** copy method for primal heuristic plugins (called when SCIP copies plugins) */
888 static
889 SCIP_DECL_HEURCOPY(heurCopyVbounds)
890 { /*lint --e{715}*/
891  assert(scip != NULL);
892  assert(heur != NULL);
893  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
894 
895  /* call inclusion method of heuristic */
897 
898  return SCIP_OKAY;
899 }
900 
901 /** destructor of primal heuristic to free user data (called when SCIP is exiting) */
902 static
903 SCIP_DECL_HEURFREE(heurFreeVbounds)
904 { /*lint --e{715}*/
905  SCIP_HEURDATA* heurdata;
906 
907  /* free heuristic data */
908  heurdata = SCIPheurGetData(heur);
909 
910  SCIPfreeMemory(scip, &heurdata);
911  SCIPheurSetData(heur, NULL);
912 
913  return SCIP_OKAY;
914 }
915 
916 
917 /** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
918 static
919 SCIP_DECL_HEUREXITSOL(heurExitsolVbounds)
920 { /*lint --e{715}*/
921  SCIP_HEURDATA* heurdata;
922  int v;
923 
924  heurdata = SCIPheurGetData(heur);
925  assert(heurdata != NULL);
926 
927  /* release all variables */
928  for( v = 0; v < heurdata->nlbvars; ++v )
929  {
930  SCIP_CALL( SCIPreleaseVar(scip, &heurdata->lbvars[v]) );
931  }
932  /* release all variables */
933  for( v = 0; v < heurdata->nubvars; ++v )
934  {
935  SCIP_CALL( SCIPreleaseVar(scip, &heurdata->ubvars[v]) );
936  }
937  /* release all variables */
938  for( v = 0; v < heurdata->nlbimpvars + heurdata->nubimpvars; ++v )
939  {
940  SCIP_CALL( SCIPreleaseVar(scip, &heurdata->impvars[v]) );
941  }
942 
943  /* free varbounds array */
944  SCIPfreeMemoryArrayNull(scip, &heurdata->impvars);
945  SCIPfreeMemoryArrayNull(scip, &heurdata->lbvars);
946  SCIPfreeMemoryArrayNull(scip, &heurdata->ubvars);
947 
948  /* reset heuristic data structure */
949  heurdataReset(heurdata);
950 
951  return SCIP_OKAY;
952 }
953 
954 /** execution method of primal heuristic */
955 static
956 SCIP_DECL_HEUREXEC(heurExecVbounds)
957 { /*lint --e{715}*/
958  SCIP_HEURDATA* heurdata;
959 
960  assert( heur != NULL );
961  assert( scip != NULL );
962  assert( result != NULL );
963 
964  *result = SCIP_DIDNOTRUN;
965 
966  if( SCIPgetNPseudoBranchCands(scip) == 0 )
967  return SCIP_OKAY;
968 
969  heurdata = SCIPheurGetData(heur);
970  assert(heurdata != NULL);
971 
972  if( !heurdata->initialized )
973  {
974  SCIP_CALL( initializeCandsLists(scip, heurdata) );
975  }
976 
977  if( !heurdata->applicable )
978  return SCIP_OKAY;
979 
980  *result = SCIP_DIDNOTFIND;
981 
982  /* try variable lower and upper bounds which respect to objective coefficients */
983  SCIP_CALL( applyVbounds(scip, heur, heurdata, heurdata->impvars, heurdata->nlbimpvars, heurdata->nubimpvars, result) );
984 
985  /* try variable lower bounds */
986  SCIP_CALL( applyVbounds(scip, heur, heurdata, heurdata->lbvars, heurdata->nlbvars, 0, result) );
987 
988  /* try variable upper bounds */
989  SCIP_CALL( applyVbounds(scip, heur, heurdata, heurdata->ubvars, 0, heurdata->nubvars, result) );
990 
991  return SCIP_OKAY;
992 }
993 
994 /*
995  * primal heuristic specific interface methods
996  */
997 
998 /** creates the vbounds primal heuristic and includes it in SCIP */
1000  SCIP* scip /**< SCIP data structure */
1001  )
1002 {
1003  SCIP_HEURDATA* heurdata;
1004  SCIP_HEUR* heur;
1005 
1006  /* create vbounds primal heuristic data */
1007  SCIP_CALL( SCIPallocMemory(scip, &heurdata) );
1008  heurdataReset(heurdata);
1009 
1010  /* include primal heuristic */
1011  SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
1013  HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecVbounds, heurdata) );
1014 
1015  assert(heur != NULL);
1016 
1017  /* set non-NULL pointers to callback methods */
1018  SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyVbounds) );
1019  SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeVbounds) );
1020  SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolVbounds) );
1021 
1022  /* add variable bounds primal heuristic parameters */
1023  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/"HEUR_NAME"/minfixingrate",
1024  "minimum percentage of integer variables that have to be fixable",
1025  &heurdata->minfixingrate, FALSE, DEFAULT_MINFIXINGRATE, 0.0, 1.0, NULL, NULL) );
1026 
1027  SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/"HEUR_NAME"/maxnodes",
1028  "maximum number of nodes to regard in the subproblem",
1029  &heurdata->maxnodes, TRUE,DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1030 
1031  SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/"HEUR_NAME"/nodesofs",
1032  "number of nodes added to the contingent of the total nodes",
1033  &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1034 
1035  SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/"HEUR_NAME"/minnodes",
1036  "minimum number of nodes required to start the subproblem",
1037  &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1038 
1039  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/"HEUR_NAME"/nodesquot",
1040  "contingent of sub problem nodes in relation to the number of nodes of the original problem",
1041  &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
1042 
1043  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/"HEUR_NAME"/minimprove",
1044  "factor by which "HEUR_NAME" heuristic should at least improve the incumbent",
1045  &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
1046 
1047  SCIP_CALL( SCIPaddIntParam(scip, "heuristics/"HEUR_NAME"/maxproprounds",
1048  "maximum number of propagation rounds during probing (-1 infinity)",
1049  &heurdata->maxproprounds, TRUE, DEFAULT_MAXPROPROUNDS, -1, INT_MAX/4, NULL, NULL) );
1050 
1051  SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/"HEUR_NAME"/copycuts",
1052  "should all active cuts from cutpool be copied to constraints in subproblem?",
1053  &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
1054 
1055  return SCIP_OKAY;
1056 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:51
static void getVariableBounds(SCIP_VAR *var, SCIP_VAR ***vbvars, int *nvbvars, SCIP_Bool lowerbound)
Definition: heur_vbounds.c:140
#define HEUR_TIMING
Definition: heur_vbounds.c:40
#define DEFAULT_NODESQUOT
Definition: heur_vbounds.c:48
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
Definition: scip.c:36923
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:10071
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:5600
#define HEUR_USESSUBSCIP
Definition: heur_vbounds.c:41
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:15788
#define DEFAULT_NODESOFS
Definition: heur_vbounds.c:47
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
Definition: scip.c:38360
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:591
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1374
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition: heur.c:717
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: scip.c:7014
static void heurdataReset(SCIP_HEURDATA *heurdata)
Definition: heur_vbounds.c:123
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip.c:1206
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip.c:10026
#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_VAR ** SCIPvarGetVlbVars(SCIP_VAR *var)
Definition: var.c:16574
int SCIPvarGetNVubs(SCIP_VAR *var)
Definition: var.c:16604
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, unsigned int timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition: scip.c:6969
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: scip.c:15670
static SCIP_RETCODE initializeCandsLists(SCIP *scip, SCIP_HEURDATA *heurdata)
Definition: heur_vbounds.c:369
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip.c:29766
#define FALSE
Definition: def.h:52
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
Definition: scip.c:37596
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:1864
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition: scip.c:3869
int SCIPgetNPseudoBranchCands(SCIP *scip)
Definition: scip.c:30364
#define TRUE
Definition: def.h:51
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
#define SCIPstatisticMessage
Definition: pub_message.h:104
#define DEFAULT_MINIMPROVE
Definition: heur_vbounds.c:45
SCIP_RETCODE SCIPsetRealParam(SCIP *scip, const char *name, SCIP_Real value)
Definition: scip.c:3914
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:44
static SCIP_RETCODE createNewSol(SCIP *scip, SCIP *subscip, SCIP_VAR **subvars, SCIP_SOL *newsol, SCIP_SOL *subsol, SCIP_Bool *success)
Definition: heur_vbounds.c:573
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 SCIPdebugMessage
Definition: pub_message.h:77
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:19214
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:16227
#define DEFAULT_MAXNODES
Definition: heur_vbounds.c:43
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:1923
#define SCIP_LONGINT_MAX
Definition: def.h:108
static SCIP_DECL_HASHKEYVAL(hashKeyValVar)
Definition: heur_vbounds.c:110
#define HEUR_NAME
Definition: heur_vbounds.c:33
SCIP_Real SCIPgetLowerbound(SCIP *scip)
Definition: scip.c:35061
SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
Definition: misc.c:1287
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:31855
SCIP_RETCODE SCIPcopyCuts(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
Definition: scip.c:2726
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
Definition: tree.c:6699
int SCIPgetNSols(SCIP *scip)
Definition: scip.c:32432
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
#define HEUR_PRIORITY
Definition: heur_vbounds.c:36
int SCIPgetNOrigVars(SCIP *scip)
Definition: scip.c:10511
int SCIPgetNConss(SCIP *scip)
Definition: scip.c:11109
SCIP_RETCODE SCIPcopy(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
Definition: scip.c:3095
SCIP_VAR ** SCIPvarGetVubVars(SCIP_VAR *var)
Definition: var.c:16616
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:19159
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:19221
int SCIPcalcHashtableSize(int minsize)
Definition: misc.c:964
#define HEUR_DESC
Definition: heur_vbounds.c:34
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38292
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip.c:30856
#define DEFAULT_MINFIXINGRATE
Definition: heur_vbounds.c:44
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip.c:37940
static SCIP_RETCODE createTopoSortedVars(SCIP *scip, SCIP_VAR **vars, int nvars, SCIP_HASHMAP *varPosMap, SCIP_VAR **usedvars, int *nusedvars, SCIP_VAR **topovars, int *ntopovars, SCIP_Bool lowerbound)
Definition: heur_vbounds.c:254
static SCIP_DECL_HEURCOPY(heurCopyVbounds)
Definition: heur_vbounds.c:891
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:1882
SCIP_RETCODE SCIPsetSeparating(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip.c:4199
#define HEUR_FREQ
Definition: heur_vbounds.c:37
SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip.c:31809
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:38349
SCIP_RETCODE SCIPpresolve(SCIP *scip)
Definition: scip.c:13437
#define SCIP_CALL(x)
Definition: def.h:258
SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1526
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip.c:755
SCIP_SOL ** SCIPgetSols(SCIP *scip)
Definition: scip.c:32481
#define DEFAULT_MINNODES
Definition: heur_vbounds.c:46
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:512
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip.c:15130
static SCIP_DECL_HEUREXEC(heurExecVbounds)
Definition: heur_vbounds.c:958
static SCIP_RETCODE applyVboundsFixings(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR **vars, int nlbvars, int nubvars, SCIP_SOL *sol, SCIP_Bool *infeasible, SCIP_RESULT *result)
Definition: heur_vbounds.c:497
static SCIP_DECL_HASHGETKEY(hashGetKeyVar)
Definition: heur_vbounds.c:94
SCIP_Real SCIPgetUpperbound(SCIP *scip)
Definition: scip.c:35202
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:15097
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:16436
#define DEFAULT_COPYCUTS
Definition: heur_vbounds.c:50
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:16062
#define SCIP_Bool
Definition: def.h:49
#define SCIPduplicateMemoryArray(scip, ptr, source, num)
Definition: scip.h:19173
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip.c:3824
static SCIP_DECL_HEUREXITSOL(heurExitsolVbounds)
Definition: heur_vbounds.c:921
SCIP_RETCODE SCIPlinkCurrentSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:31549
SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
Definition: scip.c:3550
SCIP_RETCODE SCIPsetSubscipsOff(SCIP *scip, SCIP_Bool quiet)
Definition: scip.c:4124
static SCIP_RETCODE depthFirstSearch(SCIP *scip, SCIP_VAR *var, SCIP_HASHMAP *varPosMap, SCIP_VAR **usedvars, int *nusedvars, SCIP_HASHTABLE *connected, SCIP_VAR **sortedvars, int *nsortedvars, SCIP_Bool lowerbound)
Definition: heur_vbounds.c:163
SCIP_Longint SCIPgetMemUsed(SCIP *scip)
Definition: scip.c:37975
SCIP_RETCODE SCIPfixVarProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval)
Definition: scip.c:29709
LNS heuristic uses the variable lower and upper bounds to determine the search neighborhood.
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
Definition: scip.c:29476
int SCIPvarGetNVlbs(SCIP_VAR *var)
Definition: var.c:16562
SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
Definition: scip.c:7094
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip.c:29607
SCIP_RETCODE SCIPsetPresolving(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip.c:4173
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip.c:33535
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38330
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:1317
SCIP_RETCODE SCIPincludeHeurVbounds(SCIP *scip)
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip.c:13596
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:15953
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition: heur.c:737
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:19176
#define HEUR_FREQOFS
Definition: heur_vbounds.c:38
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip.c:682
#define HEUR_MAXDEPTH
Definition: heur_vbounds.c:39
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip.c:7030
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16072
#define SCIP_Real
Definition: def.h:123
static SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
Definition: heur_vbounds.c:101
#define MIN(x, y)
Definition: memory.c:59
SCIP_RETCODE SCIPsetObjlimit(SCIP *scip, SCIP_Real objlimit)
Definition: scip.c:9567
const char * SCIPgetProbName(SCIP *scip)
Definition: scip.c:9314
#define SCIP_Longint
Definition: def.h:107
SCIP_RETCODE SCIPsetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip.c:31679
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:1499
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition: scip.c:3779
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:502
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip.c:9945
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:16052
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition: scip.c:3638
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:1901
static SCIP_DECL_HEURFREE(heurFreeVbounds)
Definition: heur_vbounds.c:905
static SCIP_RETCODE applyVbounds(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_VAR **probvars, int nlbvars, int nubvars, SCIP_RESULT *result)
Definition: heur_vbounds.c:616
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
#define SCIPfreeMemoryArrayNull(scip, ptr)
Definition: scip.h:19179
SCIP_Real SCIPsumepsilon(SCIP *scip)
Definition: scip.c:37719
default SCIP plugins
SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip.c:32978
#define HEUR_DISPCHAR
Definition: heur_vbounds.c:35
SCIP_Longint SCIPgetNNodes(SCIP *scip)
Definition: scip.c:34065
#define DEFAULT_MAXPROPROUNDS
Definition: heur_vbounds.c:49
SCIP callable library.
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip.c:31403
SCIP_Longint SCIPgetMemExternEstim(SCIP *scip)
Definition: scip.c:37988
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition: scip.c:32673