Scippy

SCIP

Solving Constraint Integer Programs

heur_reoptsols.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_reoptsols.c
17  * @brief reoptsols primal heuristic
18  * @author Jakob Witzig
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #include <assert.h>
24 #include <string.h>
25 
26 #include "scip/heur_reoptsols.h"
27 #include "scip/reopt.h"
28 
29 
30 #define HEUR_NAME "reoptsols"
31 #define HEUR_DESC "primal heuristic updating solutions found in a previous optimization round"
32 #define HEUR_DISPCHAR 'J'
33 #define HEUR_PRIORITY 40000
34 #define HEUR_FREQ -1
35 #define HEUR_FREQOFS 0
36 #define HEUR_MAXDEPTH 0
37 #define HEUR_TIMING SCIP_HEURTIMING_BEFOREPRESOL
38 #define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
39 
40 
41 /*
42  * Data structures
43  */
44 
45 /* TODO: fill in the necessary primal heuristic data */
46 
47 /** primal heuristic data */
48 struct SCIP_HeurData
49 {
50  int maxsols; /**< maximal number of solution to update per run */
51  int maxruns; /**< check solutions of the last k runs only */
52 
53  /* statistics */
54  int ncheckedsols; /**< number of updated solutions */
55  int nimprovingsols; /**< number of improving solutions */
56 };
57 
58 
59 /*
60  * Local methods
61  */
62 
63 #define heurInitsolReoptsols NULL
64 #define heurExitsolReoptsols NULL
65 #define heurExitReoptsols NULL
66 
67 /** creates a new solution for the original problem by copying the solution of the subproblem */
68 static
70  SCIP* scip, /**< original SCIP data structure */
71  SCIP_HEUR* heur, /**< the current heuristic */
72  SCIP_SOL* sol, /**< solution of the subproblem */
73  SCIP_Bool* success /**< used to store whether new solution was found or not */
74  )
75 {
76  SCIP_VAR** vars; /* the original problem's variables */
77  int nvars; /* the original problem's number of variables */
78  SCIP_Real* solvals; /* solution values of the subproblem */
79  SCIP_SOL* newsol; /* solution to be created for the original problem */
80 
81  assert(scip != NULL);
82 
83  /* get variables' data */
84  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
85 
86  SCIP_CALL( SCIPallocBufferArray(scip, &solvals, nvars) );
87 
88  /* copy the solution */
89  SCIP_CALL( SCIPgetSolVals(scip, sol, nvars, vars, solvals) );
90 
91  /* create new solution for the original problem */
92  SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) );
93  SCIP_CALL( SCIPsetSolVals(scip, newsol, nvars, vars, solvals) );
94 
95  /* try to add new solution to scip and free it immediately */
96  SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, TRUE, TRUE, TRUE, success) );
97 
98  SCIPfreeBufferArray(scip, &solvals);
99 
100  return SCIP_OKAY;
101 }
102 
103 /** copy method for primal heuristic plugins (called when SCIP copies plugins) */
104 static
105 SCIP_DECL_HEURCOPY(heurCopyReoptsols)
106 { /*lint --e{715}*/
107  assert(scip != NULL);
108  assert(heur != NULL);
109  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
110 
111  /* call inclusion method of primal heuristic */
113 
114  return SCIP_OKAY;
115 }
116 
117 /* free data of the heuristic */
118 static
119 SCIP_DECL_HEURFREE(heurFreeReoptsols)
120 {
121  SCIP_HEURDATA* heurdata;
122 
123  assert(scip != NULL );
124  assert(heur != NULL );
125 
126  heurdata = SCIPheurGetData(heur);
127  assert(heurdata != NULL );
128 
129  SCIPfreeMemory(scip, &heurdata);
130  SCIPheurSetData(heur, NULL);
131 
132  return SCIP_OKAY;
133 }
134 
135 
136 /* initialize the heuristic */
137 static SCIP_DECL_HEURINIT(heurInitReoptsols)
138 {
139  SCIP_HEURDATA* heurdata;
140 
141  assert(scip != NULL );
142  assert(heur != NULL );
143 
144  heurdata = SCIPheurGetData(heur);
145  assert(heurdata != NULL );
146 
147  heurdata->ncheckedsols = 0;
148  heurdata->nimprovingsols = 0;
149 
150  return SCIP_OKAY;
151 }
152 
153 /** execution method of primal heuristic */
154 static
155 SCIP_DECL_HEUREXEC(heurExecReoptsols)
156 {/*lint --e{715}*/
157  SCIP_HEURDATA* heurdata;
158 
159  SCIP_SOL** sols;
160  SCIP_Real objsimsol;
161  SCIP_Bool sepabestsol;
162  int allocmem;
163  int nchecksols;
164  int nsolsadded;
165 #ifdef SCIP_MORE_DEBUG
166  int nsolsaddedrun;
167 #endif
168  int run;
169  int max_run;
170 
171  assert(heur != NULL);
172  assert(scip != NULL);
173 
174  *result = SCIP_DIDNOTRUN;
175 
176  if( !SCIPisReoptEnabled(scip) )
177  return SCIP_OKAY;
178 
179  heurdata = SCIPheurGetData(heur);
180  assert(heurdata != NULL);
181 
182  max_run = heurdata->maxruns == -1 ? 0 : MAX(0, SCIPgetNReoptRuns(scip)-1-heurdata->maxruns); /*lint !e666*/
183  nchecksols = heurdata->maxsols == -1 ? INT_MAX : heurdata->maxsols;
184 
185  SCIP_CALL( SCIPgetRealParam(scip, "reoptimization/objsimsol", &objsimsol) );
186  SCIP_CALL( SCIPgetBoolParam(scip, "reoptimization/sepabestsol", &sepabestsol) );
187 
188  /* allocate a buffer array to store the solutions */
189  allocmem = 20;
190  SCIP_CALL( SCIPallocBufferArray(scip, &sols, allocmem) );
191 
192  nsolsadded = 0;
193 
194  for( run = SCIPgetNReoptRuns(scip); run > max_run && nchecksols > 0; run-- )
195  {
196  SCIP_Real sim;
197  int nsols;
198 
199 #ifdef SCIP_MORE_DEBUG
200  nsolsaddedrun = 0;
201 #endif
202  nsols = 0;
203 
204  if( objsimsol == -1 )
205  sim = 1;
206  else
208 
209  if( sim >= objsimsol )
210  {
211  int s;
212 
213  /* get solutions of a specific run */
214  SCIP_CALL( SCIPgetReopSolsRun(scip, run, sols, allocmem, &nsols) );
215 
216  /* check memory and reallocate */
217  if( nsols > allocmem )
218  {
219  allocmem = nsols;
220  SCIP_CALL( SCIPreallocBufferArray(scip, &sols, allocmem) );
221 
222  SCIP_CALL( SCIPgetReopSolsRun(scip, run, sols, allocmem, &nsols) );
223  }
224  assert(nsols <= allocmem);
225 
226  /* update the solutions
227  * stop, if the maximal number of solutions to be checked is reached
228  */
229  for( s = 0; s < nsols && nchecksols > 0; s++ )
230  {
231  SCIP_SOL* sol;
232  SCIP_Real objsol;
233 
234  sol = sols[s];
235 
237  objsol = SCIPgetSolTransObj(scip, sol);
238 
239  /* we do not want to add solutions with objective value +infinity.
240  * moreover, the solution should improve the current primal bound
241  */
242  if( !SCIPisInfinity(scip, objsol) && !SCIPisInfinity(scip, -objsol)
243  && SCIPisFeasLT(scip, objsol, SCIPgetCutoffbound(scip)) )
244  {
245  SCIP_Bool stored;
246  SCIP_Bool feasible;
247 
248  if( sepabestsol )
249  {
250  SCIP_CALL( SCIPcheckSolOrig(scip, sol, &feasible, FALSE, TRUE) );
251  }
252  else
253  feasible = TRUE;
254 
255  if( feasible)
256  {
257  /* create a new solution */
258  SCIP_CALL( createNewSol(scip, heur, sol, &stored) );
259 
260  if( stored )
261  {
262  nsolsadded++;
263 #ifdef SCIP_MORE_DEBUG
264  nsolsaddedrun++;
265 #endif
266  heurdata->nimprovingsols++;
267  }
268  }
269  }
270 
271  nchecksols--;
272  heurdata->ncheckedsols++;
273  }
274  }
275 #ifdef SCIP_MORE_DEBUG
276  printf(">> heuristic <%s> found %d of %d improving solutions from run %d.\n", HEUR_NAME, nsolsaddedrun, nsols, run);
277 #endif
278  }
279 
280  SCIPdebugMessage(">> heuristic <%s> found %d improving solutions.\n", HEUR_NAME, nsolsadded);
281 
282  if( nsolsadded > 0 )
283  *result = SCIP_FOUNDSOL;
284  else
285  *result = SCIP_DIDNOTFIND;
286 
287  /* reset the marks of the checked solutions */
289 
290  /* free the buffer array */
291  SCIPfreeBufferArray(scip, &sols);
292 
293  return SCIP_OKAY;
294 }
295 
296 
297 /*
298  * primal heuristic specific interface methods
299  */
300 
301 /* returns the number of checked solutions */
303  SCIP* scip
304  )
305 {
306  SCIP_HEUR* heur;
307  SCIP_HEURDATA* heurdata;
308 
309  assert(scip != NULL);
310 
311  heur = SCIPfindHeur(scip, HEUR_NAME);
312  assert(heur != NULL);
313 
314  heurdata = SCIPheurGetData(heur);
315  assert(heurdata != NULL);
316 
317  return heurdata->ncheckedsols;
318 }
319 
320 /* returns the number of found improving solutions */
322  SCIP* scip
323  )
324 {
325  SCIP_HEUR* heur;
326  SCIP_HEURDATA* heurdata;
327 
328  assert(scip != NULL);
329 
330  heur = SCIPfindHeur(scip, HEUR_NAME);
331  assert(heur != NULL);
332 
333  heurdata = SCIPheurGetData(heur);
334  assert(heurdata != NULL);
335 
336  return heurdata->nimprovingsols;
337 }
338 
339 /** creates the reoptsols primal heuristic and includes it in SCIP */
341  SCIP* scip /**< SCIP data structure */
342  )
343 {
344  SCIP_HEURDATA* heurdata;
345  SCIP_HEUR* heur;
346 
347  /* create reoptsols primal heuristic data */
348  SCIP_CALL( SCIPallocMemory(scip, &heurdata) );
349 
350  /* include primal heuristic */
351  SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
353  HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecReoptsols, heurdata) );
354 
355  assert(heur != NULL);
356 
357  /* set non fundamental callbacks via setter functions */
358  SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyReoptsols) );
359  SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeReoptsols) );
360  SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitReoptsols) );
364 
365  /* parameters */
366  SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxsols", "maximal number solutions which should be checked. (-1: all)",
367  &heurdata->maxsols, TRUE, 1000, -1, INT_MAX, NULL, NULL) );
368  SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxruns", "check solutions of the last k runs. (-1: all)",
369  &heurdata->maxruns, TRUE, -1, -1, INT_MAX, NULL, NULL) );
370 
371  return SCIP_OKAY;
372 }
SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINITSOL((*heurinitsol)))
Definition: scip.c:7361
#define SCIPallocMemory(scip, ptr)
Definition: scip.h:20526
int SCIPreoptsolsGetNImprovingsols(SCIP *scip)
int SCIPreoptsolsGetNCheckedsols(SCIP *scip)
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:20589
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
Definition: scip.c:41648
#define heurExitReoptsols
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
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:41920
#define HEUR_PRIORITY
#define NULL
Definition: lpi_spx.cpp:130
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
SCIP_HEUR * SCIPfindHeur(SCIP *scip, const char *name)
Definition: scip.c:7393
#define FALSE
Definition: def.h:56
SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:35113
SCIP_RETCODE SCIPrecomputeSolObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip.c:35144
#define TRUE
Definition: def.h:55
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
#define SCIP_CALL(x)
Definition: def.h:266
SCIP_RETCODE SCIPtrySolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip.c:36299
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:51
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:38561
#define SCIPdebugMessage
Definition: pub_message.h:77
static SCIP_DECL_HEURINIT(heurInitReoptsols)
static SCIP_DECL_HEUREXEC(heurExecReoptsols)
SCIP_RETCODE SCIPcheckSolOrig(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *feasible, SCIP_Bool printreason, SCIP_Bool completely)
Definition: scip.c:36470
#define HEUR_FREQ
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:3573
#define SCIPfreeMemory(scip, ptr)
Definition: scip.h:20542
#define HEUR_DISPCHAR
static SCIP_RETCODE createNewSol(SCIP *scip, SCIP_HEUR *heur, SCIP_SOL *sol, SCIP_Bool *success)
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip.c:34002
SCIP_RETCODE SCIPgetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip.c:35020
#define HEUR_USESSUBSCIP
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1068
int SCIPgetNReoptRuns(SCIP *scip)
Definition: scip.c:37345
data structures and methods for collecting reoptimization information
#define SCIP_Bool
Definition: def.h:53
#define MAX(x, y)
Definition: tclique_def.h:75
SCIP_RETCODE SCIPincludeHeurReoptsols(SCIP *scip)
static SCIP_DECL_HEURCOPY(heurCopyReoptsols)
SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
Definition: scip.c:7377
reoptsols primal heuristic
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
Definition: scip.c:7345
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
Definition: scip.c:7329
#define HEUR_NAME
#define HEUR_TIMING
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:20585
#define HEUR_MAXDEPTH
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip.c:7313
#define heurInitsolReoptsols
#define HEUR_FREQOFS
#define SCIP_Real
Definition: def.h:127
SCIP_Real SCIPgetReoptSimilarity(SCIP *scip, int run1, int run2)
Definition: scip.c:15560
SCIP_RETCODE SCIPsetSolVals(SCIP *scip, SCIP_SOL *sol, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip.c:34885
static SCIP_DECL_HEURFREE(heurFreeReoptsols)
#define heurExitsolReoptsols
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
SCIP_RETCODE SCIPgetReopSolsRun(SCIP *scip, int run, SCIP_SOL **sols, int solssize, int *nsols)
Definition: scip.c:15491
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition: scip.c:3797
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip.c:3740
void SCIPresetReoptSolMarks(SCIP *scip)
Definition: scip.c:15517
SCIP_Bool SCIPisReoptEnabled(SCIP *scip)
Definition: scip.c:15481
#define HEUR_DESC