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-2016 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file 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 
71  /* round all roundable fractional columns in the corresponding direction as long as no unroundable column was found */
72  for (c = 0; c < ncands; ++c)
73  {
74  SCIP_VAR* var;
75  SCIP_Real oldsolval;
76  SCIP_Real newsolval;
77  SCIP_Bool mayrounddown;
78  SCIP_Bool mayroundup;
79 
80  oldsolval = candssol[c];
81  assert( ! SCIPisFeasIntegral(scip, oldsolval) );
82  var = cands[c];
83  assert( SCIPvarGetStatus(var) == SCIP_VARSTATUS_COLUMN );
84  mayrounddown = SCIPvarMayRoundDown(var);
85  mayroundup = SCIPvarMayRoundUp(var);
86  SCIPdebugMessage("simple rounding heuristic: var <%s>, val=%g, rounddown=%u, roundup=%u\n",
87  SCIPvarGetName(var), oldsolval, mayrounddown, mayroundup);
88 
89  /* choose rounding direction */
90  if ( mayrounddown && mayroundup )
91  {
92  /* we can round in both directions: round in objective function direction */
93  if ( SCIPvarGetObj(var) >= 0.0 )
94  newsolval = SCIPfeasFloor(scip, oldsolval);
95  else
96  newsolval = SCIPfeasCeil(scip, oldsolval);
97  }
98  else if ( mayrounddown )
99  newsolval = SCIPfeasFloor(scip, oldsolval);
100  else if ( mayroundup )
101  newsolval = SCIPfeasCeil(scip, oldsolval);
102  else
103  break;
104 
105  /* store new solution value */
106  SCIP_CALL( SCIPsetSolVal(scip, sol, var, newsolval) );
107  }
108 
109  /* check, if rounding was successful */
110  if( c == ncands )
111  {
112  SCIP_Bool stored;
113 
114  SCIP_CALL ( SCIPadjustImplicitSolVals(scip, sol, TRUE) );
115 
116  if( SCIPallColsInLP(scip) )
117  {
118  /* check solution for feasibility, and add it to solution store if possible
119  * neither integrality nor feasibility of LP rows has to be checked, because all fractional
120  * variables were already moved in feasible direction to the next integer
121  */
122  SCIP_CALL( SCIPtrySol(scip, sol, FALSE, FALSE, FALSE, FALSE, &stored) );
123  }
124  else
125  {
126  /* if there are variables which are not present in the LP, e.g., for
127  * column generation, we need to check their bounds
128  */
129  SCIP_CALL( SCIPtrySol(scip, sol, FALSE, TRUE, FALSE, FALSE, &stored) );
130  }
131 
132  if( stored )
133  {
134 #ifdef SCIP_DEBUG
135  SCIPdebugMessage("found feasible rounded solution:\n");
136  SCIP_CALL( SCIPprintSol(scip, sol, NULL, FALSE) );
137 #endif
138  *result = SCIP_FOUNDSOL;
139  }
140  }
141  return SCIP_OKAY;
142 }
143 
144 /** perform LP-rounding */
145 static
147  SCIP* scip, /**< SCIP main data structure */
148  SCIP_HEURDATA* heurdata, /**< heuristic data */
149  SCIP_HEURTIMING heurtiming, /**< heuristic timing mask */
150  SCIP_RESULT* result /**< pointer to store the result of the heuristic call */
151  )
152 {
153  SCIP_SOL* sol;
154  SCIP_VAR** lpcands;
155  SCIP_Real* lpcandssol;
156  SCIP_Longint nlps;
157  int nlpcands;
158 
159  /* only call heuristic, if an optimal LP solution is at hand */
161  return SCIP_OKAY;
162 
163  /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
164  if( SCIPisGE(scip, SCIPgetLPObjval(scip), SCIPgetCutoffbound(scip)) )
165  return SCIP_OKAY;
166 
167  /* get fractional variables, that should be integral */
168  /* todo polish fractional implicit integer variables separately before trying the solution */
169  SCIP_CALL( SCIPgetLPBranchCands(scip, &lpcands, &lpcandssol, NULL, &nlpcands, NULL, NULL) );
170 
171  /* only call heuristic, if LP solution is fractional; except we are called during pricing, in this case we
172  * want to detect a (mixed) integer (LP) solution which is primal feasible */
173  if ( nlpcands == 0 && heurtiming != SCIP_HEURTIMING_DURINGPRICINGLOOP )
174  return SCIP_OKAY;
175 
176  /* don't call heuristic, if there are more fractional variables than roundable ones */
177  if ( nlpcands > heurdata->nroundablevars )
178  return SCIP_OKAY;
179 
180  /* get the working solution from heuristic's local data */
181  sol = heurdata->sol;
182  assert( sol != NULL );
183 
184  /* copy the current LP solution to the working solution */
185  SCIP_CALL( SCIPlinkLPSol(scip, sol) );
186 
187  /* don't call heuristic, if we have already processed the current LP solution */
188  nlps = SCIPgetNLPs(scip);
189  if( nlps == heurdata->lastlp )
190  return SCIP_OKAY;
191  heurdata->lastlp = nlps;
192 
193  /* perform simple rounding */
194  SCIPdebugMessage("executing simple LP-rounding heuristic: %d fractionals\n", nlpcands);
195  SCIP_CALL( performSimpleRounding(scip, sol, lpcands, lpcandssol, nlpcands, result) );
196 
197  return SCIP_OKAY;
198 }
199 
200 /** perform relaxation solution rounding */
201 static
203  SCIP* scip, /**< SCIP main data structure */
204  SCIP_HEURDATA* heurdata, /**< heuristic data */
205  SCIP_RESULT* result /**< pointer to store the result of the heuristic call */
206  )
207 {
208  SCIP_SOL* sol;
209  SCIP_VAR** vars;
210  SCIP_VAR** relaxcands;
211  SCIP_Real* relaxcandssol;
212  int nrelaxcands = 0;
213  int nbinvars;
214  int nintvars;
215  int nbinintvars;
216  int v;
217 
218  /* do not call heuristic if no relaxation solution is available */
219  if ( ! SCIPisRelaxSolValid(scip) )
220  return SCIP_OKAY;
221 
222  /* get variables */
223  SCIP_CALL( SCIPgetVarsData(scip, &vars, NULL, &nbinvars, &nintvars, NULL, NULL) );
224  nbinintvars = nbinvars + nintvars; /* consider binary and integral variables (don't have to care for implicit ints) */
225 
226  /* get storage */
227  SCIP_CALL( SCIPallocBufferArray(scip, &relaxcands, nbinintvars) );
228  SCIP_CALL( SCIPallocBufferArray(scip, &relaxcandssol, nbinintvars) );
229 
230  /* get fractional variables, that should be integral */
231  for (v = 0; v < nbinintvars; ++v)
232  {
233  SCIP_Real val;
234 
235  val = SCIPgetRelaxSolVal(scip, vars[v]);
236  if ( ! SCIPisFeasIntegral(scip, val) )
237  {
238  relaxcands[nrelaxcands] = vars[v];
239  relaxcandssol[nrelaxcands++] = val;
240  }
241  }
242 
243  /* don't call heuristic, if there are more fractional variables than roundable ones */
244  if ( nrelaxcands > heurdata->nroundablevars )
245  {
246  SCIPfreeBufferArray(scip, &relaxcands);
247  SCIPfreeBufferArray(scip, &relaxcandssol);
248  return SCIP_OKAY;
249  }
250 
251  /* get the working solution from heuristic's local data */
252  sol = heurdata->sol;
253  assert( sol != NULL );
254 
255  /* copy the current relaxation solution to the working solution */
256  SCIP_CALL( SCIPlinkRelaxSol(scip, sol) );
257 
258  /* perform simple rounding */
259  SCIPdebugMessage("executing simple rounding heuristic on relaxation solution: %d fractionals\n", nrelaxcands);
260  SCIP_CALL( performSimpleRounding(scip, sol, relaxcands, relaxcandssol, nrelaxcands, result) );
261 
262  /* free storage */
263  SCIPfreeBufferArray(scip, &relaxcands);
264  SCIPfreeBufferArray(scip, &relaxcandssol);
265 
266  return SCIP_OKAY;
267 }
268 
269 
270 /*
271  * Callback methods
272  */
273 
274 /** copy method for primal heuristic plugins (called when SCIP copies plugins) */
275 static
276 SCIP_DECL_HEURCOPY(heurCopySimplerounding)
277 { /*lint --e{715}*/
278  assert(scip != NULL);
279  assert(heur != NULL);
280  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
281 
282  /* call inclusion method of primal heuristic */
284 
285  return SCIP_OKAY;
286 }
287 
288 /** destructor of primal heuristic to free user data (called when SCIP is exiting) */
289 static
290 SCIP_DECL_HEURFREE(heurFreeSimplerounding) /*lint --e{715}*/
291 { /*lint --e{715}*/
292  SCIP_HEURDATA* heurdata;
293 
294  assert(heur != NULL);
295  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
296  assert(scip != NULL);
297 
298  /* free heuristic data */
299  heurdata = SCIPheurGetData(heur);
300  assert(heurdata != NULL);
301  SCIPfreeMemory(scip, &heurdata);
302  SCIPheurSetData(heur, NULL);
303 
304  return SCIP_OKAY;
305 }
306 
307 
308 /** initialization method of primal heuristic (called after problem was transformed) */
309 static
310 SCIP_DECL_HEURINIT(heurInitSimplerounding) /*lint --e{715}*/
311 { /*lint --e{715}*/
312  SCIP_HEURDATA* heurdata;
313 
314  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
315  heurdata = SCIPheurGetData(heur);
316  assert(heurdata != NULL);
317 
318  /* create heuristic data */
319  SCIP_CALL( SCIPcreateSol(scip, &heurdata->sol, heur) );
320  heurdata->lastlp = -1;
321  heurdata->nroundablevars = -1;
322 
323  return SCIP_OKAY;
324 }
325 
326 
327 /** deinitialization method of primal heuristic (called before transformed problem is freed) */
328 static
329 SCIP_DECL_HEUREXIT(heurExitSimplerounding) /*lint --e{715}*/
330 { /*lint --e{715}*/
331  SCIP_HEURDATA* heurdata;
332 
333  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
334 
335  /* free heuristic data */
336  heurdata = SCIPheurGetData(heur);
337  assert(heurdata != NULL);
338  SCIP_CALL( SCIPfreeSol(scip, &heurdata->sol) );
339 
340  return SCIP_OKAY;
341 }
342 
343 
344 /** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
345 static
346 SCIP_DECL_HEURINITSOL(heurInitsolSimplerounding)
347 {
348  SCIP_HEURDATA* heurdata;
349 
350  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
351 
352  heurdata = SCIPheurGetData(heur);
353  assert(heurdata != NULL);
354  heurdata->lastlp = -1;
355 
356  /* change the heuristic's timingmask, if it should be called only once per node */
357  if( heurdata->oncepernode )
359 
360  return SCIP_OKAY;
361 }
362 
363 
364 /** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
365 static
366 SCIP_DECL_HEUREXITSOL(heurExitsolSimplerounding)
367 {
368  /* reset the timing mask to its default value */
370 
371  return SCIP_OKAY;
372 }
373 
374 
375 /** execution method of primal heuristic */
376 static
377 SCIP_DECL_HEUREXEC(heurExecSimplerounding) /*lint --e{715}*/
378 { /*lint --e{715}*/
379  SCIP_HEURDATA* heurdata;
380 
381  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
382  assert(result != NULL);
383  assert(SCIPhasCurrentNodeLP(scip));
384 
385  *result = SCIP_DIDNOTRUN;
386 
387  /* only call heuristic, if an optimal LP solution is at hand or if relaxation solution is available */
389  return SCIP_OKAY;
390 
391  /* only call heuristic, if the LP objective value is smaller than the cutoff bound */
393  return SCIP_OKAY;
394 
395  /* get heuristic data */
396  heurdata = SCIPheurGetData(heur);
397  assert(heurdata != NULL);
398 
399  /* don't call heuristic, if we have already processed the current LP solution but no relaxation solution is available */
400  if ( SCIPgetNLPs(scip) == heurdata->lastlp && ! SCIPisRelaxSolValid(scip) )
401  return SCIP_OKAY;
402 
403  /* on our first call or after each pricing round, calculate the number of roundable variables */
404  if( heurdata->nroundablevars == -1 || heurtiming == SCIP_HEURTIMING_DURINGPRICINGLOOP )
405  {
406  SCIP_VAR** vars;
407  int nbinintvars;
408  int nroundablevars;
409  int i;
410 
411  vars = SCIPgetVars(scip);
412  nbinintvars = SCIPgetNBinVars(scip) + SCIPgetNIntVars(scip);
413  nroundablevars = 0;
414  for( i = 0; i < nbinintvars; ++i )
415  {
416  if( SCIPvarMayRoundDown(vars[i]) || SCIPvarMayRoundUp(vars[i]) )
417  nroundablevars++;
418  }
419  heurdata->nroundablevars = nroundablevars;
420  }
421 
422  /* don't call heuristic if there are no roundable variables; except we are called during pricing, in this case we
423  * want to detect a (mixed) integer (LP) solution which is primal feasible */
424  if( heurdata->nroundablevars == 0 && heurtiming != SCIP_HEURTIMING_DURINGPRICINGLOOP )
425  return SCIP_OKAY;
426 
427  *result = SCIP_DIDNOTFIND;
428 
429  /* try to round LP solution */
430  SCIP_CALL( performLPSimpleRounding(scip, heurdata, heurtiming, result) );
431 
432  /* try to round relaxation solution */
433  SCIP_CALL( performRelaxSimpleRounding(scip, heurdata, result) );
434 
435  return SCIP_OKAY;
436 }
437 
438 /*
439  * heuristic specific interface methods
440  */
441 
442 /** creates the simple rounding heuristic and includes it in SCIP */
444  SCIP* scip /**< SCIP data structure */
445  )
446 {
447  SCIP_HEURDATA* heurdata;
448  SCIP_HEUR* heur;
449 
450  /* create heuristic data */
451  SCIP_CALL( SCIPallocMemory(scip, &heurdata) );
452 
453  /* include primal heuristic */
454  SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
456  HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecSimplerounding, heurdata) );
457  assert(heur != NULL);
458 
459  /* set non-NULL pointers to callback methods */
460  SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopySimplerounding) );
461  SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitSimplerounding) );
462  SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitSimplerounding) );
463  SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolSimplerounding) );
464  SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolSimplerounding) );
465  SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeSimplerounding) );
466 
467  SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/oncepernode",
468  "should the heuristic only be called once per node?",
469  &heurdata->oncepernode, TRUE, DEFAULT_ONCEPERNODE, NULL, NULL) );
470 
471  return SCIP_OKAY;
472 }
SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINITSOL((*heurinitsol)))
Definition: scip.c:7361
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:51
#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:33125
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:20526
SCIP_RETCODE SCIPlinkRelaxSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:34706
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16443
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1147
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: scip.c:7297
static SCIP_RETCODE performSimpleRounding(SCIP *scip, SCIP_SOL *sol, SCIP_VAR **cands, SCIP_Real *candssol, int ncands, SCIP_RESULT *result)
SCIP_Bool SCIPvarMayRoundDown(SCIP_VAR *var)
Definition: var.c:3259
static SCIP_DECL_HEURCOPY(heurCopySimplerounding)
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip.c:10653
unsigned int SCIP_HEURTIMING
Definition: type_timing.h:95
#define NULL
Definition: lpi_spx.cpp:130
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:42032
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition: scip.c:34843
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:7252
#define FALSE
Definition: def.h:56
static SCIP_RETCODE performLPSimpleRounding(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_HEURTIMING heurtiming, SCIP_RESULT *result)
#define HEUR_DISPCHAR
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:10743
#define TRUE
Definition: def.h:55
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
#define SCIP_CALL(x)
Definition: def.h:266
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:51
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:42008
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:38561
static SCIP_DECL_HEURFREE(heurFreeSimplerounding)
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip.c:26439
#define SCIPdebugMessage
Definition: pub_message.h:77
#define SCIP_HEURTIMING_DURINGPRICINGLOOP
Definition: type_timing.h:83
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:16905
SCIP_RETCODE SCIPadjustImplicitSolVals(SCIP *scip, SCIP_SOL *sol, SCIP_Bool uselprows)
Definition: scip.c:35354
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition: scip.c:26482
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
Definition: scip.c:42044
SCIP_Bool SCIPallColsInLP(SCIP *scip)
Definition: scip.c:26829
static SCIP_DECL_HEUREXEC(heurExecSimplerounding)
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:3547
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16562
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:20542
static SCIP_DECL_HEUREXIT(heurExitSimplerounding)
#define SCIP_HEURTIMING_AFTERLPNODE
Definition: type_timing.h:71
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip.c:34002
#define HEUR_DESC
#define HEUR_TIMING
void SCIPheurSetTimingmask(SCIP_HEUR *heur, SCIP_HEURTIMING timingmask)
Definition: heur.c:1187
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip.c:26354
SCIP_Longint SCIPgetNLPs(SCIP *scip)
Definition: scip.c:37435
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1068
#define HEUR_NAME
#define SCIP_Bool
Definition: def.h:53
static SCIP_DECL_HEURINITSOL(heurInitsolSimplerounding)
SCIP_RETCODE SCIPincludeHeurSimplerounding(SCIP *scip)
static SCIP_DECL_HEUREXITSOL(heurExitsolSimplerounding)
SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
Definition: scip.c:7377
SCIP_Real SCIPgetRelaxSolVal(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:17904
#define HEUR_PRIORITY
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:34648
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
Definition: scip.c:7345
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41624
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
Definition: scip.c:7329
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20585
int SCIPgetNIntVars(SCIP *scip)
Definition: scip.c:10788
#define DEFAULT_ONCEPERNODE
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip.c:7313
#define SCIP_Real
Definition: def.h:127
#define HEUR_USESSUBSCIP
SCIP_Bool SCIPvarMayRoundUp(SCIP_VAR *var)
Definition: var.c:3267
Simple and fast LP rounding heuristic.
#define SCIP_Longint
Definition: def.h:112
SCIP_Bool SCIPisRelaxSolValid(SCIP *scip)
Definition: scip.c:17841
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1058
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip.c:10572
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:20597
#define HEUR_FREQ
#define HEUR_MAXDEPTH
static SCIP_DECL_HEURINIT(heurInitSimplerounding)
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:36217
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition: scip.c:35397
static SCIP_RETCODE performRelaxSimpleRounding(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_RESULT *result)
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip.c:34607