Scippy

SCIP

Solving Constraint Integer Programs

heur_simplerounding.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-2017 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_simplerounding.c
17  * @brief simple and fast LP rounding heuristic
18  * @author Tobias Achterberg
19  * @author Marc Pfetsch
20  *
21  * The heuristic also tries to round relaxation solutions if available.
22  */
23 
24 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
25 
26 #include <assert.h>
27 #include <string.h>
28 
30 
31 
32 #define HEUR_NAME "simplerounding"
33 #define HEUR_DESC "simple and fast LP rounding heuristic"
34 #define HEUR_DISPCHAR 'r'
35 #define HEUR_PRIORITY 0
36 #define HEUR_FREQ 1
37 #define HEUR_FREQOFS 0
38 #define HEUR_MAXDEPTH -1
39 #define HEUR_TIMING SCIP_HEURTIMING_DURINGLPLOOP | SCIP_HEURTIMING_DURINGPRICINGLOOP
40 #define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
41 
42 #define DEFAULT_ONCEPERNODE FALSE /**< should the heuristic only be called once per node? */
43 
44 /* locally defined heuristic data */
45 struct SCIP_HeurData
46 {
47  SCIP_SOL* sol; /**< working solution */
48  SCIP_Longint lastlp; /**< last LP number where the heuristic was applied */
49  int nroundablevars; /**< number of variables that can be rounded (-1 if not yet calculated) */
50  SCIP_Bool oncepernode; /**< should the heuristic only be called once per node? */
51 };
52 
53 
54 /*
55  * Local methods
56  */
57 
58 /** perform rounding */
59 static
61  SCIP* scip, /**< SCIP main data structure */
62  SCIP_SOL* sol, /**< solution to round */
63  SCIP_VAR** cands, /**< candidate variables */
64  SCIP_Real* candssol, /**< solutions of candidate variables */
65  int ncands, /**< number of candidates */
66  SCIP_RESULT* result /**< pointer to store the result of the heuristic call */
67  )
68 {
69  int c;
70  int nunroundableimplints = 0;
71 
72  /* round all roundable fractional columns in the corresponding direction as long as no unroundable column was found */
73  for (c = 0; c < ncands; ++c)
74  {
75  SCIP_VAR* var;
76  SCIP_Real oldsolval;
77  SCIP_Real newsolval;
78  SCIP_Bool mayrounddown;
79  SCIP_Bool mayroundup;
80 
81  oldsolval = candssol[c];
82  assert( ! SCIPisFeasIntegral(scip, oldsolval) );
83  var = cands[c];
84  assert( SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN );
85  mayrounddown = SCIPvarMayRoundDown(var);
86  mayroundup = SCIPvarMayRoundUp(var);
87  SCIPdebugMsg(scip, "simple rounding heuristic: var <%s>, val=%g, rounddown=%u, roundup=%u\n",
88  SCIPvarGetName(var), oldsolval, mayrounddown, mayroundup);
89 
90  /* choose rounding direction */
91  if ( mayrounddown && mayroundup )
92  {
93  /* we can round in both directions: round in objective function direction */
94  if ( SCIPvarGetObj(var) >= 0.0 )
95  newsolval = SCIPfeasFloor(scip, oldsolval);
96  else
97  newsolval = SCIPfeasCeil(scip, oldsolval);
98  }
99  else if ( mayrounddown )
100  newsolval = SCIPfeasFloor(scip, oldsolval);
101  else if ( mayroundup )
102  newsolval = SCIPfeasCeil(scip, oldsolval);
103  else if( SCIPvarGetType(var) == SCIP_VARTYPE_IMPLINT )
104  {
105  ++nunroundableimplints;
106  continue;
107  }
108  else
109  break;
110 
111  /* store new solution value */
112  SCIP_CALL( SCIPsetSolVal(scip, sol, var, newsolval) );
113  }
114 
115  /* check, if rounding was successful */
116  if( c == ncands )
117  {
118  SCIP_Bool stored;
119  SCIP_Bool checklprows;
120 
121  /* unroundable implicit integers are adjusted. LP rows must be checked afterwards */
122  if( nunroundableimplints > 0 )
123  {
125  checklprows = TRUE;
126  }
127  else
128  checklprows = FALSE;
129 
130  if( SCIPallColsInLP(scip) )
131  {
132  /* check solution for feasibility, and add it to solution store if possible
133  * integrality need not be checked, because all fractional
134  * variables were already moved in feasible direction to the next integer
135  *
136  * feasibility of LP rows must be checked again at the presence of
137  * unroundable, implicit integer variables with fractional LP solution
138  * value
139  */
140  SCIP_CALL( SCIPtrySol(scip, sol, FALSE, FALSE, FALSE, FALSE, checklprows, &stored) );
141  }
142  else
143  {
144  /* if there are variables which are not present in the LP, e.g., for
145  * column generation, we need to check their bounds
146  */
147  SCIP_CALL( SCIPtrySol(scip, sol, FALSE, FALSE, TRUE, FALSE, checklprows, &stored) );
148  }
149 
150  if( stored )
151  {
152 #ifdef SCIP_DEBUG
153  SCIPdebugMsg(scip, "found feasible rounded solution:\n");
154  SCIP_CALL( SCIPprintSol(scip, sol, NULL, FALSE) );
155 #endif
156  *result = SCIP_FOUNDSOL;
157  }
158  }
159  return SCIP_OKAY;
160 }
161 
162 /** perform LP-rounding */
163 static
165  SCIP* scip, /**< SCIP main data structure */
166  SCIP_HEURDATA* heurdata, /**< heuristic data */
167  SCIP_HEURTIMING heurtiming, /**< heuristic timing mask */
168  SCIP_RESULT* result /**< pointer to store the result of the heuristic call */
169  )
170 {
171  SCIP_SOL* sol;
172  SCIP_VAR** lpcands;
173  SCIP_Real* lpcandssol;
174  SCIP_Longint nlps;
175  int nlpcands;
176  int nfracimplvars;
177 
178  /* only call heuristic, if an optimal LP solution is at hand */
180  return SCIP_OKAY;
181 
182  /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
183  if( SCIPisGE(scip, SCIPgetLPObjval(scip), SCIPgetCutoffbound(scip)) )
184  return SCIP_OKAY;
185 
186  /* get fractional variables, that should be integral */
187  SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, NULL, &nlpcands, NULL, &nfracimplvars) );
188 
189  /* only call heuristic, if LP solution is fractional; except we are called during pricing, in this case we
190  * want to detect a (mixed) integer (LP) solution which is primal feasible
191  */
192  if ( nlpcands == 0 && heurtiming != SCIP_HEURTIMING_DURINGPRICINGLOOP )
193  return SCIP_OKAY;
194 
195  /* don't call heuristic, if there are more fractional variables than roundable ones. We do not consider
196  * fractional implicit integer variables here, because simple rounding may adjust those separately,
197  * even if they aren't roundable
198  */
199  if ( nlpcands > heurdata->nroundablevars )
200  return SCIP_OKAY;
201 
202  /* get the working solution from heuristic's local data */
203  sol = heurdata->sol;
204  assert( sol != NULL );
205 
206  /* copy the current LP solution to the working solution */
207  SCIP_CALL( SCIPlinkLPSol(scip, sol) );
208 
209  /* don't call heuristic, if we have already processed the current LP solution */
210  nlps = SCIPgetNLPs(scip);
211  if( nlps == heurdata->lastlp )
212  return SCIP_OKAY;
213  heurdata->lastlp = nlps;
214 
215  /* perform simple rounding */
216  SCIPdebugMsg(scip, "executing simple LP-rounding heuristic, fractionals: %d + %d\n", nlpcands, nfracimplvars);
217  SCIP_CALL( performSimpleRounding(scip, sol, lpcands, lpcandssol, nlpcands + nfracimplvars, result) );
218 
219  return SCIP_OKAY;
220 }
221 
222 /** perform relaxation solution rounding */
223 static
225  SCIP* scip, /**< SCIP main data structure */
226  SCIP_HEURDATA* heurdata, /**< heuristic data */
227  SCIP_RESULT* result /**< pointer to store the result of the heuristic call */
228  )
229 {
230  SCIP_SOL* sol;
231  SCIP_VAR** vars;
232  SCIP_VAR** relaxcands;
233  SCIP_Real* relaxcandssol;
234  int nrelaxcands = 0;
235  int nbinvars;
236  int nintvars;
237  int nimplvars;
238  int ndiscretevars;
239  int v;
240 
241  /* do not call heuristic if no relaxation solution is available */
242  if ( ! SCIPisRelaxSolValid(scip) )
243  return SCIP_OKAY;
244 
245  /* get variables */
246  SCIP_CALL( SCIPgetVarsData(scip, &vars, NULL, &nbinvars, &nintvars, &nimplvars, NULL) );
247  ndiscretevars = nbinvars + nintvars + nimplvars; /* consider binary, integral, and implicit integer variables */
248 
249  /* get storage */
250  SCIP_CALL( SCIPallocBufferArray(scip, &relaxcands, ndiscretevars) );
251  SCIP_CALL( SCIPallocBufferArray(scip, &relaxcandssol, ndiscretevars) );
252 
253  /* get fractional variables, that should be integral */
254  for (v = 0; v < nbinvars + nintvars; ++v)
255  {
256  SCIP_Real val;
257 
258  val = SCIPgetRelaxSolVal(scip, vars[v]);
259  if ( ! SCIPisFeasIntegral(scip, val) )
260  {
261  relaxcands[nrelaxcands] = vars[v];
262  relaxcandssol[nrelaxcands++] = val;
263  }
264  }
265 
266  /* don't call heuristic, if there are more fractional variables than roundable ones. We explicitly
267  * do not consider implicit integer variables with fractional relaxation solution here
268  * because they may be feasibly adjusted, although they are not roundable
269  */
270  if ( nrelaxcands > heurdata->nroundablevars )
271  {
272  SCIPfreeBufferArray(scip, &relaxcands);
273  SCIPfreeBufferArray(scip, &relaxcandssol);
274  return SCIP_OKAY;
275  }
276 
277  /* collect implicit integer variables with fractional solution value */
278  for( v = nbinvars + nintvars; v < ndiscretevars; ++v )
279  {
280  SCIP_Real val;
281 
282  val = SCIPgetRelaxSolVal(scip, vars[v]);
283  if ( ! SCIPisFeasIntegral(scip, val) )
284  {
285  relaxcands[nrelaxcands] = vars[v];
286  relaxcandssol[nrelaxcands++] = val;
287  }
288  }
289  /* get the working solution from heuristic's local data */
290  sol = heurdata->sol;
291  assert( sol != NULL );
292 
293  /* copy the current relaxation solution to the working solution */
294  SCIP_CALL( SCIPlinkRelaxSol(scip, sol) );
295 
296  /* perform simple rounding */
297  SCIPdebugMsg(scip, "executing simple rounding heuristic on relaxation solution: %d fractionals\n", nrelaxcands);
298  SCIP_CALL( performSimpleRounding(scip, sol, relaxcands, relaxcandssol, nrelaxcands, result) );
299 
300  /* free storage */
301  SCIPfreeBufferArray(scip, &relaxcands);
302  SCIPfreeBufferArray(scip, &relaxcandssol);
303 
304  return SCIP_OKAY;
305 }
306 
307 
308 /*
309  * Callback methods
310  */
311 
312 /** copy method for primal heuristic plugins (called when SCIP copies plugins) */
313 static
314 SCIP_DECL_HEURCOPY(heurCopySimplerounding)
315 { /*lint --e{715}*/
316  assert(scip != NULL);
317  assert(heur != NULL);
318  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
319 
320  /* call inclusion method of primal heuristic */
322 
323  return SCIP_OKAY;
324 }
325 
326 /** destructor of primal heuristic to free user data (called when SCIP is exiting) */
327 static
328 SCIP_DECL_HEURFREE(heurFreeSimplerounding) /*lint --e{715}*/
329 { /*lint --e{715}*/
330  SCIP_HEURDATA* heurdata;
331 
332  assert(heur != NULL);
333  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
334  assert(scip != NULL);
335 
336  /* free heuristic data */
337  heurdata = SCIPheurGetData(heur);
338  assert(heurdata != NULL);
339  SCIPfreeBlockMemory(scip, &heurdata);
340  SCIPheurSetData(heur, NULL);
341 
342  return SCIP_OKAY;
343 }
344 
345 
346 /** initialization method of primal heuristic (called after problem was transformed) */
347 static
348 SCIP_DECL_HEURINIT(heurInitSimplerounding) /*lint --e{715}*/
349 { /*lint --e{715}*/
350  SCIP_HEURDATA* heurdata;
351 
352  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
353  heurdata = SCIPheurGetData(heur);
354  assert(heurdata != NULL);
355 
356  /* create heuristic data */
357  SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
358  heurdata->lastlp = -1;
359  heurdata->nroundablevars = -1;
360 
361  return SCIP_OKAY;
362 }
363 
364 
365 /** deinitialization method of primal heuristic (called before transformed problem is freed) */
366 static
367 SCIP_DECL_HEUREXIT(heurExitSimplerounding) /*lint --e{715}*/
368 { /*lint --e{715}*/
369  SCIP_HEURDATA* heurdata;
370 
371  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
372 
373  /* free heuristic data */
374  heurdata = SCIPheurGetData(heur);
375  assert(heurdata != NULL);
376  SCIP_CALL( SCIPfreeSol(scip, &heurdata->sol) );
377 
378  return SCIP_OKAY;
379 }
380 
381 
382 /** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
383 static
384 SCIP_DECL_HEURINITSOL(heurInitsolSimplerounding)
385 {
386  SCIP_HEURDATA* heurdata;
387 
388  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
389 
390  heurdata = SCIPheurGetData(heur);
391  assert(heurdata != NULL);
392  heurdata->lastlp = -1;
393 
394  /* change the heuristic's timingmask, if it should be called only once per node */
395  if( heurdata->oncepernode )
397 
398  return SCIP_OKAY;
399 }
400 
401 
402 /** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
403 static
404 SCIP_DECL_HEUREXITSOL(heurExitsolSimplerounding)
405 {
406  /* reset the timing mask to its default value */
408 
409  return SCIP_OKAY;
410 }
411 
412 
413 /** execution method of primal heuristic */
414 static
415 SCIP_DECL_HEUREXEC(heurExecSimplerounding) /*lint --e{715}*/
416 { /*lint --e{715}*/
417  SCIP_HEURDATA* heurdata;
418 
419  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
420  assert(result != NULL);
421  assert(SCIPhasCurrentNodeLP(scip));
422 
423  *result = SCIP_DIDNOTRUN;
424 
425  /* only call heuristic, if an optimal LP solution is at hand or if relaxation solution is available */
427  return SCIP_OKAY;
428 
429  /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
431  return SCIP_OKAY;
432 
433  /* get heuristic data */
434  heurdata = SCIPheurGetData(heur);
435  assert(heurdata != NULL);
436 
437  /* don't call heuristic, if we have already processed the current LP solution but no relaxation solution is available */
438  if ( SCIPgetNLPs(scip) == heurdata->lastlp && ! SCIPisRelaxSolValid(scip) )
439  return SCIP_OKAY;
440 
441  /* on our first call or after each pricing round, calculate the number of roundable variables */
442  if( heurdata->nroundablevars == -1 || heurtiming == SCIP_HEURTIMING_DURINGPRICINGLOOP )
443  {
444  SCIP_VAR** vars;
445  int nbinintvars;
446  int nroundablevars;
447  int i;
448 
449  vars = SCIPgetVars(scip);
450  nbinintvars = SCIPgetNBinVars(scip) + SCIPgetNIntVars(scip);
451  nroundablevars = 0;
452  for( i = 0; i < nbinintvars; ++i )
453  {
454  if( SCIPvarMayRoundDown(vars[i]) || SCIPvarMayRoundUp(vars[i]) )
455  nroundablevars++;
456  }
457  heurdata->nroundablevars = nroundablevars;
458  }
459 
460  /* don't call heuristic if there are no roundable variables; except we are called during pricing, in this case we
461  * want to detect a (mixed) integer (LP) solution which is primal feasible */
462  if( heurdata->nroundablevars == 0 && heurtiming != SCIP_HEURTIMING_DURINGPRICINGLOOP )
463  return SCIP_OKAY;
464 
465  *result = SCIP_DIDNOTFIND;
466 
467  /* try to round LP solution */
468  SCIP_CALL( performLPSimpleRounding(scip, heurdata, heurtiming, result) );
469 
470  /* try to round relaxation solution */
471  SCIP_CALL( performRelaxSimpleRounding(scip, heurdata, result) );
472 
473  return SCIP_OKAY;
474 }
475 
476 /*
477  * heuristic specific interface methods
478  */
479 
480 /** creates the simple rounding heuristic and includes it in SCIP */
482  SCIP* scip /**< SCIP data structure */
483  )
484 {
485  SCIP_HEURDATA* heurdata;
486  SCIP_HEUR* heur;
487 
488  /* create heuristic data */
489  SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
490 
491  /* include primal heuristic */
492  SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
494  HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecSimplerounding, heurdata) );
495  assert(heur != NULL);
496 
497  /* set non-NULL pointers to callback methods */
498  SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopySimplerounding) );
499  SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitSimplerounding) );
500  SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitSimplerounding) );
501  SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolSimplerounding) );
502  SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolSimplerounding) );
503  SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeSimplerounding) );
504 
505  SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/oncepernode",
506  "should the heuristic only be called once per node?",
507  &heurdata->oncepernode, TRUE, DEFAULT_ONCEPERNODE, NULL, NULL) );
508 
509  return SCIP_OKAY;
510 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
Definition: scip.c:8209
#define HEUR_FREQOFS
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
Definition: scip.c:36995
int SCIPgetNIntVars(SCIP *scip)
Definition: scip.c:11896
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:38570
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:43447
static SCIP_RETCODE performSimpleRounding(SCIP *scip, SCIP_SOL *sol, SCIP_VAR **cands, SCIP_Real *candssol, int ncands, SCIP_RESULT *result)
static SCIP_DECL_HEURCOPY(heurCopySimplerounding)
SCIP_RETCODE SCIPadjustImplicitSolVals(SCIP *scip, SCIP_SOL *sol, SCIP_Bool uselprows)
Definition: scip.c:39276
unsigned int SCIP_HEURTIMING
Definition: type_timing.h:97
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
Definition: scip.c:8177
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:47009
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip.c:11680
#define FALSE
Definition: def.h:64
static SCIP_RETCODE performLPSimpleRounding(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_HEURTIMING heurtiming, SCIP_RESULT *result)
#define HEUR_DISPCHAR
#define TRUE
Definition: def.h:63
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:51
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip.h:22602
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.c:8084
static SCIP_DECL_HEURFREE(heurFreeSimplerounding)
#define SCIP_HEURTIMING_DURINGPRICINGLOOP
Definition: type_timing.h:85
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:22632
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1119
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip.h:22585
#define SCIPdebugMsg
Definition: scip.h:455
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
Definition: scip.c:47429
SCIP_RETCODE SCIPincludeHeurSimplerounding(SCIP *scip)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:47417
static SCIP_DECL_HEUREXEC(heurExecSimplerounding)
static SCIP_DECL_HEUREXIT(heurExitSimplerounding)
SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINITSOL((*heurinitsol)))
Definition: scip.c:8193
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1198
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip.c:8145
#define SCIP_HEURTIMING_AFTERLPNODE
Definition: type_timing.h:73
#define HEUR_DESC
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16662
#define HEUR_TIMING
#define SCIP_CALL(x)
Definition: def.h:350
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip.c:29202
#define HEUR_NAME
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:22620
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition: scip.c:38765
#define SCIP_Bool
Definition: def.h:61
static SCIP_DECL_HEURINITSOL(heurInitsolSimplerounding)
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip.c:29287
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip.c:38529
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17124
static SCIP_DECL_HEUREXITSOL(heurExitsolSimplerounding)
SCIP_RETCODE SCIPtrySol(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.c:40694
#define HEUR_PRIORITY
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:11851
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip.c:29366
SCIP_Bool SCIPisRelaxSolValid(SCIP *scip)
Definition: scip.c:20046
#define DEFAULT_ONCEPERNODE
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
Definition: scip.c:8161
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip.c:11761
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16781
#define SCIP_Real
Definition: def.h:149
#define HEUR_USESSUBSCIP
void SCIPheurSetTimingmask(SCIP_HEUR *heur, SCIP_HEURTIMING timingmask)
Definition: heur.c:1238
SCIP_RETCODE SCIPlinkRelaxSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:38628
Simple and fast LP rounding heuristic.
#define SCIP_Longint
Definition: def.h:134
SCIP_Bool SCIPallColsInLP(SCIP *scip)
Definition: scip.c:29713
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:16827
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: scip.c:8129
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:47393
#define HEUR_FREQ
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1109
#define HEUR_MAXDEPTH
static SCIP_DECL_HEURINIT(heurInitSimplerounding)
SCIP_Longint SCIPgetNLPs(SCIP *scip)
Definition: scip.c:42308
SCIP_Bool SCIPvarMayRoundUp(SCIP_VAR *var)
Definition: var.c:3280
SCIP_Bool SCIPvarMayRoundDown(SCIP_VAR *var)
Definition: var.c:3272
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:4239
static SCIP_RETCODE performRelaxSimpleRounding(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_RESULT *result)
SCIP_Real SCIPgetRelaxSolVal(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:20110
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip.c:37872
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition: scip.c:39319