Scippy

SCIP

Solving Constraint Integer Programs

heur_completesol.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-2022 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 visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file heur_completesol.c
17  * @ingroup DEFPLUGINS_HEUR
18  * @brief COMPLETESOL - primal heuristic trying to complete given partial solutions
19  * @author Jakob Witzig
20  */
21 
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
23 
24 #include "blockmemshell/memory.h"
25 #include "scip/cons_linear.h"
26 #include "scip/heur_completesol.h"
27 #include "scip/pub_event.h"
28 #include "scip/pub_heur.h"
29 #include "scip/pub_message.h"
30 #include "scip/pub_misc.h"
31 #include "scip/pub_sol.h"
32 #include "scip/pub_var.h"
33 #include "scip/scip_branch.h"
34 #include "scip/scip_cons.h"
35 #include "scip/scip_copy.h"
36 #include "scip/scip_event.h"
37 #include "scip/scip_general.h"
38 #include "scip/scip_heur.h"
39 #include "scip/scip_mem.h"
40 #include "scip/scip_message.h"
41 #include "scip/scip_nlp.h"
42 #include "scip/scip_nodesel.h"
43 #include "scip/scip_numerics.h"
44 #include "scip/scip_param.h"
45 #include "scip/scip_prob.h"
46 #include "scip/scip_probing.h"
47 #include "scip/scip_sol.h"
48 #include "scip/scip_solve.h"
49 #include "scip/scip_solvingstats.h"
50 #include "scip/scip_timing.h"
51 #include "scip/scip_tree.h"
52 #include "scip/scip_var.h"
53 #include <string.h>
54 
55 #define HEUR_NAME "completesol"
56 #define HEUR_DESC "primal heuristic trying to complete given partial solutions"
57 #define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
58 #define HEUR_PRIORITY 0
59 #define HEUR_FREQ 0
60 #define HEUR_FREQOFS 0
61 #define HEUR_MAXDEPTH 0
62 #define HEUR_TIMING SCIP_HEURTIMING_BEFOREPRESOL | SCIP_HEURTIMING_BEFORENODE
63 #define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
64 
65 /* default values for heuristic plugins */
66 #define DEFAULT_MAXNODES 5000LL /**< maximum number of nodes to regard in the subproblem */
67 #define DEFAULT_MAXUNKRATE 0.85 /**< maximum percentage of unknown solution values */
68 #define DEFAULT_ADDALLSOLS FALSE /**< should all subproblem solutions be added to the original SCIP? */
69 #define DEFAULT_MINNODES 50LL /**< minimum number of nodes to regard in the subproblem */
70 #define DEFAULT_NODESOFS 500LL /**< number of nodes added to the contingent of the total nodes */
71 #define DEFAULT_NODESQUOT 0.1 /**< subproblem nodes in relation to nodes of the original problem */
72 #define DEFAULT_LPLIMFAC 2.0 /**< factor by which the limit on the number of LP depends on the node limit */
73 #define DEFAULT_OBJWEIGHT 1.0 /**< weight of the original objective function (1: only original objective) */
74 #define DEFAULT_BOUNDWIDENING 0.1 /**< bound widening factor applied to continuous variables
75  * (0: round bounds to next integer, 1: relax to global bounds)
76  */
77 #define DEFAULT_MINIMPROVE 0.01 /**< factor by which the incumbent should be improved at least */
78 #define DEFAULT_MINOBJWEIGHT 1e-3 /**< minimal weight for original objective function (zero could lead to infinite solutions) */
79 #define DEFAULT_IGNORECONT FALSE /**< should solution values for continuous variables be ignored? */
80 #define DEFAULT_BESTSOLS 5 /**< heuristic stops, if the given number of improving solutions were found (-1: no limit) */
81 #define DEFAULT_MAXPROPROUNDS 10 /**< maximal number of iterations in propagation (-1: no limit) */
82 #define DEFAULT_MAXLPITER -1LL /**< maximal number of LP iterations (-1: no limit) */
83 #define DEFAULT_MAXCONTVARS -1 /**< maximal number of continuous variables after presolving (-1: no limit) */
84 #define DEFAULT_BEFOREPRESOL TRUE /**< should the heuristic run before presolving? */
85 
86 /* event handler properties */
87 #define EVENTHDLR_NAME "Completesol"
88 #define EVENTHDLR_DESC "LP event handler for " HEUR_NAME " heuristic"
89 
90 
91 /** primal heuristic data */
92 struct SCIP_HeurData
93 {
94  SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
95  SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
96  SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
97  SCIP_Longint maxlpiter; /**< maximal number of LP iterations (-1: no limit) */
98  SCIP_Real maxunknownrate; /**< maximal rate of changed coefficients in the objective function */
99  SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
100  SCIP_Real nodelimit; /**< the nodelimit employed in the current sub-SCIP, for the event handler*/
101  SCIP_Real lplimfac; /**< factor by which the limit on the number of LP depends on the node limit */
102  SCIP_Real objweight; /**< weight of the original objective function (1: only original obj, 0: try to keep to given solution) */
103  SCIP_Real boundwidening; /**< bound widening factor applied to continuous variables
104  * (0: fix variables to given solution values, 1: relax to global bounds)
105  */
106  SCIP_Real minimprove; /**< factor by which the incumbent should be improved at least */
107  SCIP_Bool addallsols; /**< should all subproblem solutions be added to the original SCIP? */
108  SCIP_Bool ignorecont; /**< should solution values for continuous variables be ignored? */
109  SCIP_Bool beforepresol; /**< should the heuristic run before presolving? */
110  int bestsols; /**< heuristic stops, if the given number of improving solutions were found (-1: no limit) */
111  int maxcontvars; /**< maximal number of continuous variables after presolving (-1: no limit) */
112  int maxproprounds; /**< maximal number of iterations in propagation (-1: no limit) */
113 };
114 
115 /* ---------------- Callback methods of event handler ---------------- */
116 
117 /* exec the event handler
118  *
119  * we interrupt the solution process
120  */
121 static
122 SCIP_DECL_EVENTEXEC(eventExecCompletesol)
123 {
124  SCIP_HEURDATA* heurdata;
125 
126  assert(eventhdlr != NULL);
127  assert(eventdata != NULL);
128  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
129  assert(event != NULL);
130  assert(SCIPeventGetType(event) & SCIP_EVENTTYPE_LPSOLVED);
131 
132  heurdata = (SCIP_HEURDATA*)eventdata;
133  assert(heurdata != NULL);
134 
135  /* interrupt solution process of sub-SCIP */
136  if( SCIPgetNLPs(scip) > heurdata->lplimfac * heurdata->nodelimit )
137  {
138  SCIPdebugMsg(scip, "interrupt after %" SCIP_LONGINT_FORMAT " LPs\n",SCIPgetNLPs(scip));
140  }
141 
142  return SCIP_OKAY;
143 }
144 
145 /** creates a subproblem by fixing a number of variables */
146 static
148  SCIP* scip, /**< original SCIP data structure */
149  SCIP* subscip, /**< SCIP data structure for the subproblem */
150  SCIP_HEURDATA* heurdata, /**< heuristic's private data structure */
151  SCIP_VAR** subvars, /**< the variables of the subproblem */
152  SCIP_SOL* partialsol, /**< partial solution */
153  SCIP_Bool* tightened /**< array to store for which variables we have found bound tightenings */
154  )
155 {
156  SCIP_VAR** vars;
157  SCIP_CONS* objcons;
158  SCIP_Real epsobj;
159  SCIP_Real cutoff;
160  SCIP_Real upperbound;
161  char consobjname[SCIP_MAXSTRLEN];
162  int nvars;
163  int i;
164 
165  assert(scip != NULL);
166  assert(subscip != NULL);
167  assert(subvars != NULL);
168  assert(heurdata != NULL);
169 
170  /* if there is already a solution, add an objective cutoff */
171  if( SCIPgetNSols(scip) > 0 )
172  {
173  assert(!SCIPisInfinity(scip, SCIPgetUpperbound(scip)));
174 
175  upperbound = SCIPgetUpperbound(scip) - SCIPsumepsilon(scip);
176 
177  if( !SCIPisInfinity(scip, -1.0 * SCIPgetLowerbound(scip)) )
178  cutoff = (1 - heurdata->minimprove) * SCIPgetUpperbound(scip) + heurdata->minimprove * SCIPgetLowerbound(scip);
179  else
180  {
181  if( SCIPgetUpperbound(scip) >= 0 )
182  cutoff = (1 - heurdata->minimprove) * SCIPgetUpperbound(scip);
183  else
184  cutoff = (1 + heurdata->minimprove) * SCIPgetUpperbound(scip);
185  }
186  cutoff = MIN(upperbound, cutoff);
187  SCIPdebugMsg(scip, "set cutoff=%g for sub-SCIP\n", cutoff);
188  }
189  else
190  cutoff = SCIPinfinity(scip);
191 
192  /* calculate objective coefficients for all potential epsilons */
193  if( SCIPisEQ(scip, heurdata->objweight, 1.0) )
194  return SCIP_OKAY;
195  else if( !SCIPisInfinity(scip, cutoff) )
196  epsobj = 1.0;
197  else
198  {
199  /* divide by objweight to avoid changing objective coefficient of original problem variables */
200  epsobj = (1.0 - heurdata->objweight)/heurdata->objweight;
201 
202  /* scale with -1 if we have a maximization problem */
204  epsobj *= -1.0;
205  }
206 
207  /* get active variables */
208  vars = SCIPgetVars(scip);
209  nvars = SCIPgetNVars(scip);
210 
211  objcons = NULL;
212 
213  /* add constraints to measure the distance to the given partial solution */
214  for( i = 0; i < nvars; i++ )
215  {
216  SCIP_Real solval;
217  int idx;
218 
219  assert(SCIPvarIsActive(vars[i]));
220 
221  if( subvars[i] == NULL )
222  continue;
223 
224  /* add objective function as a constraint, if a primal bound exists */
225  if( SCIPisInfinity(scip, cutoff) )
226  {
227  /* create the constraints */
228  if( objcons == NULL )
229  {
230  SCIP_Real lhs;
231  SCIP_Real rhs;
232 
233  if( SCIPgetObjsense(subscip) == SCIP_OBJSENSE_MINIMIZE )
234  {
235  lhs = -SCIPinfinity(subscip);
236  rhs = cutoff;
237  }
238  else
239  {
240  lhs = cutoff;
241  rhs = SCIPinfinity(subscip);
242  }
243 
244  (void)SCIPsnprintf(consobjname, SCIP_MAXSTRLEN, "obj");
245  SCIP_CALL( SCIPcreateConsBasicLinear(subscip, &objcons, consobjname, 0, NULL, NULL, lhs, rhs) );
246  }
247 
248  /* add the variable to the constraints */
249  SCIP_CALL( SCIPaddCoefLinear(subscip, objcons, subvars[i], SCIPvarGetObj(subvars[i])) );
250 
251  /* set objective coefficient to 0.0 */
252  SCIP_CALL( SCIPchgVarObj(subscip, subvars[i], 0.0) );
253  }
254 
255  solval = SCIPgetSolVal(scip, partialsol, vars[i]);
256 
257  /* skip variables with unknown solution value */
258  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
259  continue;
260 
261  idx = SCIPvarGetProbindex(vars[i]);
262  assert(idx >= 0);
263 
264  /* skip variables where we already found some bound tightenings */
265  if( tightened[idx] == FALSE )
266  {
267  /* special case: vars[i] is binary; we do not add an extra variable, but we mimic the behavior we would get with it.
268  * E.g., if the solval is 0.3, setting the variable to 0 would give a cost of 0.3 * epsobj, setting it to 1 gives
269  * 0.7 * epsobj. Thus, 0.3 * epsobj can be treated as a constant in the objective function and the variable gets
270  * an objective coefficient of 0.4 * epsobj.
271  */
272  if( SCIPvarIsBinary(vars[i]) )
273  {
274  SCIP_Real frac = SCIPfeasFrac(scip, solval);
275  SCIP_Real objcoef;
276 
277  frac = MIN(frac, 1-frac);
278  objcoef = (1 - 2*frac) * epsobj * (int)SCIPgetObjsense(scip);
279 
280  if( solval > 0.5 )
281  {
282  SCIP_CALL( SCIPchgVarObj(scip, vars[i], -objcoef) );
283  }
284  else
285  {
286  SCIP_CALL( SCIPchgVarObj(scip, vars[i], objcoef) );
287  }
288  }
289  else
290  {
291  SCIP_CONS* conspos;
292  SCIP_CONS* consneg;
293  SCIP_VAR* eps;
294  char consnamepos[SCIP_MAXSTRLEN];
295  char consnameneg[SCIP_MAXSTRLEN];
296  char epsname[SCIP_MAXSTRLEN];
297 
298  /* create two new variables */
299  (void)SCIPsnprintf(epsname, SCIP_MAXSTRLEN, "eps_%s", SCIPvarGetName(subvars[i]));
300 
301  SCIP_CALL( SCIPcreateVarBasic(subscip, &eps, epsname, 0.0, SCIPinfinity(scip), epsobj, SCIP_VARTYPE_CONTINUOUS) );
302  SCIP_CALL( SCIPaddVar(subscip, eps) );
303 
304  /* create two constraints */
305  (void)SCIPsnprintf(consnamepos, SCIP_MAXSTRLEN, "cons_%s_pos", SCIPvarGetName(subvars[i]));
306  (void)SCIPsnprintf(consnameneg, SCIP_MAXSTRLEN, "cons_%s_neq", SCIPvarGetName(subvars[i]));
307 
308  /* x_{i} - s_{i} <= e_{i} <==> x_{i} - e_{i} <= s_{i} */
309  SCIP_CALL( SCIPcreateConsBasicLinear(subscip, &conspos, consnamepos, 0, NULL, NULL, -SCIPinfinity(scip), solval) );
310  SCIP_CALL( SCIPaddCoefLinear(subscip, conspos, subvars[i], 1.0) );
311  SCIP_CALL( SCIPaddCoefLinear(subscip, conspos, eps, -1.0) );
312  SCIP_CALL( SCIPaddCons(subscip, conspos) );
313  SCIP_CALL( SCIPreleaseCons(subscip, &conspos) );
314 
315  /* s_{i} - x_{i} <= e_{i} <==> e_{i} - x_{i} >= s_{i} */
316  SCIP_CALL( SCIPcreateConsBasicLinear(subscip, &consneg, consnameneg, 0, NULL, NULL, solval, SCIPinfinity(scip)) );
317  SCIP_CALL( SCIPaddCoefLinear(subscip, consneg, subvars[i], -1.0) );
318  SCIP_CALL( SCIPaddCoefLinear(subscip, consneg, eps, 1.0) );
319  SCIP_CALL( SCIPaddCons(subscip, consneg) );
320  SCIP_CALL( SCIPreleaseCons(subscip, &consneg) );
321 
322  /* release the variables */
323  SCIP_CALL( SCIPreleaseVar(subscip, &eps) );
324  }
325  }
326  }
327 
328  /* add and release the constraint representing the original objective function */
329  if( objcons != NULL )
330  {
331  SCIP_CALL( SCIPaddCons(subscip, objcons) );
332  SCIP_CALL( SCIPreleaseCons(subscip, &objcons) );
333  }
334 
335  return SCIP_OKAY;
336 }
337 
338 /** perform a probing bound change or fixes the variable */
339 static
341  SCIP* scip, /**< original SCIP data structure */
342  SCIP_VAR* var, /**< problem variable */
343  SCIP_Real newval, /**< new bound */
344  SCIP_BRANCHDIR branchdir, /**< bound change direction */
345  SCIP_Bool* success /**< pointer to store whether the bound could be tightened */
346  )
347 {
348  SCIP_Real ub;
349  SCIP_Real lb;
350 
351  assert(scip != NULL);
352  assert(var != NULL);
353 
354  (*success) = FALSE;
355 
356  ub = SCIPvarGetUbLocal(var);
357  lb = SCIPvarGetLbLocal(var);
358 
359  switch (branchdir) {
361  if( SCIPisLT(scip, newval, ub) && SCIPisGE(scip, newval, lb) )
362  {
363  SCIP_CALL( SCIPchgVarUbProbing(scip, var, newval) );
364  (*success) = TRUE;
365  }
366  break;
368  if( SCIPisLE(scip, newval, ub) && SCIPisGT(scip, newval, lb) )
369  {
370  SCIP_CALL( SCIPchgVarLbProbing(scip, var, newval) );
371  (*success) = TRUE;
372  }
373  break;
375  if( SCIPisLE(scip, newval, ub) && SCIPisGE(scip, newval, lb) )
376  {
377  SCIP_CALL( SCIPfixVarProbing(scip, var, newval) );
378  (*success) = TRUE;
379  }
380  break;
381  default:
382  return SCIP_INVALIDDATA;
383  }/*lint !e788*/
384 
385  return SCIP_OKAY;
386 }
387 
388 /** tries variables bound changes guided by the given solution */
389 static
391  SCIP* scip, /**< original SCIP data structure */
392  SCIP_HEURDATA* heurdata, /**< heuristic's private data structure */
393  SCIP_VAR** vars, /**< problem variables */
394  int nvars, /**< number of problem variables */
395  SCIP_SOL* sol, /**< solution to guide the bound changes */
396  SCIP_Bool* tightened, /**< array to store if variable bound could be tightened */
397  SCIP_Bool* infeasible /**< pointer to store whether subproblem is infeasible */
398  )
399 {
400 #ifndef NDEBUG
401  SCIP_Bool incontsection;
402 #endif
403  SCIP_Bool abortearly;
404  SCIP_Bool cutoff;
405  SCIP_Bool probingsuccess;
406  SCIP_Longint ndomreds;
407  SCIP_Longint ndomredssum;
408  int nbndtightenings;
409  int v;
410 
411  assert(scip != NULL);
412  assert(heurdata != NULL);
413  assert(vars != NULL);
414  assert(nvars >= 0);
415  assert(sol != NULL);
416  assert(tightened != NULL);
417 
419 
420  SCIPdebugMsg(scip, "> start probing along the solution values\n");
421 
422  *infeasible = FALSE;
423  abortearly = FALSE;
424  nbndtightenings = 0;
425  ndomredssum = 0;
426 #ifndef NDEBUG
427  incontsection = FALSE;
428 #endif
429 
430  /* there is at least one integral variable; open one probing node for all non-continuous variables */
431  if( nvars - SCIPgetNContVars(scip) > 0 )
432  {
433  SCIP_CALL( SCIPnewProbingNode(scip) );
434  }
435 
436  for( v = 0; v < nvars && !abortearly; v++ )
437  {
438  SCIP_Real solval;
439 
440  assert(SCIPvarIsActive(vars[v]));
441 
442  cutoff = FALSE;
443  ndomreds = 0;
444 
445 #ifndef NDEBUG
446  incontsection |= (!SCIPvarIsIntegral(vars[v])); /*lint !e514*/
447  assert(!incontsection || !SCIPvarIsIntegral(vars[v]));
448 #endif
449 
450  /* return if we have found enough domain reductions tightenings */
451  if( ndomredssum > 0.3*nvars )
452  break;
453 
454  solval = SCIPgetSolVal(scip, sol, vars[v]);
455 
456  /* skip unknown variables */
457  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
458  continue;
459  assert(!SCIPisInfinity(scip, solval) && !SCIPisInfinity(scip, -solval));
460 
461  /* variable is binary or integer */
462  if( SCIPvarIsIntegral(vars[v]) )
463  {
464  /* the solution value is integral, try to fix them */
465  if( SCIPisIntegral(scip, solval) )
466  {
467  SCIP_CALL( chgProbingBound(scip, vars[v], solval, SCIP_BRANCHDIR_FIXED, &probingsuccess) );
468  tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
469  ++nbndtightenings;
470 
471 #ifdef SCIP_MORE_DEBUG
472  SCIPdebugMsg(scip, "> fix variable <%s> = [%g,%g] to %g \n", SCIPvarGetName(vars[v]),
473  SCIPvarGetLbGlobal(vars[v]), SCIPvarGetUbGlobal(vars[v]), solval);
474 #endif
475  }
476  else
477  {
478  SCIP_Real ub = SCIPceil(scip, solval) + 1.0;
479  SCIP_Real lb = SCIPfloor(scip, solval) - 1.0;
480 
481  /* try tightening of upper bound */
482  if( SCIPisLT(scip, ub, SCIPvarGetUbLocal(vars[v])) )
483  {
484  SCIP_CALL( chgProbingBound(scip, vars[v], solval, SCIP_BRANCHDIR_DOWNWARDS, &probingsuccess) );
485  tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
486  ++nbndtightenings;
487 
488 #ifdef SCIP_MORE_DEBUG
489  SCIPdebugMsg(scip, "> tighten upper bound of variable <%s>: %g to %g\n", SCIPvarGetName(vars[v]),
490  SCIPvarGetUbGlobal(vars[v]), ub);
491 #endif
492  }
493 
494  /* try tightening of lower bound */
495  if( SCIPisGT(scip, lb, SCIPvarGetLbLocal(vars[v])) )
496  {
497  SCIP_CALL( chgProbingBound(scip, vars[v], solval, SCIP_BRANCHDIR_UPWARDS, &probingsuccess) );
498  tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
499  ++nbndtightenings;
500 
501 #ifdef SCIP_MORE_DEBUG
502  SCIPdebugMsg(scip, "> tighten lower bound of variable <%s>: %g to %g\n", SCIPvarGetName(vars[v]),
503  SCIPvarGetLbGlobal(vars[v]), ub);
504 #endif
505  }
506  }
507  }
508  /* variable is continuous */
509  else
510  {
511  /* fix to lb or ub */
512  if( SCIPisEQ(scip, solval, SCIPvarGetLbLocal(vars[v])) || SCIPisEQ(scip, solval, SCIPvarGetUbLocal(vars[v])) )
513  {
514  /* open a new probing node */
515  if( SCIPgetProbingDepth(scip) < SCIP_MAXTREEDEPTH-10 )
516  {
517  SCIP_CALL( SCIPnewProbingNode(scip) );
518 
519  SCIP_CALL( chgProbingBound(scip, vars[v], solval, SCIP_BRANCHDIR_FIXED, &probingsuccess) );
520 
521  /* skip propagation if the bound could not be changed, e.g., already tightened due to previous
522  * domain propagation
523  */
524  if( probingsuccess )
525  {
526  SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, &cutoff, &ndomreds) );
527  }
528 
529  if( cutoff )
530  {
531  ndomreds = 0;
533  }
534  else
535  {
536  assert(SCIPvarGetProbindex(vars[v]) >= 0);
537  tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
538  ++nbndtightenings;
539 #ifdef SCIP_MORE_DEBUG
540  SCIPdebugMsg(scip, "> fix variable <%s> = [%g,%g] to %g (ndomreds=%lld)\n", SCIPvarGetName(vars[v]),
541  SCIPvarGetLbGlobal(vars[v]), SCIPvarGetUbGlobal(vars[v]), solval, ndomreds);
542 #endif
543  }
544  }
545  else
546  /* abort probing */
547  abortearly = TRUE;
548  }
549  else
550  {
551  SCIP_Real offset;
552  SCIP_Real newub = SCIPvarGetUbGlobal(vars[v]);
553  SCIP_Real newlb = SCIPvarGetLbGlobal(vars[v]);
554 
555  /* both bound are finite */
556  if( !SCIPisInfinity(scip, -newlb) && !SCIPisInfinity(scip, newub) )
557  offset = REALABS(heurdata->boundwidening * (newub-newlb));
558  else
559  {
560  offset = 0.0;
561 
562  /* if exactly one bound is finite, widen bound w.r.t. solution value and finite bound */
563  if( !SCIPisInfinity(scip, -newlb) )
564  offset = REALABS(heurdata->boundwidening * (solval-newlb));
565  else if( !SCIPisInfinity(scip, newub) )
566  offset = REALABS(heurdata->boundwidening * (newub-solval));
567  }
568 
569  /* update bounds */
570  newub = SCIPceil(scip, solval) + offset;
571  newlb = SCIPfloor(scip, solval) - offset;
572 
573  /* try tightening of upper bound */
574  if( SCIPisLT(scip, newub, SCIPvarGetUbLocal(vars[v])) )
575  {
576  /* open a new probing node */
577  if( SCIPgetProbingDepth(scip) < SCIP_MAXTREEDEPTH-10 )
578  {
579  SCIP_CALL( SCIPnewProbingNode(scip) );
580  SCIP_CALL( chgProbingBound(scip, vars[v], newub, SCIP_BRANCHDIR_DOWNWARDS, &probingsuccess) );
581 
582  /* skip propagation if the bound could not be changed, e.g., already tightened due to previous
583  * domain propagation
584  */
585  if( probingsuccess )
586  {
587  SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, &cutoff, &ndomreds) );
588  }
589 
590  if( cutoff )
591  {
592  ndomreds = 0;
593 
594  /* backtrack to last feasible probing node */
596 
597  /* we can tighten the lower bound by newub */
598  SCIP_CALL( chgProbingBound(scip, vars[v], newub, SCIP_BRANCHDIR_UPWARDS, &probingsuccess) );
599 
600  /* propagate the new bound */
601  SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, &cutoff, &ndomreds) );
602 
603  /* there is no feasible solution w.r.t. the current bounds */
604  if( cutoff )
605  {
606  SCIPdebugMsg(scip, "> subproblem is infeasible within the local bounds\n");
607  *infeasible = TRUE;
608  return SCIP_OKAY;
609  }
610 #ifdef SCIP_MORE_DEBUG
611  SCIPdebugMsg(scip, "> tighten lower bound of variable <%s>: %g to %g\n",
612  SCIPvarGetName(vars[v]), SCIPvarGetLbGlobal(vars[v]), newub);
613 #endif
614  }
615  else
616  {
617  assert(SCIPvarGetProbindex(vars[v]) >= 0);
618  tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
619  ++nbndtightenings;
620 #ifdef SCIP_MORE_DEBUG
621  SCIPdebugMsg(scip, "> tighten upper bound of variable <%s>: %g to %g (ndomreds=%lld)\n",
622  SCIPvarGetName(vars[v]), SCIPvarGetUbGlobal(vars[v]), newub, ndomreds);
623 #endif
624  }
625  }
626  else
627  /* abort probing */
628  abortearly = TRUE;
629  }
630 
631  /* try tightening of lower bound */
632  if( SCIPisGT(scip, newlb, SCIPvarGetLbLocal(vars[v])) )
633  {
634  /* open a new probing node */
635  if( SCIPgetProbingDepth(scip) < SCIP_MAXTREEDEPTH-10 )
636  {
637  SCIP_CALL( SCIPnewProbingNode(scip) );
638  SCIP_CALL( chgProbingBound(scip, vars[v], newlb, SCIP_BRANCHDIR_UPWARDS, &probingsuccess) );
639 
640  /* skip propagation if the bound could not be changed, e.g., already tightened due to previous
641  * domain propagation
642  */
643  if( probingsuccess )
644  {
645  SCIP_CALL( SCIPpropagateProbing(scip, -1, &cutoff, &ndomreds) );
646  }
647 
648  if( cutoff )
649  {
650  ndomreds = 0;
651 
652  /* backtrack to last feasible probing node */
654 
655  /* we can tighten the upper bound by newlb */
656  SCIP_CALL( chgProbingBound(scip, vars[v], newlb, SCIP_BRANCHDIR_DOWNWARDS, &probingsuccess) );
657 
658  /* propagate the new bound */
659  SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, &cutoff, &ndomreds) );
660 
661  /* there is no feasible solution w.r.t. the current bounds */
662  if( cutoff )
663  {
664  SCIPdebugMsg(scip, "> subproblem is infeasible within the local bounds\n");
665  *infeasible = TRUE;
666  return SCIP_OKAY;
667  }
668 #ifdef SCIP_MORE_DEBUG
669  SCIPdebugMsg(scip, "> tighten upper bound of variable <%s>: %g to %g\n",
670  SCIPvarGetName(vars[v]), SCIPvarGetUbGlobal(vars[v]), newlb);
671 #endif
672  }
673  else
674  {
675  assert(SCIPvarGetProbindex(vars[v]) >= 0);
676  tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
677  ++nbndtightenings;
678 #ifdef SCIP_MORE_DEBUG
679  SCIPdebugMsg(scip, "> tighten lower bound of variable <%s>: %g to %g (ndomreds=%lld)\n",
680  SCIPvarGetName(vars[v]), SCIPvarGetLbGlobal(vars[v]), newlb, ndomreds);
681 #endif
682  }
683  }
684  else
685  /* abort probing */
686  abortearly = TRUE;
687  }
688  }
689  }
690 
691  ndomredssum += ndomreds;
692  }
693 
694  SCIPdebugMsg(scip, "> found %d bound tightenings and %lld induced domain reductions (abort=%u).\n", nbndtightenings,
695  ndomredssum, abortearly);
696 
697  return SCIP_OKAY;
698 }
699 
700 /* setup and solve the sub-SCIP */
701 static
703  SCIP* scip, /**< original SCIP data structure */
704  SCIP* subscip, /**< sub-SCIP data structure */
705  SCIP_HEUR* heur, /**< heuristic data structure */
706  SCIP_HEURDATA* heurdata, /**< heuristic's private data structure */
707  SCIP_RESULT* result, /**< result data structure */
708  SCIP_Longint nstallnodes, /**< number of stalling nodes for the subproblem */
709  SCIP_SOL* partialsol, /**< partial solution */
710  SCIP_Bool* tightened /**< array to store whether a variable was already tightened */
711  )
712 {
713  SCIP_HASHMAP* varmapf;
714  SCIP_VAR** vars;
715  SCIP_VAR** subvars = NULL;
716  SCIP_EVENTHDLR* eventhdlr;
717  int nvars;
718  int i;
719 
720  SCIP_SOL** subsols;
721  int nsubsols;
722 
723  SCIP_Bool valid;
724  SCIP_Bool success;
725  SCIP_RETCODE retcode;
726 
727  assert(scip != NULL);
728  assert(subscip != NULL);
729  assert(heur != NULL);
730  assert(heurdata != NULL);
731  assert(result != NULL);
732  assert(partialsol != NULL);
733 
734  vars = SCIPgetVars(scip);
735  nvars = SCIPgetNVars(scip);
736 
737  /* create the variable mapping hash map */
738  SCIP_CALL( SCIPhashmapCreate(&varmapf, SCIPblkmem(subscip), nvars) );
739 
740  eventhdlr = NULL;
741  valid = FALSE;
742 
743  /* copy complete SCIP instance */
744  SCIP_CALL( SCIPcopyConsCompression(scip, subscip, varmapf, NULL, "completesol", NULL, NULL, 0, FALSE, FALSE, FALSE,
745  TRUE, &valid) );
746  SCIPdebugMsg(scip, "Copying the SCIP instance returned with valid=%u.\n", valid);
747 
748  /* create event handler for LP events */
749  SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecCompletesol, NULL) );
750  if( eventhdlr == NULL )
751  {
752  SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
753  return SCIP_PLUGINNOTFOUND;
754  }
755 
756  /* allocate memory to align the SCIP and the sub-SCIP variables */
757  SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
758 
759  /* map all variables */
760  for( i = 0; i < nvars; i++ )
761  subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapf, vars[i]);
762 
763  /* free hash map */
764  SCIPhashmapFree(&varmapf);
765 
766  /* create a new problem, which fixes variables with same value in bestsol and LP relaxation */
767  SCIP_CALL( createSubproblem(scip, subscip, heurdata, subvars, partialsol, tightened) );
768  SCIPdebugMsg(scip, "Completesol subproblem: %d vars, %d cons\n", SCIPgetNVars(subscip), SCIPgetNConss(subscip));
769 
770  /* do not abort subproblem on CTRL-C */
771  SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
772 
773 #ifdef SCIP_DEBUG
774  /* for debugging, enable full output */
775  SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", SCIP_VERBLEVEL_FULL) );
776  SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", -1) );
777 #else
778  /* disable statistic timing inside sub SCIP and output to console */
779  SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", (int) SCIP_VERBLEVEL_NONE) );
780  SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
781 #endif
782 
783  /* set limits for the subproblem */
784  SCIP_CALL( SCIPcopyLimits(scip, subscip) );
785  heurdata->nodelimit = heurdata->maxnodes;
786  SCIP_CALL( SCIPsetLongintParam(subscip, "limits/stallnodes", nstallnodes) );
787  SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", heurdata->maxnodes) );
788  SCIP_CALL( SCIPsetIntParam(subscip, "limits/bestsol", heurdata->bestsols) );
789 
790  /* limit the number of LP iterations */
791  SCIP_CALL( SCIPsetLongintParam(subscip, "lp/iterlim", heurdata->maxlpiter) );
792  SCIP_CALL( SCIPsetLongintParam(subscip, "lp/rootiterlim", heurdata->maxlpiter) );
793 
794  /* forbid recursive call of heuristics and separators solving sub-SCIPs */
795  SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
796 
797  /* disable cutting plane separation */
799 
800  /* disable expensive presolving */
802 
803  /* use best estimate node selection */
804  if( SCIPfindNodesel(subscip, "estimate") != NULL && !SCIPisParamFixed(subscip, "nodeselection/estimate/stdpriority") )
805  {
806  SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/estimate/stdpriority", INT_MAX/4) );
807  }
808 
809  /* use inference branching */
810  if( SCIPfindBranchrule(subscip, "inference") != NULL && !SCIPisParamFixed(subscip, "branching/inference/priority") )
811  {
812  SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
813  }
814 
815  /* disable conflict analysis */
816  if( !SCIPisParamFixed(subscip, "conflict/enable") )
817  {
818  SCIP_CALL( SCIPsetBoolParam(subscip, "conflict/enable", FALSE) );
819  }
820 
821  /* speed up sub-SCIP by not checking dual LP feasibility */
822  SCIP_CALL( SCIPsetBoolParam(subscip, "lp/checkdualfeas", FALSE) );
823 
824  SCIP_CALL( SCIPtransformProb(subscip) );
825  SCIP_CALL( SCIPcatchEvent(subscip, SCIP_EVENTTYPE_LPSOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, NULL) );
826 
827  /* solve the subproblem */
828  SCIPdebugMsg(scip, "solving subproblem: nstallnodes=%" SCIP_LONGINT_FORMAT ", maxnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->maxnodes);
829 
830  /* errors in solving the subproblem should not kill the overall solving process;
831  * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
832  */
833 
834  retcode = SCIPpresolve(subscip);
835 
836  /* errors in presolving the subproblem should not kill the overall solving process;
837  * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
838  */
839  if( retcode != SCIP_OKAY )
840  {
841  SCIPwarningMessage(scip, "Error while presolving subproblem in %s heuristic; sub-SCIP terminated with code <%d>\n", HEUR_NAME, retcode);
842 
843  SCIPABORT(); /*lint --e{527}*/
844 
845  goto TERMINATE;
846  }
847 
848  if( SCIPgetStage(subscip) == SCIP_STAGE_PRESOLVED )
849  {
850  SCIPdebugMsg(scip, "presolved instance has bin=%d, int=%d, cont=%d variables\n",
851  SCIPgetNBinVars(subscip), SCIPgetNIntVars(subscip), SCIPgetNContVars(subscip));
852 
853  /* check whether the presolved instance is small enough */
854  if( heurdata->maxcontvars >= 0 && SCIPgetNContVars(subscip) > heurdata->maxcontvars )
855  {
856  SCIPdebugMsg(scip, "presolved instance has too many continuous variables (maxcontvars: %d)\n", heurdata->maxcontvars);
857  goto TERMINATE;
858  }
859 
860  /* set node limit of 1 if the presolved problem is an LP, otherwise we would start branching if an LP iteration
861  * limit was set by the user.
862  */
863  if( !SCIPisNLPEnabled(subscip) && SCIPgetNContVars(subscip) == SCIPgetNVars(subscip) )
864  {
865  SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", 1LL) );
866  }
867 
868  retcode = SCIPsolve(subscip);
869 
870  /* errors in solving the subproblem should not kill the overall solving process;
871  * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
872  */
873  if( retcode != SCIP_OKAY )
874  {
875  SCIPwarningMessage(scip, "Error while solving subproblem in %s heuristic; sub-SCIP terminated with code <%d>\n", HEUR_NAME, retcode);
876 
877  SCIPABORT(); /*lint --e{527}*/
878 
879  goto TERMINATE;
880  }
881  }
882 
883  SCIP_CALL( SCIPdropEvent(subscip, SCIP_EVENTTYPE_LPSOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, -1) );
884 
885  /* print solving statistics of subproblem if we are in SCIP's debug mode */
887 
888  /* check, whether a solution was found;
889  * due to numerics, it might happen that not all solutions are feasible -> try all solutions until one was accepted
890  */
891  nsubsols = SCIPgetNSols(subscip);
892  subsols = SCIPgetSols(subscip);
893  success = FALSE;
894  for( i = 0; i < nsubsols && (!success || heurdata->addallsols); i++ )
895  {
896  SCIP_SOL* newsol;
897 
898  /* create new solution, try to add to SCIP, and free it immediately */
899  SCIP_CALL( SCIPtranslateSubSol(scip, subscip, subsols[i], heur, subvars, &newsol) );
900  SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, FALSE, TRUE, TRUE, TRUE, &success) );
901 
902  if( success )
903  *result = SCIP_FOUNDSOL;
904  }
905 
906  SCIPstatisticPrintf("%s statistic: fixed %6.3f integer variables, needed %6.1f seconds, %" SCIP_LONGINT_FORMAT " nodes, solution %10.4f found at node %" SCIP_LONGINT_FORMAT "\n",
907  HEUR_NAME, 0.0, SCIPgetSolvingTime(subscip), SCIPgetNNodes(subscip), success ? SCIPgetPrimalbound(scip) : SCIPinfinity(scip),
908  nsubsols > 0 ? SCIPsolGetNodenum(SCIPgetBestSol(subscip)) : -1 );
909 
910  /* print message if the completion of a partial solution failed */
911  if( *result != SCIP_FOUNDSOL )
912  {
913  switch( SCIPgetStatus(subscip) )
914  {
916  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (subproblem is infeasible)\n");
917  break;
919  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (node limit exceeded)\n");
920  break;
922  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (time limit exceeded)\n");
923  break;
925  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (memory limit exceeded)\n");
926  break;
927  default:
928  break;
929  } /*lint !e788*/
930  }
931 
932 TERMINATE:
933  SCIPfreeBufferArray(scip, &subvars);
934 
935  return SCIP_OKAY;
936 }
937 
938 /** main procedure of the completesol heuristic, creates and solves a sub-SCIP */
939 static
941  SCIP* scip, /**< original SCIP data structure */
942  SCIP_HEUR* heur, /**< heuristic data structure */
943  SCIP_HEURDATA* heurdata, /**< heuristic's private data structure */
944  SCIP_RESULT* result, /**< result data structure */
945  SCIP_Longint nstallnodes, /**< number of stalling nodes for the subproblem */
946  SCIP_SOL* partialsol /**< partial solution */
947  )
948 {
949  SCIP* subscip;
950  SCIP_VAR** vars;
951  SCIP_Bool* tightened;
952  SCIP_Bool infeasible;
953  SCIP_Bool success;
954  SCIP_RETCODE retcode;
955  int nvars;
956 
957  assert(scip != NULL);
958  assert(heur != NULL);
959  assert(heurdata != NULL);
960  assert(result != NULL);
961  assert(partialsol != NULL);
962 
963  *result = SCIP_DIDNOTRUN;
964 
965  SCIPdebugMsg(scip, "+---+ Start Completesol heuristic +---+\n");
966 
967  /* check whether there is enough time and memory left */
968  SCIP_CALL( SCIPcheckCopyLimits(scip, &success) );
969 
970  if( !success )
971  return SCIP_OKAY;
972 
973  *result = SCIP_DIDNOTFIND;
974 
975  /* get variable data */
976  vars = SCIPgetVars(scip);
977  nvars = SCIPgetNVars(scip);
978 
979  /* get buffer memory and initialize it to FALSE */
980  SCIP_CALL( SCIPallocClearBufferArray(scip, &tightened, nvars) );
981 
982  SCIP_CALL( SCIPstartProbing(scip) );
983 
984  SCIP_CALL( tightenVariables(scip, heurdata, vars, nvars, partialsol, tightened, &infeasible) );
985 
986  if( infeasible )
987  {
988  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (subproblem is infeasible)\n");
989  goto ENDPROBING;
990  }
991 
992  /* initialize the subproblem */
993  SCIP_CALL( SCIPcreate(&subscip) );
994 
995  retcode = setupAndSolve(scip, subscip, heur, heurdata, result, nstallnodes, partialsol, tightened);
996 
997  /* free subproblem */
998  SCIP_CALL( SCIPfree(&subscip) );
999 
1000  SCIP_CALL( retcode );
1001 
1002  ENDPROBING:
1003  SCIPfreeBufferArray(scip, &tightened);
1004  SCIP_CALL( SCIPendProbing(scip) );
1005 
1006  return SCIP_OKAY;
1007 }
1008 
1009 
1010 /*
1011  * Callback methods of primal heuristic
1012  */
1013 
1014 /** copy method for primal heuristic plugins (called when SCIP copies plugins) */
1015 static
1016 SCIP_DECL_HEURCOPY(heurCopyCompletesol)
1017 { /*lint --e{715}*/
1018  assert(scip != NULL);
1019  assert(heur != NULL);
1020  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
1021 
1022  /* call inclusion method of primal heuristic */
1024 
1025  return SCIP_OKAY;
1026 }
1027 
1028 /** destructor of primal heuristic to free user data (called when SCIP is exiting) */
1029 static
1030 SCIP_DECL_HEURFREE(heurFreeCompletesol)
1031 { /*lint --e{715}*/
1032  SCIP_HEURDATA* heurdata;
1033 
1034  assert(heur != NULL);
1035  assert(scip != NULL);
1036 
1037  /* get heuristic data */
1038  heurdata = SCIPheurGetData(heur);
1039  assert(heurdata != NULL);
1040 
1041  /* free heuristic data */
1042  SCIPfreeBlockMemory(scip, &heurdata);
1043  SCIPheurSetData(heur, NULL);
1044 
1045  return SCIP_OKAY;
1046 }
1047 
1048 /** execution method of primal heuristic */
1049 static
1050 SCIP_DECL_HEUREXEC(heurExecCompletesol)
1051 {/*lint --e{715}*/
1052  SCIP_HEURDATA* heurdata;
1053  SCIP_VAR** vars;
1054  SCIP_SOL** partialsols;
1055  SCIP_Longint nstallnodes;
1056  int npartialsols;
1057  int nunknown;
1058  int nfracints;
1059  int nvars;
1060  int s;
1061  int v;
1062 
1063  assert( heur != NULL );
1064  assert( scip != NULL );
1065  assert( result != NULL );
1066 
1067  *result = SCIP_DELAYED;
1068 
1069  /* do not call heuristic of node was already detected to be infeasible */
1070  if( nodeinfeasible )
1071  return SCIP_OKAY;
1072 
1073  /* get heuristic data */
1074  heurdata = SCIPheurGetData(heur);
1075  assert( heurdata != NULL );
1076 
1077  *result = SCIP_DIDNOTRUN;
1078 
1079  if( SCIPisStopped(scip) )
1080  return SCIP_OKAY;
1081 
1082  /* do not run after restart */
1083  if( SCIPgetNRuns(scip) > 1 )
1084  return SCIP_OKAY;
1085 
1086  /* check whether we want to run before presolving */
1087  if( (heurtiming & SCIP_HEURTIMING_BEFOREPRESOL) && !heurdata->beforepresol )
1088  return SCIP_OKAY;
1089 
1090  /* only run before root node */
1091  if( (heurtiming & SCIP_HEURTIMING_BEFORENODE)
1092  && (heurdata->beforepresol || SCIPgetCurrentNode(scip) != SCIPgetRootNode(scip)) )
1093  return SCIP_OKAY;
1094 
1095  /* get variable data and return of no variables are left in the problem */
1096  vars = SCIPgetVars(scip);
1097  nvars = SCIPgetNVars(scip);
1098 
1099  if( nvars == 0 )
1100  return SCIP_OKAY;
1101 
1102  /* calculate the maximal number of branching nodes until heuristic is aborted */
1103  nstallnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
1104 
1105  /* reward Completesol if it succeeded often */
1106  nstallnodes = (SCIP_Longint)(nstallnodes * 3.0 * (SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur) + 1.0));
1107  nstallnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-SCIP as 100 nodes */
1108  nstallnodes += heurdata->nodesofs;
1109 
1110  /* determine the node limit for the current process */
1111  nstallnodes = MIN(nstallnodes, heurdata->maxnodes);
1112 
1113  /* check whether we have enough nodes left to call subproblem solving */
1114  if( nstallnodes < heurdata->minnodes )
1115  {
1116  SCIPdebugMsg(scip, "skipping Complete: nstallnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n",
1117  nstallnodes, heurdata->minnodes);
1118  return SCIP_OKAY;
1119  }
1120 
1121  /* check the number of variables with unknown value and continuous variables with fractional value */
1122  nfracints = 0;
1123 
1124  /* get all partial sols */
1125  npartialsols = SCIPgetNPartialSols(scip);
1126  partialsols = SCIPgetPartialSols(scip);
1127 
1128  /* loop over all partial solutions */
1129  for( s = 0; s < npartialsols; s++ )
1130  {
1131  SCIP_SOL* sol;
1132  SCIP_Real solval;
1133  SCIP_Real unknownrate;
1134 
1135  sol = partialsols[s];
1136  assert(sol != NULL);
1137  assert(SCIPsolIsPartial(sol));
1138 
1139  nunknown = 0;
1140  /* loop over all variables */
1141  for( v = 0; v < nvars; v++ )
1142  {
1143  assert(SCIPvarIsActive(vars[v]));
1144 
1145  /* skip continuous variables if they should ignored */
1146  if( !SCIPvarIsIntegral(vars[v]) && heurdata->ignorecont )
1147  continue;
1148 
1149  solval = SCIPgetSolVal(scip, sol, vars[v]);
1150 
1151  /* we only want to count variables that are unfixed after the presolving */
1152  if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1153  ++nunknown;
1154  else if( SCIPvarIsIntegral(vars[v]) && !SCIPisIntegral(scip, solval) )
1155  ++nfracints;
1156  }
1157 
1158  if( heurdata->ignorecont )
1159  unknownrate = nunknown/((SCIP_Real)SCIPgetNBinVars(scip) + SCIPgetNIntVars(scip) + SCIPgetNImplVars(scip));
1160  else
1161  unknownrate = nunknown/((SCIP_Real)nvars);
1162  SCIPdebugMsg(scip, "%d (rate %.4f) unknown solution values\n", nunknown, unknownrate);
1163 
1164  /* run the heuristic, if not too many unknown variables exist */
1165  if( unknownrate > heurdata->maxunknownrate )
1166  {
1167  SCIPwarningMessage(scip, "ignore partial solution (%d) because unknown rate is too large (%g > %g)\n", s,
1168  unknownrate, heurdata->maxunknownrate);
1169  continue;
1170  }
1171 
1172  /* all variables have a finite/known solution value all integer variables have an integral solution value,
1173  * and there are no continuous variables
1174  * in the sub-SCIP, all variables would be fixed, so create a new solution without solving a sub-SCIP
1175  */
1176  if( nunknown == 0 && nfracints == 0 && SCIPgetNContVars(scip) == 0 && SCIPgetNImplVars(scip) == 0 )
1177  {
1178  SCIP_SOL* newsol;
1179  SCIP_Bool stored;
1180 
1181  assert(vars != NULL);
1182  assert(nvars >= 0);
1183 
1184  SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) );
1185 
1186  for( v = 0; v < nvars; v++ )
1187  {
1188  solval = SCIPgetSolVal(scip, sol, vars[v]);
1189  assert(solval != SCIP_UNKNOWN); /*lint !e777*/
1190 
1191  SCIP_CALL( SCIPsetSolVal(scip, newsol, vars[v], solval) );
1192  }
1193 
1194  SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, FALSE, TRUE, TRUE, TRUE, &stored) );
1195  if( stored )
1196  *result = SCIP_FOUNDSOL;
1197  }
1198  else
1199  {
1200  /* run the heuristic */
1201  SCIP_CALL( applyCompletesol(scip, heur, heurdata, result, nstallnodes, sol) );
1202  }
1203  }
1204 
1205  return SCIP_OKAY;
1206 }
1207 
1208 
1209 /*
1210  * primal heuristic specific interface methods
1211  */
1212 
1213 /** creates the completesol primal heuristic and includes it in SCIP */
1215  SCIP* scip /**< SCIP data structure */
1216  )
1217 {
1218  SCIP_HEURDATA* heurdata;
1219  SCIP_HEUR* heur;
1220 
1221  /* create completesol primal heuristic data */
1222  SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
1223  assert(heurdata != NULL);
1224 
1225  /* include primal heuristic */
1228  HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecCompletesol, heurdata) );
1229 
1230  assert(heur != NULL);
1231 
1232  /* set non fundamental callbacks via setter functions */
1233  SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyCompletesol) );
1234  SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeCompletesol) );
1235 
1236  /* add completesol primal heuristic parameters */
1237 
1238  SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
1239  "maximum number of nodes to regard in the subproblem",
1240  &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1241 
1242  SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
1243  "minimum number of nodes required to start the subproblem",
1244  &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1245 
1246  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/maxunknownrate",
1247  "maximal rate of unknown solution values",
1248  &heurdata->maxunknownrate, FALSE, DEFAULT_MAXUNKRATE, 0.0, 1.0, NULL, NULL) );
1249 
1250  SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/addallsols",
1251  "should all subproblem solutions be added to the original SCIP?",
1252  &heurdata->addallsols, TRUE, DEFAULT_ADDALLSOLS, NULL, NULL) );
1253 
1254  SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
1255  "number of nodes added to the contingent of the total nodes",
1256  &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1257 
1258  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
1259  "contingent of sub problem nodes in relation to the number of nodes of the original problem",
1260  &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
1261 
1262  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lplimfac",
1263  "factor by which the limit on the number of LP depends on the node limit",
1264  &heurdata->lplimfac, TRUE, DEFAULT_LPLIMFAC, 1.0, SCIP_REAL_MAX, NULL, NULL) );
1265 
1266  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/objweight",
1267  "weight of the original objective function (1: only original objective)",
1268  &heurdata->objweight, TRUE, DEFAULT_OBJWEIGHT, DEFAULT_MINOBJWEIGHT, 1.0, NULL, NULL) );
1269 
1270  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/boundwidening",
1271  "bound widening factor applied to continuous variables (0: fix variables to given solution values, 1: relax to global bounds)",
1272  &heurdata->boundwidening, TRUE, DEFAULT_BOUNDWIDENING, 0.0, 1.0, NULL, NULL) );
1273 
1274  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
1275  "factor by which the incumbent should be improved at least",
1276  &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
1277 
1278  SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/ignorecont",
1279  "should number of continuous variables be ignored?",
1280  &heurdata->ignorecont, FALSE, DEFAULT_IGNORECONT, NULL, NULL) );
1281 
1282  SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/solutions",
1283  "heuristic stops, if the given number of improving solutions were found (-1: no limit)",
1284  &heurdata->bestsols, FALSE, DEFAULT_BESTSOLS, -1, INT_MAX, NULL, NULL) );
1285 
1286  SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxproprounds",
1287  "maximal number of iterations in propagation (-1: no limit)",
1288  &heurdata->maxproprounds, FALSE, DEFAULT_MAXPROPROUNDS, -1, INT_MAX, NULL, NULL) );
1289 
1290  SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/beforepresol",
1291  "should the heuristic run before presolving?",
1292  &heurdata->beforepresol, FALSE, DEFAULT_BEFOREPRESOL, NULL, NULL) );
1293 
1294  SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxlpiter",
1295  "maximal number of LP iterations (-1: no limit)",
1296  &heurdata->maxlpiter, FALSE, DEFAULT_MAXLPITER, -1LL, SCIP_LONGINT_MAX, NULL, NULL) );
1297 
1298  SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxcontvars",
1299  "maximal number of continuous variables after presolving",
1300  &heurdata->maxcontvars, FALSE, DEFAULT_MAXCONTVARS, -1, INT_MAX, NULL, NULL) );
1301 
1302  return SCIP_OKAY;
1303 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
int SCIPgetNIntVars(SCIP *scip)
Definition: scip_prob.c:2080
#define EVENTHDLR_DESC
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
Definition: scip_timing.c:369
#define SCIP_EVENTTYPE_LPSOLVED
Definition: type_event.h:92
SCIP_RETCODE SCIPsetSeparating(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip_param.c:949
#define DEFAULT_NODESQUOT
public methods for SCIP parameter handling
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip_tree.c:82
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:356
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip_probing.c:216
SCIP_RETCODE SCIPcreateConsBasicLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
public methods for node selector plugins
public methods for memory management
static SCIP_RETCODE tightenVariables(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR **vars, int nvars, SCIP_SOL *sol, SCIP_Bool *tightened, SCIP_Bool *infeasible)
int SCIPgetProbingDepth(SCIP *scip)
Definition: scip_probing.c:189
#define DEFAULT_MINOBJWEIGHT
SCIP_Real SCIPgetPrimalbound(SCIP *scip)
#define SCIPallocClearBufferArray(scip, ptr, num)
Definition: scip_mem.h:117
primal heuristic trying to complete given partial solutions
#define HEUR_MAXDEPTH
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17910
#define SCIP_MAXSTRLEN
Definition: def.h:293
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition: heur.c:1587
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17966
#define SCIP_HEURTIMING_BEFORENODE
Definition: type_timing.h:70
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
public solving methods
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: scip_event.c:95
public methods for timing
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1245
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17431
#define DEFAULT_MINIMPROVE
#define DEFAULT_MAXPROPROUNDS
SCIP_SOL ** SCIPgetSols(SCIP *scip)
Definition: scip_sol.c:2254
#define FALSE
Definition: def.h:87
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3014
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:315
SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:102
SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
Definition: scip_copy.c:3278
int SCIPgetNPartialSols(SCIP *scip)
Definition: scip_sol.c:3413
static SCIP_DECL_HEURCOPY(heurCopyCompletesol)
SCIP_Real SCIPinfinity(SCIP *scip)
#define DEFAULT_ADDALLSOLS
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10755
#define DEFAULT_BOUNDWIDENING
#define TRUE
Definition: def.h:86
#define SCIPdebug(x)
Definition: pub_message.h:84
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_RETCODE SCIPsetPresolving(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip_param.c:923
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
Definition: scip_branch.c:288
SCIP_RETCODE SCIPtranslateSubSol(SCIP *scip, SCIP *subscip, SCIP_SOL *subsol, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_SOL **newsol)
Definition: scip_copy.c:1399
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17600
SCIP_RETCODE SCIPcreateVarBasic(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype)
Definition: scip_var.c:185
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:67
public methods for problem variables
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:99
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition: scip_heur.c:108
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:292
#define DEFAULT_BESTSOLS
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3201
SCIP_Real SCIPfeasFrac(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define SCIP_LONGINT_MAX
Definition: def.h:163
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:127
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip_general.c:283
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1362
public methods for SCIP variables
#define HEUR_DISPCHAR
SCIP_NODE * SCIPgetRootNode(SCIP *scip)
Definition: scip_tree.c:101
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:111
SCIP_SOL ** SCIPgetPartialSols(SCIP *scip)
Definition: scip_sol.c:3391
#define SCIPdebugMsg
Definition: scip_message.h:69
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:74
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
int SCIPgetNContVars(SCIP *scip)
Definition: scip_prob.c:2170
real eps
public methods for numerical tolerances
#define DEFAULT_MINNODES
#define EVENTHDLR_NAME
public methods for querying solving statistics
public methods for the branch-and-bound tree
enum SCIP_BranchDir SCIP_BRANCHDIR
Definition: type_history.h:39
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17920
static SCIP_DECL_EVENTEXEC(eventExecCompletesol)
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip_solve.c:2613
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1441
#define SCIPerrorMessage
Definition: pub_message.h:55
SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
Definition: scip_param.c:210
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2768
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip_heur.c:169
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip_probing.c:571
public methods for event handler plugins and event handlers
SCIP_RETCODE SCIPfixVarProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval)
Definition: scip_probing.c:409
#define HEUR_USESSUBSCIP
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition: scip_param.c:420
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip_general.c:474
SCIP_RETCODE SCIPpresolve(SCIP *scip)
Definition: scip_solve.c:2443
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:48
#define DEFAULT_MAXCONTVARS
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip_probing.c:251
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:164
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17251
static SCIP_RETCODE createSubproblem(SCIP *scip, SCIP *subscip, SCIP_HEURDATA *heurdata, SCIP_VAR **subvars, SCIP_SOL *partialsol, SCIP_Bool *tightened)
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3048
SCIP_Bool SCIPisNLPEnabled(SCIP *scip)
Definition: scip_nlp.c:65
#define NULL
Definition: lpi_spx1.cpp:155
static SCIP_RETCODE setupAndSolve(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_RESULT *result, SCIP_Longint nstallnodes, SCIP_SOL *partialsol, SCIP_Bool *tightened)
#define HEUR_TIMING
#define REALABS(x)
Definition: def.h:201
static SCIP_DECL_HEURFREE(heurFreeCompletesol)
public methods for problem copies
public methods for primal CIP solutions
#define SCIP_CALL(x)
Definition: def.h:384
SCIP_Real SCIPgetLowerbound(SCIP *scip)
static SCIP_RETCODE applyCompletesol(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_RESULT *result, SCIP_Longint nstallnodes, SCIP_SOL *partialsol)
#define SCIPstatisticPrintf
Definition: pub_message.h:117
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:216
#define SCIP_HEURTIMING_BEFOREPRESOL
Definition: type_timing.h:86
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition: heur.c:1567
public methods for primal heuristic plugins and divesets
public methods for constraint handler plugins and constraints
#define DEFAULT_MAXUNKRATE
#define DEFAULT_IGNORECONT
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4510
#define DEFAULT_MAXLPITER
SCIP_RETCODE SCIPcopyConsCompression(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool threadsafe, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
Definition: scip_copy.c:2951
#define HEUR_PRIORITY
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
#define SCIP_UNKNOWN
Definition: def.h:198
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition: scip_sol.c:1212
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:84
SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip_event.c:277
int SCIPgetNImplVars(SCIP *scip)
Definition: scip_prob.c:2125
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:1021
SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
Definition: sol.c:2584
#define DEFAULT_OBJWEIGHT
SCIP_RETCODE SCIPtrySolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip_sol.c:3231
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip_param.c:478
SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip_event.c:311
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17758
#define DEFAULT_NODESOFS
SCIP_RETCODE SCIPincludeHeurCompletesol(SCIP *scip)
int SCIPgetNSols(SCIP *scip)
Definition: scip_sol.c:2205
int SCIPgetNRuns(SCIP *scip)
Constraint handler for linear constraints in their most general form, .
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
#define SCIP_MAXTREEDEPTH
Definition: def.h:320
#define DEFAULT_BEFOREPRESOL
int SCIPgetNBinVars(SCIP *scip)
Definition: scip_prob.c:2035
static SCIP_RETCODE chgProbingBound(SCIP *scip, SCIP_VAR *var, SCIP_Real newval, SCIP_BRANCHDIR branchdir, SCIP_Bool *success)
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1990
#define SCIP_REAL_MAX
Definition: def.h:178
public methods for nonlinear relaxation
#define HEUR_FREQ
public methods for branching rule plugins and branching
static SCIP_DECL_HEUREXEC(heurExecCompletesol)
public methods for managing events
general public methods
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition: scip_sol.c:2304
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
public methods for solutions
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1666
int SCIPgetNConss(SCIP *scip)
Definition: scip_prob.c:3040
#define DEFAULT_LPLIMFAC
public methods for the probing mode
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1110
#define HEUR_DESC
public methods for message output
SCIP_SOLORIGIN SCIPsolGetOrigin(SCIP_SOL *sol)
Definition: sol.c:2511
SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
Definition: scip_nodesel.c:225
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1945
#define SCIP_Real
Definition: def.h:177
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:694
public methods for message handling
#define SCIP_Longint
Definition: def.h:162
SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
Definition: scip_copy.c:3235
SCIP_OBJSENSE SCIPgetObjsense(SCIP *scip)
Definition: scip_prob.c:1223
SCIP_RETCODE SCIPtransformProb(SCIP *scip)
Definition: scip_solve.c:358
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define HEUR_NAME
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: scip_heur.c:153
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17976
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip_probing.c:156
SCIP_Real SCIPsumepsilon(SCIP *scip)
SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
Definition: scip_solve.c:3516
SCIP_Real SCIPgetUpperbound(SCIP *scip)
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
Definition: scip_probing.c:110
public methods for primal heuristics
SCIP_Bool SCIPsolIsPartial(SCIP_SOL *sol)
Definition: sol.c:2531
SCIPallocBlockMemory(scip, subsol))
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1352
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_Longint SCIPgetNLPs(SCIP *scip)
#define SCIPABORT()
Definition: def.h:356
public methods for global and local (sub)problems
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17442
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:336
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1352
#define DEFAULT_MAXNODES
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:130
SCIP_RETCODE SCIPsetSubscipsOff(SCIP *scip, SCIP_Bool quiet)
Definition: scip_param.c:874
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
#define HEUR_FREQOFS
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition: scip_param.c:536
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:48
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17580
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip_general.c:315
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:319
memory allocation routines