Scippy

SCIP

Solving Constraint Integer Programs

heur_mpec.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_mpec.c
17  * @ingroup DEFPLUGINS_HEUR
18  * @brief mpec primal heuristic
19  * @author Felipe Serrano
20  * @author Benjamin Mueller
21  */
22 
23 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
24 
25 #include "blockmemshell/memory.h"
26 #include "scip/pub_expr.h"
27 #include "scip/expr_var.h"
28 #include "scip/expr_sum.h"
29 #include "scip/expr_pow.h"
30 #include "scip/heur_mpec.h"
31 #include "scip/heur_subnlp.h"
32 #include "scip/pub_cons.h"
33 #include "scip/pub_heur.h"
34 #include "scip/pub_message.h"
35 #include "scip/pub_misc.h"
36 #include "scip/pub_nlp.h"
37 #include "scip/pub_var.h"
38 #include "scip/scip_cons.h"
39 #include "scip/scip_general.h"
40 #include "scip/scip_heur.h"
41 #include "scip/scip_mem.h"
42 #include "scip/scip_message.h"
43 #include "scip/scip_nlp.h"
44 #include "scip/scip_nlpi.h"
45 #include "scip/scip_numerics.h"
46 #include "scip/scip_param.h"
47 #include "scip/scip_prob.h"
48 #include "scip/scip_sol.h"
49 #include "scip/scip_solvingstats.h"
50 #include "scip/scip_timing.h"
51 #include <string.h>
52 
53 
54 #define HEUR_NAME "mpec"
55 #define HEUR_DESC "regularization heuristic for convex and nonconvex MINLPs"
56 #define HEUR_DISPCHAR SCIP_HEURDISPCHAR_DIVING
57 #define HEUR_PRIORITY -2050000
58 #define HEUR_FREQ 50
59 #define HEUR_FREQOFS 0
60 #define HEUR_MAXDEPTH -1
61 #define HEUR_TIMING SCIP_HEURTIMING_AFTERLPNODE
62 #define HEUR_USESSUBSCIP TRUE /**< disable the heuristic in sub-SCIPs, even though it does not use any */
63 
64 #define DEFAULT_INITTHETA 0.125 /**< default initial regularization right-hand side value (< 0.25) */
65 #define DEFAULT_SIGMA 0.5 /**< default regularization update factor (< 1) */
66 #define DEFAULT_MAXITER 100 /**< default maximum number of iterations of the MPEC loop */
67 #define DEFAULT_MAXNLPITER 500 /**< default maximum number of NLP iterations per solve */
68 #define DEFAULT_MINGAPLEFT 0.05 /**< default minimum amount of gap left in order to call the heuristic */
69 #define DEFAULT_SUBNLPTRIGGER 1e-3 /**< default maximum integrality violation before triggering a sub-NLP call */
70 #define DEFAULT_MAXNLPCOST 1e+8 /**< default maximum cost available for solving NLPs per call of the heuristic */
71 #define DEFAULT_MINIMPROVE 0.01 /**< default factor by which heuristic should at least improve the incumbent */
72 #define DEFAULT_MAXNUNSUCC 10 /**< default maximum number of consecutive calls for which the heuristic did not find an improving solution */
73 
74 /*
75  * Data structures
76  */
77 
78 /** primal heuristic data */
79 struct SCIP_HeurData
80 {
81  SCIP_NLPI* nlpi; /**< nlpi used to create the nlpi problem */
82  SCIP_NLPIPROBLEM* nlpiprob; /**< nlpi problem representing the NLP relaxation */
83  SCIP_HASHMAP* var2idx; /**< mapping between variables and nlpi indices */
84  SCIP_HEUR* subnlp; /**< sub-NLP heuristic */
85 
86  SCIP_Real inittheta; /**< initial regularization right-hand side value */
87  SCIP_Real sigma; /**< regularization update factor */
88  SCIP_Real subnlptrigger; /**< maximum number of NLP iterations per solve */
89  SCIP_Real maxnlpcost; /**< maximum cost available for solving NLPs per call of the heuristic */
90  SCIP_Real minimprove; /**< factor by which heuristic should at least improve the incumbent */
91  SCIP_Real mingapleft; /**< minimum amount of gap left in order to call the heuristic */
92  int maxiter; /**< maximum number of iterations of the MPEC loop */
93  int maxnlpiter; /**< maximum number of NLP iterations per solve */
94  int nunsucc; /**< number of consecutive calls for which the heuristic did not find an
95  * improving solution */
96  int maxnunsucc; /**< maximum number of consecutive calls for which the heuristic did not
97  * find an improving solution */
98 };
99 
100 
101 /*
102  * Local methods
103  */
104 
105 /** creates the data structure for generating the current NLP relaxation */
106 static
108  SCIP* scip, /**< SCIP data structure */
109  SCIP_HEURDATA* heurdata /**< heuristic data */
110  )
111 {
112  SCIP_Real cutoff = SCIPinfinity(scip);
113 
114  assert(heurdata != NULL);
115  assert(heurdata->nlpi != NULL);
116 
117  /* NLP has been already created */
118  if( heurdata->nlpiprob != NULL )
119  return SCIP_OKAY;
120 
121  /* compute cutoff value to ensure minimum improvement */
122  if( SCIPgetNSols(scip) > 0 )
123  {
124  SCIP_Real upperbound = SCIPgetUpperbound(scip) - SCIPsumepsilon(scip);
125 
126  assert( !SCIPisInfinity(scip, SCIPgetUpperbound(scip)) );
127 
128  if( !SCIPisInfinity(scip, -SCIPgetLowerbound(scip)) )
129  {
130  cutoff = (1.0 - heurdata->minimprove) * SCIPgetUpperbound(scip)
131  + heurdata->minimprove * SCIPgetLowerbound(scip);
132  }
133  else
134  {
135  if( SCIPgetUpperbound(scip) >= 0.0 )
136  cutoff = ( 1.0 - heurdata->minimprove ) * SCIPgetUpperbound(scip);
137  else
138  cutoff = ( 1.0 + heurdata->minimprove ) * SCIPgetUpperbound(scip);
139  }
140  cutoff = MIN(upperbound, cutoff);
141  SCIPdebugMsg(scip, "set objective limit %g in [%g,%g]\n", cutoff, SCIPgetLowerbound(scip),
142  SCIPgetUpperbound(scip));
143  }
144 
145  SCIP_CALL( SCIPhashmapCreate(&heurdata->var2idx, SCIPblkmem(scip), SCIPgetNVars(scip)) );
146  SCIP_CALL( SCIPcreateNlpiProblemFromNlRows(scip, heurdata->nlpi, &heurdata->nlpiprob, "MPEC-nlp", SCIPgetNLPNlRows(scip), SCIPgetNNLPNlRows(scip),
147  heurdata->var2idx, NULL, NULL, cutoff, TRUE, FALSE) );
148 
149  return SCIP_OKAY;
150 }
151 
152 /** frees the data structures for the NLP relaxation */
153 static
155  SCIP* scip, /**< SCIP data structure */
156  SCIP_HEURDATA* heurdata /**< heuristic data */
157  )
158 {
159  assert(heurdata != NULL);
160 
161  /* NLP has not been created yet */
162  if( heurdata->nlpiprob == NULL )
163  return SCIP_OKAY;
164 
165  assert(heurdata->nlpi != NULL);
166  assert(heurdata->var2idx != NULL);
167 
168  SCIPhashmapFree(&heurdata->var2idx);
169  SCIP_CALL( SCIPfreeNlpiProblem(scip, heurdata->nlpi, &heurdata->nlpiprob) );
170 
171  return SCIP_OKAY;
172 }
173 
174 /** adds or updates the regularization constraints to the NLP; for a given parameter theta we add for each non-fixed
175  * binary variable z the constraint z*(1-z) <= theta; if these constraint are already present we update the theta on
176  * the right-hand side
177  */
178 static
180  SCIP* scip, /**< SCIP data structure */
181  SCIP_HEURDATA* heurdata, /**< heuristic data */
182  SCIP_VAR** binvars, /**< array containing all non-fixed binary variables */
183  int nbinvars, /**< total number of non-fixed binary variables */
184  SCIP_Real theta, /**< regularization parameter */
185  SCIP_Bool update /**< should the regularization constraints be added or updated? */
186  )
187 {
188  int i;
189 
190  assert(binvars != NULL);
191  assert(nbinvars > 0);
192 
193  /* add or update regularization for each non-fixed binary variables */
194  if( !update )
195  {
196  SCIP_NLROW** nlrows;
197 
198  SCIP_CALL( SCIPallocBufferArray(scip, &nlrows, nbinvars) );
199 
200  for( i = 0; i < nbinvars; ++i )
201  {
202  SCIP_Real one = 1.0;
203  SCIP_Real minusone = -1.0;
204  SCIP_EXPR* varexpr;
205  SCIP_EXPR* powexpr;
206  SCIP_EXPR* sumexpr;
207  char name[SCIP_MAXSTRLEN];
208 
209  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_reg", SCIPvarGetName(binvars[i]));
210 
211  /* -binvars[i]^2 */
212  SCIP_CALL( SCIPcreateExprVar(scip, &varexpr, binvars[i], NULL, NULL) );
213  SCIP_CALL( SCIPcreateExprPow(scip, &powexpr, varexpr, 2.0, NULL, NULL) );
214  SCIP_CALL( SCIPcreateExprSum(scip, &sumexpr, 1, &powexpr, &minusone, 0.0, NULL, NULL) );
215 
216  /* binvars[i] - binvars[i]^2 <= theta */
217  SCIP_CALL( SCIPcreateNlRow(scip, &nlrows[i], name, 0.0, 1, &binvars[i], &one, sumexpr, -SCIPinfinity(scip), theta, SCIP_EXPRCURV_CONCAVE) );
218 
219  SCIP_CALL( SCIPreleaseExpr(scip, &sumexpr) );
220  SCIP_CALL( SCIPreleaseExpr(scip, &powexpr) );
221  SCIP_CALL( SCIPreleaseExpr(scip, &varexpr) );
222  }
223 
224  SCIP_CALL( SCIPaddNlpiProblemNlRows(scip, heurdata->nlpi, heurdata->nlpiprob, heurdata->var2idx, nlrows, nbinvars) );
225 
226  for( i = nbinvars-1; i >= 0; --i )
227  {
228  SCIP_CALL( SCIPreleaseNlRow(scip, &nlrows[i]) );
229  }
230 
231  SCIPfreeBufferArray(scip, &nlrows);
232  }
233  else
234  {
235  int startidx = SCIPgetNNLPNlRows(scip) + 1; /* the cutoff is a separate constraint */
236  SCIP_Real* lhss;
237  SCIP_Real* rhss;
238  int* indices;
239 
240  SCIP_CALL( SCIPallocBufferArray(scip, &lhss, nbinvars) );
241  SCIP_CALL( SCIPallocBufferArray(scip, &rhss, nbinvars) );
242  SCIP_CALL( SCIPallocBufferArray(scip, &indices, nbinvars) );
243 
244  for( i = 0; i < nbinvars; ++i )
245  {
246  lhss[i] = -SCIPinfinity(scip);
247  rhss[i] = theta;
248  indices[i] = startidx + i;
249  }
250 
251  SCIP_CALL( SCIPchgNlpiConsSides(scip, heurdata->nlpi, heurdata->nlpiprob, nbinvars, indices, lhss, rhss) );
252 
253  SCIPfreeBufferArray(scip, &indices);
254  SCIPfreeBufferArray(scip, &rhss);
255  SCIPfreeBufferArray(scip, &lhss);
256  }
257 
258  return SCIP_OKAY;
259 }
260 
261 /** recursive helper function to count the number of nodes in a sub-expr */
262 static
264  SCIP_EXPR* expr /**< expression */
265  )
266 {
267  int sum;
268  int i;
269 
270  assert(expr != NULL);
271 
272  sum = 0;
273  for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
274  {
275  SCIP_EXPR* child = SCIPexprGetChildren(expr)[i];
276  sum += getExprSize(child);
277  }
278  return 1 + sum;
279 }
280 
281 /** main execution function of the MPEC heuristic */
282 static
284  SCIP* scip, /**< SCIP data structure */
285  SCIP_HEUR* heur, /**< MPEC heuristic */
286  SCIP_HEURDATA* heurdata, /**< heuristic data */
287  SCIP_RESULT* result /**< pointer to store the result */
288  )
289 {
290  SCIP_NLPSTATISTICS nlpstatistics;
291  SCIP_NLPPARAM nlpparam = SCIP_NLPPARAM_DEFAULT(scip); /*lint !e446*/
292  SCIP_VAR** binvars = NULL;
293  SCIP_Real* initguess = NULL;
294  SCIP_Real* ubs = NULL;
295  SCIP_Real* lbs = NULL;
296  int* indices = NULL;
297  SCIP_Real theta = heurdata->inittheta;
298  SCIP_Real nlpcostperiter = 0.0;
299  SCIP_Real nlpcostleft = heurdata->maxnlpcost;
300  SCIP_Bool reinit = TRUE;
301  SCIP_Bool fixed = FALSE;
302  SCIP_Bool subnlpcalled = FALSE;
303  int nbinvars = 0;
304  int i;
305 
306  assert(heurdata->nlpiprob != NULL);
307  assert(heurdata->var2idx != NULL);
308  assert(heurdata->nlpi != NULL);
309  assert(result != NULL);
310 
311  SCIP_CALL( SCIPallocBufferArray(scip, &binvars, SCIPgetNBinVars(scip)) );
312 
313  /* collect all non-fixed binary variables */
314  for( i = 0; i < SCIPgetNBinVars(scip); ++i )
315  {
316  SCIP_VAR* var = SCIPgetVars(scip)[i];
317  assert(SCIPvarGetType(var) == SCIP_VARTYPE_BINARY);
318 
319  if( !SCIPisFeasEQ(scip, SCIPvarGetLbLocal(var), SCIPvarGetUbLocal(var)) )
320  binvars[nbinvars++] = var;
321  }
322 
323  /* all binary variables are fixed */
324  SCIPdebugMsg(scip, "nbinvars %d\n", nbinvars);
325  if( nbinvars == 0 )
326  goto TERMINATE;
327 
328  SCIP_CALL( SCIPallocBufferArray(scip, &initguess, SCIPgetNVars(scip)) );
329  SCIP_CALL( SCIPallocBufferArray(scip, &lbs, nbinvars) );
330  SCIP_CALL( SCIPallocBufferArray(scip, &ubs, nbinvars) );
331  SCIP_CALL( SCIPallocBufferArray(scip, &indices, nbinvars) );
332 
333  /* compute estimate cost for each NLP iteration */
334  for( i = 0; i < SCIPgetNNLPNlRows(scip); ++i )
335  {
336  SCIP_NLROW* nlrow = SCIPgetNLPNlRows(scip)[i];
337  assert(nlrow != NULL);
338 
339  nlpcostperiter += 1.0 * SCIPnlrowGetNLinearVars(nlrow);
340 
341  if( SCIPnlrowGetExpr(nlrow) != NULL )
342  nlpcostperiter += 3.0 * getExprSize(SCIPnlrowGetExpr(nlrow));
343  }
344 
345  /* set initial guess */
346  for( i = 0; i < SCIPgetNVars(scip); ++i )
347  {
348  SCIP_VAR* var = SCIPgetVars(scip)[i];
349  initguess[i] = SCIPgetSolVal(scip, NULL, var);
350  /* SCIPdebugMsg(scip, "set initial value for %s to %g\n", SCIPvarGetName(var), initguess[i]); */
351  }
352  SCIP_CALL( SCIPsetNlpiInitialGuess(scip, heurdata->nlpi, heurdata->nlpiprob, initguess, NULL, NULL, NULL) );
353 
354  /* set parameters of NLP solver */
355  nlpparam.feastol /= 10.0;
356  nlpparam.opttol /= 10.0;
357  nlpparam.iterlimit = heurdata->maxnlpiter;
358 
359  /* main loop */
360  for( i = 0; i < heurdata->maxiter && *result != SCIP_FOUNDSOL && nlpcostleft > 0.0 && !SCIPisStopped(scip); ++i )
361  {
362  SCIP_Real* primal = NULL;
363  SCIP_Bool binaryfeasible;
364  SCIP_Bool regularfeasible;
365  SCIP_NLPSOLSTAT solstat;
366  SCIP_Real maxviolbin = 0.0;
367  SCIP_Real maxviolreg = 0.0;
368  int j;
369 
370  /* add or update regularization */
371  SCIP_CALL( addRegularScholtes(scip, heurdata, binvars, nbinvars, theta, i > 0) );
372 
373  /* solve NLP */
374  SCIP_CALL( SCIPsolveNlpiParam(scip, heurdata->nlpi, heurdata->nlpiprob, nlpparam) );
375  solstat = SCIPgetNlpiSolstat(scip, heurdata->nlpi, heurdata->nlpiprob);
376 
377  /* give up if an error occurred or no primal values are accessible */
378  if( solstat > SCIP_NLPSOLSTAT_LOCINFEASIBLE )
379  {
380  SCIPdebugMsg(scip, "error occured during NLP solve -> stop!\n");
381  break;
382  }
383 
384  /* update nlpcostleft */
385  SCIP_CALL( SCIPgetNlpiStatistics(scip, heurdata->nlpi, heurdata->nlpiprob, &nlpstatistics) );
386  nlpcostleft -= nlpstatistics.niterations * nlpcostperiter * nbinvars;
387  SCIPdebugMsg(scip, "nlpcostleft = %e\n", nlpcostleft);
388 
389  SCIP_CALL( SCIPgetNlpiSolution(scip, heurdata->nlpi, heurdata->nlpiprob, &primal, NULL, NULL, NULL, NULL) );
390  assert(primal != NULL);
391 
392  /* check for binary feasibility */
393  binaryfeasible = TRUE;
394  regularfeasible = TRUE;
395  for( j = 0; j < nbinvars; ++j )
396  {
397  int idx = SCIPhashmapGetImageInt(heurdata->var2idx, (void*)binvars[j]);
398  binaryfeasible = binaryfeasible && SCIPisFeasIntegral(scip, primal[idx]);
399  regularfeasible = regularfeasible && SCIPisLE(scip, primal[idx] - SQR(primal[idx]), theta);
400 
401  maxviolreg = MAX(maxviolreg, primal[idx] - SQR(primal[idx]) - theta);
402  maxviolbin = MAX(maxviolbin, MIN(primal[idx], 1.0-primal[idx]));
403  }
404  SCIPdebugMsg(scip, "maxviol-regularization %g maxviol-integrality %g\n", maxviolreg, maxviolbin);
405 
406  /* call sub-NLP heuristic when the maximum binary infeasibility is small enough (or this is the last iteration
407  * because we reached the nlpcost limit)
408  */
409  if( !subnlpcalled && heurdata->subnlp != NULL
410  && (SCIPisLE(scip, maxviolbin, heurdata->subnlptrigger) || nlpcostleft <= 0.0)
411  && !SCIPisStopped(scip) )
412  {
413  SCIP_SOL* refpoint;
414  SCIP_RESULT subnlpresult;
415 
416  SCIPdebugMsg(scip, "call sub-NLP heuristic because binary infeasibility is small enough\n");
417  SCIP_CALL( SCIPcreateSol(scip, &refpoint, heur) );
418 
419  for( j = 0; j < SCIPgetNVars(scip); ++j )
420  {
421  SCIP_VAR* var = SCIPgetVars(scip)[j];
422  SCIP_Real val = SCIPvarIsBinary(var) ? SCIPfeasRound(scip, primal[j]) : primal[j];
423  SCIP_CALL( SCIPsetSolVal(scip, refpoint, var, val) );
424  }
425 
426  SCIP_CALL( SCIPapplyHeurSubNlp(scip, heurdata->subnlp, &subnlpresult, refpoint, NULL) );
427  SCIP_CALL( SCIPfreeSol(scip, &refpoint) );
428  SCIPdebugMsg(scip, "result of sub-NLP call: %d\n", subnlpresult);
429 
430  /* stop MPEC heuristic when the sub-NLP heuristic has found a feasible solution */
431  if( subnlpresult == SCIP_FOUNDSOL )
432  {
433  SCIPdebugMsg(scip, "sub-NLP found a feasible solution -> stop!\n");
434  break;
435  }
436 
437  subnlpcalled = TRUE;
438  }
439 
440  /* NLP feasible + binary feasible -> add solution and stop */
441  if( solstat <= SCIP_NLPSOLSTAT_FEASIBLE && binaryfeasible )
442  {
443  SCIP_SOL* sol;
444  SCIP_Bool stored;
445 
446  SCIP_CALL( SCIPcreateSol(scip, &sol, heur) );
447 
448  for( j = 0; j < SCIPgetNVars(scip); ++j )
449  {
450  SCIP_VAR* var = SCIPgetVars(scip)[j];
451  assert(j == SCIPhashmapGetImageInt(heurdata->var2idx, (void*)var));
452  SCIP_CALL( SCIPsetSolVal(scip, sol, var, primal[j]) );
453  }
454 
455 #ifdef SCIP_DEBUG
456  SCIP_CALL( SCIPtrySolFree(scip, &sol, TRUE, TRUE, TRUE, TRUE, FALSE, &stored) );
457 #else
458  SCIP_CALL( SCIPtrySolFree(scip, &sol, FALSE, FALSE, TRUE, TRUE, FALSE, &stored) );
459 #endif
460  SCIPdebugMsg(scip, "found a solution (stored = %u)\n", stored);
461 
462  if( stored )
463  *result = SCIP_FOUNDSOL;
464  break;
465  }
466 
467  /* NLP feasible + binary infeasible -> reduce theta */
468  else if( solstat <= SCIP_NLPSOLSTAT_FEASIBLE && !binaryfeasible )
469  {
470  BMScopyMemoryArray(initguess, primal, SCIPgetNVars(scip));
471  SCIP_CALL( SCIPsetNlpiInitialGuess(scip, heurdata->nlpi, heurdata->nlpiprob, primal, NULL, NULL, NULL) );
472  SCIPdebugMsg(scip, "update theta from %g -> %g\n", theta, theta*heurdata->sigma);
473 
474  if( !reinit )
475  {
476  SCIPdebugMsg(scip, "reinit fixed the infeasibility\n");
477  reinit = TRUE;
478  }
479 
480  theta *= heurdata->sigma;
481 
482  /* unfix binary variables */
483  if( fixed )
484  {
485  SCIPdebugMsg(scip, "unfixing binary variables\n");
486  for( j = 0; j < nbinvars; ++j )
487  {
488  lbs[j] = 0.0;
489  ubs[j] = 1.0;
490  indices[j] = SCIPhashmapGetImageInt(heurdata->var2idx, (void*)binvars[j]);
491  }
492  SCIP_CALL( SCIPchgNlpiVarBounds(scip, heurdata->nlpi, heurdata->nlpiprob, nbinvars, indices, lbs, ubs) );
493  fixed = FALSE;
494  }
495  }
496 
497  /* NLP infeasible + regularization feasible -> stop (give up) */
498  else if( solstat > SCIP_NLPSOLSTAT_FEASIBLE && regularfeasible )
499  {
500  SCIPdebugMsg(scip, "NLP is infeasible but regularization constraints are satisfied -> stop!\n");
501  break;
502  }
503 
504  /* NLP infeasible + binary infeasible -> set initial point / fix binary variables */
505  else
506  {
507  assert(solstat > SCIP_NLPSOLSTAT_FEASIBLE && !regularfeasible);
508 
509  SCIPdebugMsg(scip, "NLP solution is not feasible for the NLP and the binary variables\n");
510 
511  /* stop if fixing did not resolve the infeasibility */
512  if( fixed )
513  {
514  SCIPdebugMsg(scip, "fixing variables did not resolve infeasibility -> stop!\n");
515  break;
516  }
517 
518  /* fix variables if reinit is FALSE; otherwise set another initial point */
519  if( !reinit )
520  {
521  int nfixedvars = 0;
522 
523  /* fix binary variables */
524  for( j = 0; j < nbinvars; ++j )
525  {
526  int idx = SCIPhashmapGetImageInt(heurdata->var2idx, (void*)binvars[j]);
527  indices[j] = idx;
528 
529  if( SCIPisFeasLE(scip, primal[idx] - SQR(primal[idx]), theta) )
530  {
531  lbs[j] = 0.0;
532  ubs[j] = 1.0;
533  }
534  else
535  {
536  lbs[j] = primal[idx] >= 0.5 ? 0.0 : 1.0;
537  ubs[j] = primal[idx] >= 0.5 ? 0.0 : 1.0;
538  ++nfixedvars;
539  /* SCIPdebugMsg(scip, "fix binary variable %s = %g\n", SCIPvarGetName(binvars[j]), ubs[j]); */
540  }
541  }
542  SCIPdebugMsg(scip, "fixed %d binary variables\n", nfixedvars);
543  SCIP_CALL( SCIPchgNlpiVarBounds(scip, heurdata->nlpi, heurdata->nlpiprob, nbinvars, indices, lbs, ubs) );
544  fixed = TRUE;
545  }
546  else
547  {
548  SCIPdebugMsg(scip, "update initial guess\n");
549 
550  /* set initial point */
551  for( j = 0; j < nbinvars; ++j )
552  {
553  int idx = SCIPhashmapGetImageInt(heurdata->var2idx, (void*)binvars[j]);
554  initguess[idx] = primal[idx] >= 0.5 ? 0.0 : 1.0;
555  /* SCIPdebugMsg(scip, "update init guess for %s to %g\n", SCIPvarGetName(binvars[j]), initguess[idx]); */
556  }
557  SCIP_CALL( SCIPsetNlpiInitialGuess(scip, heurdata->nlpi, heurdata->nlpiprob, initguess, NULL, NULL, NULL) );
558  reinit = FALSE;
559  }
560  }
561  }
562 
563 TERMINATE:
564  SCIPfreeBufferArrayNull(scip, &indices);
565  SCIPfreeBufferArrayNull(scip, &ubs);
566  SCIPfreeBufferArrayNull(scip, &lbs);
567  SCIPfreeBufferArrayNull(scip, &initguess);
568  SCIPfreeBufferArray(scip, &binvars);
569 
570  return SCIP_OKAY;
571 }
572 
573 
574 /*
575  * Callback methods of primal heuristic
576  */
577 
578 /** copy method for primal heuristic plugins (called when SCIP copies plugins) */
579 static
580 SCIP_DECL_HEURCOPY(heurCopyMpec)
581 { /*lint --e{715}*/
582  assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
583 
584  /* call inclusion method of primal heuristic */
586 
587  return SCIP_OKAY;
588 }
589 
590 /** destructor of primal heuristic to free user data (called when SCIP is exiting) */
591 static
592 SCIP_DECL_HEURFREE(heurFreeMpec)
593 { /*lint --e{715}*/
594  SCIP_HEURDATA* heurdata = SCIPheurGetData(heur);
595  assert(heurdata != NULL);
596 
597  SCIPfreeBlockMemory(scip, &heurdata);
598  SCIPheurSetData(heur, NULL);
599 
600  return SCIP_OKAY;
601 }
602 
603 /** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
604 static
605 SCIP_DECL_HEURINITSOL(heurInitsolMpec)
606 { /*lint --e{715}*/
607  SCIP_HEURDATA* heurdata = SCIPheurGetData(heur);
608 
609  assert(heurdata != NULL);
610  assert(heurdata->nlpi == NULL);
611 
612  if( SCIPgetNNlpis(scip) > 0 )
613  {
614  heurdata->nlpi = SCIPgetNlpis(scip)[0];
615  heurdata->subnlp = SCIPfindHeur(scip, "subnlp");
616  }
617 
618  return SCIP_OKAY;
619 }
620 
621 
622 /** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
623 static
624 SCIP_DECL_HEUREXITSOL(heurExitsolMpec)
625 { /*lint --e{715}*/
626  SCIP_HEURDATA* heurdata = SCIPheurGetData(heur);
627 
628  assert(heurdata != NULL);
629  heurdata->nlpi = NULL;
630 
631  return SCIP_OKAY;
632 }
633 
634 /** execution method of primal heuristic */
635 static
636 SCIP_DECL_HEUREXEC(heurExecMpec)
637 { /*lint --e{715}*/
638  SCIP_HEURDATA* heurdata = SCIPheurGetData(heur);
639  SCIP_CONSHDLR* sosonehdlr = SCIPfindConshdlr(scip, "SOS1");
640  SCIP_CONSHDLR* sostwohdlr = SCIPfindConshdlr(scip, "SOS2");
641 
642  assert(heurdata != NULL);
643 
644  *result = SCIP_DIDNOTRUN;
645 
646  if( SCIPgetNIntVars(scip) > 0 || SCIPgetNBinVars(scip) == 0
647  || heurdata->nlpi == NULL || !SCIPisNLPConstructed(scip)
648  || heurdata->mingapleft > SCIPgetGap(scip)
649  || heurdata->nunsucc > heurdata->maxnunsucc )
650  return SCIP_OKAY;
651 
652  /* skip heuristic if constraints without a nonlinear representation are present */
653  if( (sosonehdlr != NULL && SCIPconshdlrGetNConss(sosonehdlr) > 0) ||
654  (sostwohdlr != NULL && SCIPconshdlrGetNConss(sostwohdlr) > 0) )
655  {
656  return SCIP_OKAY;
657  }
658 
659  *result = SCIP_DIDNOTFIND;
660 
661  /* call MPEC method */
662  SCIP_CALL( createNLP(scip, heurdata) );
663  SCIP_CALL( heurExec(scip, heur, heurdata, result) );
664  SCIP_CALL( freeNLP(scip, heurdata) );
665 
666  /* update number of unsuccessful calls */
667  heurdata->nunsucc = (*result == SCIP_FOUNDSOL) ? 0 : heurdata->nunsucc + 1;
668 
669  return SCIP_OKAY;
670 }
671 
672 
673 /*
674  * primal heuristic specific interface methods
675  */
676 
677 /** creates the mpec primal heuristic and includes it in SCIP */
679  SCIP* scip /**< SCIP data structure */
680  )
681 {
682  SCIP_HEURDATA* heurdata = NULL;
683  SCIP_HEUR* heur = NULL;
684 
685  /* create mpec primal heuristic data */
686  SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
687  BMSclearMemory(heurdata);
688 
689  /* include primal heuristic */
690  SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
692  HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecMpec, heurdata) );
693 
694  assert(heur != NULL);
695 
696  /* set non fundamental callbacks via setter functions */
697  SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyMpec) );
698  SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeMpec) );
699  SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolMpec) );
700  SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolMpec) );
701 
702  /* add mpec primal heuristic parameters */
703  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/inittheta",
704  "initial regularization right-hand side value",
705  &heurdata->inittheta, FALSE, DEFAULT_INITTHETA, 0.0, 0.25, NULL, NULL) );
706 
707  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/sigma",
708  "regularization update factor",
709  &heurdata->sigma, FALSE, DEFAULT_SIGMA, 0.0, 1.0, NULL, NULL) );
710 
711  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/subnlptrigger",
712  "maximum number of NLP iterations per solve",
713  &heurdata->subnlptrigger, FALSE, DEFAULT_SUBNLPTRIGGER, 0.0, 1.0, NULL, NULL) );
714 
715  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/maxnlpcost",
716  "maximum cost available for solving NLPs per call of the heuristic",
717  &heurdata->maxnlpcost, FALSE, DEFAULT_MAXNLPCOST, 0.0, SCIPinfinity(scip), NULL, NULL) );
718 
719  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
720  "factor by which heuristic should at least improve the incumbent",
721  &heurdata->minimprove, FALSE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
722 
723  SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/mingapleft",
724  "minimum amount of gap left in order to call the heuristic",
725  &heurdata->mingapleft, FALSE, DEFAULT_MINGAPLEFT, 0.0, SCIPinfinity(scip), NULL, NULL) );
726 
727  SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxiter",
728  "maximum number of iterations of the MPEC loop",
729  &heurdata->maxiter, FALSE, DEFAULT_MAXITER, 0, INT_MAX, NULL, NULL) );
730 
731  SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxnlpiter",
732  "maximum number of NLP iterations per solve",
733  &heurdata->maxnlpiter, FALSE, DEFAULT_MAXNLPITER, 0, INT_MAX, NULL, NULL) );
734 
735  SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxnunsucc",
736  "maximum number of consecutive calls for which the heuristic did not find an improving solution",
737  &heurdata->maxnunsucc, FALSE, DEFAULT_MAXNUNSUCC, 0, INT_MAX, NULL, NULL) );
738 
739  return SCIP_OKAY;
740 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
Definition: scip_heur.c:233
SCIP_RETCODE SCIPincludeHeurMpec(SCIP *scip)
Definition: heur_mpec.c:678
int SCIPgetNIntVars(SCIP *scip)
Definition: scip_prob.c:2081
static SCIP_RETCODE heurExec(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_RESULT *result)
Definition: heur_mpec.c:283
#define HEUR_FREQ
Definition: heur_mpec.c:58
int SCIPgetNNLPNlRows(SCIP *scip)
Definition: scip_nlp.c:332
mpec primal heuristic
SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
Definition: scip_nlp.c:101
SCIP_RETCODE SCIPcreateExprPow(SCIP *scip, SCIP_EXPR **expr, SCIP_EXPR *child, SCIP_Real exponent, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_pow.c:3166
static SCIP_DECL_HEURFREE(heurFreeMpec)
Definition: heur_mpec.c:592
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
public methods for SCIP parameter handling
SCIP_Real opttol
Definition: type_nlpi.h:61
public methods for memory management
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:877
int SCIPexprGetNChildren(SCIP_EXPR *expr)
Definition: expr.c:3798
#define SCIP_MAXSTRLEN
Definition: def.h:293
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17966
public methods for timing
SCIP_Real feastol
Definition: type_nlpi.h:60
SCIP_Real SCIPfeasRound(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17431
#define DEFAULT_SUBNLPTRIGGER
Definition: heur_mpec.c:69
#define FALSE
Definition: def.h:87
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3014
SCIP_RETCODE SCIPapplyHeurSubNlp(SCIP *scip, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_SOL *refpoint, SCIP_SOL *resultsol)
Definition: heur_subnlp.c:1757
static SCIP_RETCODE createNLP(SCIP *scip, SCIP_HEURDATA *heurdata)
Definition: heur_mpec.c:107
#define DEFAULT_MAXNLPITER
Definition: heur_mpec.c:67
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10755
#define HEUR_USESSUBSCIP
Definition: heur_mpec.c:62
#define TRUE
Definition: def.h:86
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
#define DEFAULT_MAXNLPCOST
Definition: heur_mpec.c:70
int SCIPnlrowGetNLinearVars(SCIP_NLROW *nlrow)
Definition: nlp.c:1764
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_NLPI ** SCIPgetNlpis(SCIP *scip)
Definition: scip_nlpi.c:177
SCIP_RETCODE SCIPcreateExprVar(SCIP *scip, SCIP_EXPR **expr, SCIP_VAR *var, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_var.c:381
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:127
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1362
variable expression handler
#define DEFAULT_MAXNUNSUCC
Definition: heur_mpec.c:72
#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 SCIPcreateExprSum(SCIP *scip, SCIP_EXPR **expr, int nchildren, SCIP_EXPR **children, SCIP_Real *coefficients, SCIP_Real constant, SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), void *ownercreatedata)
Definition: expr_sum.c:1070
#define DEFAULT_MINGAPLEFT
Definition: heur_mpec.c:68
#define HEUR_DESC
Definition: heur_mpec.c:55
#define DEFAULT_MAXITER
Definition: heur_mpec.c:66
public methods for numerical tolerances
public functions to work with algebraic expressions
static SCIP_DECL_HEUREXITSOL(heurExitsolMpec)
Definition: heur_mpec.c:624
public methods for querying solving statistics
int SCIPgetNNlpis(SCIP *scip)
Definition: scip_nlpi.c:190
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
Definition: expr.c:3808
public methods for NLPI solver interfaces
public methods for managing constraints
SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINITSOL((*heurinitsol)))
Definition: scip_heur.c:217
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1441
SCIP_HEUR * SCIPfindHeur(SCIP *scip, const char *name)
Definition: scip_heur.c:249
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip_heur.c:169
enum SCIP_NlpSolStat SCIP_NLPSOLSTAT
Definition: type_nlpi.h:159
SCIP_RETCODE SCIPreleaseNlRow(SCIP *scip, SCIP_NLROW **nlrow)
Definition: scip_nlp.c:1016
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:128
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:48
static SCIP_DECL_HEURCOPY(heurCopyMpec)
Definition: heur_mpec.c:580
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17251
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3048
#define NULL
Definition: lpi_spx1.cpp:155
power and signed power expression handlers
#define SCIP_CALL(x)
Definition: def.h:384
SCIP_Real SCIPgetLowerbound(SCIP *scip)
SCIP_NLROW ** SCIPgetNLPNlRows(SCIP *scip)
Definition: scip_nlp.c:310
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_DECL_HEUREXEC(heurExecMpec)
Definition: heur_mpec.c:636
#define HEUR_TIMING
Definition: heur_mpec.c:61
#define HEUR_PRIORITY
Definition: heur_mpec.c:57
public methods for primal heuristic plugins and divesets
static SCIP_RETCODE freeNLP(SCIP *scip, SCIP_HEURDATA *heurdata)
Definition: heur_mpec.c:154
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4590
public methods for constraint handler plugins and constraints
public methods for NLP management
#define HEUR_MAXDEPTH
Definition: heur_mpec.c:60
#define HEUR_NAME
Definition: heur_mpec.c:54
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
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
#define DEFAULT_INITTHETA
Definition: heur_mpec.c:64
SCIP_RETCODE SCIPreleaseExpr(SCIP *scip, SCIP_EXPR **expr)
Definition: scip_expr.c:1407
SCIP_Real SCIPgetGap(SCIP *scip)
#define MAX(x, y)
Definition: tclique_def.h:83
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 SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:976
SCIP_RETCODE SCIPcreateNlRow(SCIP *scip, SCIP_NLROW **nlrow, const char *name, SCIP_Real constant, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, SCIP_EXPRCURV curvature)
Definition: scip_nlp.c:912
int SCIPgetNSols(SCIP *scip)
Definition: scip_sol.c:2205
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:127
SCIP_RETCODE SCIPcreateNlpiProblemFromNlRows(SCIP *scip, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM **nlpiprob, const char *name, SCIP_NLROW **nlrows, int nnlrows, SCIP_HASHMAP *var2idx, SCIP_HASHMAP *nlrow2idx, SCIP_Real *nlscore, SCIP_Real cutoffbound, SCIP_Bool setobj, SCIP_Bool onlyconvex)
Definition: scip_nlpi.c:434
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
#define BMSclearMemory(ptr)
Definition: memory.h:122
int SCIPgetNBinVars(SCIP *scip)
Definition: scip_prob.c:2036
static int getExprSize(SCIP_EXPR *expr)
Definition: heur_mpec.c:263
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1991
public methods for nonlinear relaxation
#define HEUR_DISPCHAR
Definition: heur_mpec.c:56
general public methods
public methods for solutions
static SCIP_DECL_HEURINITSOL(heurInitsolMpec)
Definition: heur_mpec.c:605
#define DEFAULT_SIGMA
Definition: heur_mpec.c:65
public methods for message output
NLP local search primal heuristic using sub-SCIPs.
#define HEUR_FREQOFS
Definition: heur_mpec.c:59
static SCIP_RETCODE addRegularScholtes(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR **binvars, int nbinvars, SCIP_Real theta, SCIP_Bool update)
Definition: heur_mpec.c:179
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1946
#define SCIP_NLPPARAM_DEFAULT(scip)
Definition: type_nlpi.h:117
#define SCIP_Real
Definition: def.h:177
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:694
public methods for message handling
SCIP_RETCODE SCIPaddNlpiProblemNlRows(SCIP *scip, SCIP_NLPI *nlpi, SCIP_NLPIPROBLEM *nlpiprob, SCIP_HASHMAP *var2idx, SCIP_NLROW **nlrows, int nnlrows)
Definition: scip_nlpi.c:855
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17416
sum expression handler
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
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_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPsumepsilon(SCIP *scip)
SCIP_Real SCIPgetUpperbound(SCIP *scip)
public methods for primal heuristics
SCIPallocBlockMemory(scip, subsol))
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3221
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1352
public methods for global and local (sub)problems
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1352
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_EXPR * SCIPnlrowGetExpr(SCIP_NLROW *nlrow)
Definition: nlp.c:1794
#define DEFAULT_MINIMPROVE
Definition: heur_mpec.c:71
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:319
memory allocation routines