Scippy

SCIP

Solving Constraint Integer Programs

heur_multistart.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-2025 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file heur_multistart.c
26 * @ingroup DEFPLUGINS_HEUR
27 * @brief multistart heuristic for convex and nonconvex MINLPs
28 * @author Benjamin Mueller
29 */
30
31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32
34#include "scip/scip_expr.h"
35#include "scip/pub_expr.h"
37#include "scip/heur_subnlp.h"
38#include "scip/pub_heur.h"
39#include "scip/pub_message.h"
40#include "scip/pub_misc.h"
41#include "scip/pub_misc_sort.h"
42#include "scip/pub_nlp.h"
43#include "scip/pub_var.h"
44#include "scip/scip_general.h"
45#include "scip/scip_heur.h"
46#include "scip/scip_mem.h"
47#include "scip/scip_message.h"
48#include "scip/scip_nlp.h"
49#include "scip/scip_nlpi.h"
50#include "scip/scip_numerics.h"
51#include "scip/scip_param.h"
52#include "scip/scip_prob.h"
54#include "scip/scip_sol.h"
55#include "scip/scip_timing.h"
56#include <string.h>
57
58
59#define HEUR_NAME "multistart"
60#define HEUR_DESC "multistart heuristic for convex and nonconvex MINLPs"
61#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
62#define HEUR_PRIORITY -2100000
63#define HEUR_FREQ 0
64#define HEUR_FREQOFS 0
65#define HEUR_MAXDEPTH -1
66#define HEUR_TIMING SCIP_HEURTIMING_AFTERNODE
67#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
68
69#define DEFAULT_RANDSEED 131 /**< initial random seed */
70#define DEFAULT_NRNDPOINTS 100 /**< default number of generated random points per call */
71#define DEFAULT_MAXBOUNDSIZE 2e+4 /**< default maximum variable domain size for unbounded variables */
72#define DEFAULT_MAXITER 300 /**< default number of iterations to reduce the violation of a point */
73#define DEFAULT_MINIMPRFAC 0.05 /**< default minimum required improving factor to proceed in improvement of a point */
74#define DEFAULT_MINIMPRITER 10 /**< default number of iteration when checking the minimum improvement */
75#define DEFAULT_MAXRELDIST 0.15 /**< default maximum distance between two points in the same cluster */
76#define DEFAULT_GRADLIMIT 5e+6 /**< default limit for gradient computations for all improvePoint() calls */
77#define DEFAULT_MAXNCLUSTER 3 /**< default maximum number of considered clusters per heuristic call */
78#define DEFAULT_ONLYNLPS TRUE /**< should the heuristic run only on continuous problems? */
79
80#define MINFEAS -1e+4 /**< minimum feasibility for a point; used for filtering and improving
81 * feasibility */
82#define MINIMPRFAC 0.95 /**< improvement factor used to discard randomly generated points with a
83 * too large objective value */
84#define GRADCOSTFAC_LINEAR 1.0 /**< gradient cost factor for the number of linear variables */
85#define GRADCOSTFAC_NONLINEAR 3.0 /**< gradient cost factor for the number of nodes in nonlinear expression */
86
87/*
88 * Data structures
89 */
90
91/** primal heuristic data */
92struct SCIP_HeurData
93{
94 int nrndpoints; /**< number of random points generated per execution call */
95 SCIP_Real maxboundsize; /**< maximum variable domain size for unbounded variables */
96 SCIP_RANDNUMGEN* randnumgen; /**< random number generator */
97 SCIP_HEUR* heursubnlp; /**< sub-NLP heuristic */
98
99 int maxiter; /**< number of iterations to reduce the maximum violation of a point */
100 SCIP_Real minimprfac; /**< minimum required improving factor to proceed in the improvement of a single point */
101 int minimpriter; /**< number of iteration when checking the minimum improvement */
102
103 SCIP_Real maxreldist; /**< maximum distance between two points in the same cluster */
104 SCIP_Real gradlimit; /**< limit for gradient computations for all improvePoint() calls (0 for no limit) */
105 int maxncluster; /**< maximum number of considered clusters per heuristic call */
106 SCIP_Bool onlynlps; /**< should the heuristic run only on continuous problems? */
107};
108
109
110/*
111 * Local methods
112 */
113
114
115/** returns an unique index of a variable in the range of 0,..,SCIPgetNVars(scip)-1 */
116#ifndef NDEBUG
117static
119 SCIP_HASHMAP* varindex, /**< maps variables to indicies between 0,..,SCIPgetNVars(scip)-1 */
120 SCIP_VAR* var /**< variable */
121 )
122{
123 assert(varindex != NULL);
124 assert(var != NULL);
125 assert(SCIPhashmapExists(varindex, (void*)var));
126
127 return SCIPhashmapGetImageInt(varindex, (void*)var);
128}
129#else
130#define getVarIndex(varindex,var) (SCIPhashmapGetImageInt((varindex), (void*)(var)))
131#endif
132
133/** samples and stores random points; stores points which have a better objective value than the current incumbent
134 * solution
135 */
136static
138 SCIP* scip, /**< SCIP data structure */
139 SCIP_SOL** rndpoints, /**< array to store all random points */
140 int nmaxrndpoints, /**< maximum number of random points to compute */
141 SCIP_Real maxboundsize, /**< maximum variable domain size for unbounded variables */
142 SCIP_RANDNUMGEN* randnumgen, /**< random number generator */
143 SCIP_Real bestobj, /**< objective value in the transformed space of the current incumbent */
144 int* nstored /**< pointer to store the number of randomly generated points */
145 )
146{
147 SCIP_VAR** vars;
148 SCIP_SOL* sol;
149 SCIP_Real val;
150 SCIP_Real lb;
151 SCIP_Real ub;
152 int nvars;
153 int niter;
154 int i;
155
156 assert(scip != NULL);
157 assert(rndpoints != NULL);
158 assert(nmaxrndpoints > 0);
159 assert(maxboundsize > 0.0);
160 assert(randnumgen != NULL);
161 assert(nstored != NULL);
162
163 vars = SCIPgetVars(scip);
164 nvars = SCIPgetNVars(scip);
165 *nstored = 0;
166
167 SCIP_CALL( SCIPcreateSol(scip, &sol, NULL) );
168
169 for( niter = 0; niter < 3 * nmaxrndpoints && *nstored < nmaxrndpoints; ++niter )
170 {
171 /* reset solution, in case the old one had infinite objective, which can give difficulties in updating the obj value */
172 SCIP_CALL( SCIPclearSol(scip, sol) );
173
174 for( i = 0; i < nvars; ++i )
175 {
176 lb = MIN(SCIPvarGetLbLocal(vars[i]), SCIPvarGetUbLocal(vars[i])); /*lint !e666*/
177 ub = MAX(SCIPvarGetLbLocal(vars[i]), SCIPvarGetUbLocal(vars[i])); /*lint !e666*/
178
179 if( SCIPisFeasEQ(scip, lb, ub) )
180 val = (lb + ub) / 2.0;
181 /* use a smaller domain for unbounded variables */
182 else if( !SCIPisInfinity(scip, -lb) && !SCIPisInfinity(scip, ub) )
183 val = SCIPrandomGetReal(randnumgen, lb, ub);
184 else if( !SCIPisInfinity(scip, -lb) )
185 val = lb + SCIPrandomGetReal(randnumgen, 0.0, maxboundsize);
186 else if( !SCIPisInfinity(scip, ub) )
187 val = ub - SCIPrandomGetReal(randnumgen, 0.0, maxboundsize);
188 else
189 {
190 assert(SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub));
191 val = SCIPrandomGetReal(randnumgen, -0.5*maxboundsize, 0.5*maxboundsize);
192 }
193 assert(SCIPisFeasGE(scip, val, lb) && SCIPisFeasLE(scip, val, ub));
194
195 /* set solution value; round the sampled point for integer variables */
196 if( SCIPvarIsIntegral(vars[i]) )
197 val = SCIPfeasRound(scip, val);
198 SCIP_CALL( SCIPsetSolVal(scip, sol, vars[i], val) );
199 }
200
201 /* add solution if it is good enough */
202 if( SCIPisLE(scip, SCIPgetSolTransObj(scip, sol), bestobj) )
203 {
204 SCIP_CALL( SCIPcreateSolCopy(scip, &rndpoints[*nstored], sol) );
205 ++(*nstored);
206 }
207 }
208 assert(*nstored <= nmaxrndpoints);
209 SCIPdebugMsg(scip, "found %d randomly generated points\n", *nstored);
210
211 SCIP_CALL( SCIPfreeSol(scip, &sol) );
212
213 return SCIP_OKAY;
214}
215
216/** computes the minimum feasibility of a given point; a negative value means that there is an infeasibility */
217static
219 SCIP* scip, /**< SCIP data structure */
220 SCIP_NLROW** nlrows, /**< array containing all nlrows */
221 int nnlrows, /**< total number of nlrows */
222 SCIP_SOL* sol, /**< solution */
223 SCIP_Real* minfeas /**< buffer to store the minimum feasibility */
224 )
225{
226 SCIP_Real tmp;
227 int i;
228
229 assert(scip != NULL);
230 assert(sol != NULL);
231 assert(minfeas != NULL);
232 assert(nlrows != NULL);
233 assert(nnlrows > 0);
234
235 *minfeas = SCIPinfinity(scip);
236
237 for( i = 0; i < nnlrows; ++i )
238 {
239 assert(nlrows[i] != NULL);
240
241 SCIP_CALL( SCIPgetNlRowSolFeasibility(scip, nlrows[i], sol, &tmp) );
242 if( tmp == SCIP_INVALID ) /*lint !e777*/
243 {
244 *minfeas = -SCIPinfinity(scip);
245 return SCIP_OKAY;
246 }
247 *minfeas = MIN(*minfeas, tmp);
248 }
249
250 return SCIP_OKAY;
251}
252
253/** computes the gradient for a given point and nonlinear row */
254static
256 SCIP* scip, /**< SCIP data structure */
257 SCIP_NLROW* nlrow, /**< nonlinear row */
258 SCIP_SOL* sol, /**< solution to compute the gradient for */
259 SCIP_HASHMAP* varindex, /**< maps variables to indicies between 0,..,SCIPgetNVars(scip)-1 uniquely */
260 SCIP_EXPRITER* exprit, /**< expression iterator that can be used */
261 SCIP_Real* grad, /**< buffer to store the gradient; grad[varindex(i)] corresponds to SCIPgetVars(scip)[i] */
262 SCIP_Real* norm /**< buffer to store ||grad||^2, or SCIP_INVALID if function not differentiable */
263 )
264{
265 SCIP_EXPR* expr;
266 SCIP_VAR* var;
267 int i;
268
269 assert(scip != NULL);
270 assert(nlrow != NULL);
271 assert(varindex != NULL);
272 assert(sol != NULL);
273 assert(norm != NULL);
274
276 *norm = 0.0;
277
278 /* linear part */
279 for( i = 0; i < SCIPnlrowGetNLinearVars(nlrow); i++ )
280 {
281 var = SCIPnlrowGetLinearVars(nlrow)[i];
282 assert(var != NULL);
283 assert(getVarIndex(varindex, var) >= 0 && getVarIndex(varindex, var) < SCIPgetNVars(scip));
284
285 grad[getVarIndex(varindex, var)] += SCIPnlrowGetLinearCoefs(nlrow)[i];
286 }
287
288 /* expression part */
289 expr = SCIPnlrowGetExpr(nlrow);
290
291 if( expr != NULL )
292 {
293 assert(exprit != NULL);
294
295 SCIP_CALL( SCIPevalExprGradient(scip, expr, sol, 0L) );
296
297 /* TODO: change this when nlrows store the vars */
299 for( ; !SCIPexpriterIsEnd(exprit); expr = SCIPexpriterGetNext(exprit) ) /*lint !e441*/ /*lint !e440*/
300 {
301 if( !SCIPisExprVar(scip, expr) )
302 continue;
303
304 var = SCIPgetVarExprVar(expr);
305 assert(var != NULL);
306 assert(getVarIndex(varindex, var) >= 0 && getVarIndex(varindex, var) < SCIPgetNVars(scip));
307
308 if( SCIPexprGetDerivative(expr) == SCIP_INVALID ) /*lint !e777*/
309 {
310 *norm = SCIP_INVALID;
311 return SCIP_OKAY;
312 }
313
314 grad[getVarIndex(varindex, var)] += SCIPexprGetDerivative(expr);
315 }
316 }
317
318 /* compute ||grad||^2 */
319 for( i = 0; i < SCIPgetNVars(scip); ++i )
320 *norm += SQR(grad[i]);
321
322 return SCIP_OKAY;
323}
324
325/** use consensus vectors to improve feasibility for a given starting point */
326static
328 SCIP* scip, /**< SCIP data structure */
329 SCIP_NLROW** nlrows, /**< array containing all nlrows */
330 int nnlrows, /**< total number of nlrows */
331 SCIP_HASHMAP* varindex, /**< maps variables to indicies between 0,..,SCIPgetNVars(scip)-1 */
332 SCIP_SOL* point, /**< random generated point */
333 int maxiter, /**< maximum number of iterations */
334 SCIP_Real minimprfac, /**< minimum required improving factor to proceed in the improvement of a single point */
335 int minimpriter, /**< number of iteration when checking the minimum improvement */
336 SCIP_Real* minfeas, /**< pointer to store the minimum feasibility */
337 SCIP_Real* nlrowgradcosts, /**< estimated costs for each gradient computation */
338 SCIP_Real* gradcosts /**< pointer to store the estimated gradient costs */
339 )
340{
341 SCIP_VAR** vars;
342 SCIP_EXPRITER* exprit;
343 SCIP_Real* grad;
344 SCIP_Real* updatevec;
345 SCIP_Real lastminfeas;
346 int nvars;
347 int r;
348 int i;
349
350 assert(varindex != NULL);
351 assert(point != NULL);
352 assert(maxiter > 0);
353 assert(minfeas != NULL);
354 assert(nlrows != NULL);
355 assert(nnlrows > 0);
356 assert(nlrowgradcosts != NULL);
357 assert(gradcosts != NULL);
358
359 *gradcosts = 0.0;
360
361 SCIP_CALL( getMinFeas(scip, nlrows, nnlrows, point, minfeas) );
362#ifdef SCIP_DEBUG_IMPROVEPOINT
363 printf("start minfeas = %e\n", *minfeas);
364#endif
365
366 /* stop since start point is feasible */
367 if( !SCIPisFeasLT(scip, *minfeas, 0.0) )
368 {
369#ifdef SCIP_DEBUG_IMPROVEPOINT
370 printf("start point is feasible");
371#endif
372 return SCIP_OKAY;
373 }
374
375 lastminfeas = *minfeas;
376 vars = SCIPgetVars(scip);
377 nvars = SCIPgetNVars(scip);
378
379 SCIP_CALL( SCIPallocBufferArray(scip, &grad, nvars) );
380 SCIP_CALL( SCIPallocBufferArray(scip, &updatevec, nvars) );
381 SCIP_CALL( SCIPcreateExpriter(scip, &exprit) );
382
383 /* main loop */
384 for( r = 0; r < maxiter && SCIPisFeasLT(scip, *minfeas, 0.0); ++r )
385 {
386 SCIP_Real feasibility;
387 SCIP_Real activity;
388 SCIP_Real nlrownorm;
389 SCIP_Real scale;
390 int nviolnlrows;
391
392 BMSclearMemoryArray(updatevec, nvars);
393 nviolnlrows = 0;
394
395 for( i = 0; i < nnlrows; ++i )
396 {
397 int j;
398
399 SCIP_CALL( SCIPgetNlRowSolFeasibility(scip, nlrows[i], point, &feasibility) );
400
401 if( feasibility == SCIP_INVALID ) /*lint !e777*/
402 {
403#ifdef SCIP_DEBUG_IMPROVEPOINT
404 printf("nlrow cannot be evaluated at current point -> skip nlrow\n");
405#endif
406 continue;
407 }
408
409 /* do not consider non-violated constraints */
410 if( SCIPisFeasGE(scip, feasibility, 0.0) )
411 continue;
412
413 SCIP_CALL( computeGradient(scip, nlrows[i], point, varindex, exprit, grad, &nlrownorm) );
414
415 /* update estimated costs for computing gradients */
416 *gradcosts += nlrowgradcosts[i];
417
418 /* skip nlrow if gradient is not available at the current point */
419 if( nlrownorm == SCIP_INVALID ) /*lint !e777*/
420 {
421#ifdef SCIP_DEBUG_IMPROVEPOINT
422 printf("gradient not available at current point -> skip nlrow\n");
423#endif
424 continue;
425 }
426
427 /* increase number of violated differentiable nlrows */
428 ++nviolnlrows;
429
430 /* stop if the gradient disappears at the current point */
431 if( SCIPisZero(scip, nlrownorm) )
432 {
433#ifdef SCIP_DEBUG_IMPROVEPOINT
434 printf("gradient vanished at current point -> stop\n");
435#endif
436 goto TERMINATE;
437 }
438
439 SCIP_CALL( SCIPgetNlRowSolActivity(scip, nlrows[i], point, &activity) );
440 assert(activity != SCIP_INVALID); /*lint !e777*/
441
442 /* compute -g(x_k) / ||grad(g)(x_k)||^2 for a constraint g(x_k) <= 0 */
443 scale = -feasibility / nlrownorm;
444 if( !SCIPisInfinity(scip, SCIPnlrowGetRhs(nlrows[i])) && SCIPisGT(scip, activity, SCIPnlrowGetRhs(nlrows[i])) )
445 scale *= -1.0;
446
447 /* skip nonlinear row if the scale is too small or too large */
448 if( SCIPisEQ(scip, scale, 0.0) || SCIPisHugeValue(scip, REALABS(scale)) )
449 continue;
450
451 for( j = 0; j < nvars; ++j )
452 updatevec[j] += scale * grad[j];
453 }
454
455 /* if there are no violated differentiable rows, stop since start point is feasible or we have no direction for improvement */
456 if( nviolnlrows == 0 )
457 {
458 assert(updatevec[i] == 0.0);
459 goto TERMINATE;
460 }
461
462 for( i = 0; i < nvars; ++i )
463 {
464 /* adjust point */
465 updatevec[i] = SCIPgetSolVal(scip, point, vars[i]) + updatevec[i] / nviolnlrows;
466 updatevec[i] = MIN(updatevec[i], SCIPvarGetUbLocal(vars[i])); /*lint !e666*/
467 updatevec[i] = MAX(updatevec[i], SCIPvarGetLbLocal(vars[i])); /*lint !e666*/
468
469 SCIP_CALL( SCIPsetSolVal(scip, point, vars[i], updatevec[i]) );
470 }
471
472 /* update feasibility */
473 SCIP_CALL( getMinFeas(scip, nlrows, nnlrows, point, minfeas) );
474
475 /* check stopping criterion */
476 if( r % minimpriter == 0 && r > 0 )
477 {
478 if( *minfeas <= MINFEAS
479 || (*minfeas-lastminfeas) / MAX(REALABS(*minfeas), REALABS(lastminfeas)) < minimprfac ) /*lint !e666*/
480 break;
481 lastminfeas = *minfeas;
482 }
483 }
484
485TERMINATE:
486#ifdef SCIP_DEBUG_IMPROVEPOINT
487 printf("niter=%d minfeas=%e\n", r, *minfeas);
488#endif
489
490 SCIPfreeExpriter(&exprit);
491
492 SCIPfreeBufferArray(scip, &updatevec);
494
495 return SCIP_OKAY;
496}
497
498/** sorts points w.r.t their feasibilities; points with a feasibility which is too small (w.r.t. the geometric mean of
499 * all feasibilities) will be filtered out
500 */
501static
503 SCIP* scip, /**< SCIP data structure */
504 SCIP_SOL** points, /**< array containing improved points */
505 SCIP_Real* feasibilities, /**< array containing feasibility for each point (sorted) */
506 int npoints, /**< total number of points */
507 int* nusefulpoints /**< pointer to store the total number of useful points */
508 )
509{
510 SCIP_Real minfeas;
511 SCIP_Real meanfeas;
512 int i;
513
514 assert(points != NULL);
515 assert(feasibilities != NULL);
516 assert(npoints > 0);
517 assert(nusefulpoints != NULL);
518
519 /* sort points w.r.t their feasibilities; non-negative feasibility correspond to feasible points for the NLP */
520 SCIPsortDownRealPtr(feasibilities, (void**)points, npoints);
521 minfeas = feasibilities[npoints - 1];
522
523 /* check if all points are feasible */
524 if( SCIPisFeasGE(scip, minfeas, 0.0) )
525 {
526 *nusefulpoints = npoints;
527 return SCIP_OKAY;
528 }
529
530 *nusefulpoints = 0;
531
532 /* compute shifted geometric mean of feasibilities (shift value = 1 - minfeas) */
533 meanfeas = 1.0;
534 for( i = 0; i < npoints; ++i )
535 {
536 assert(feasibilities[i] - minfeas + 1.0 > 0.0);
537 meanfeas *= pow(feasibilities[i] - minfeas + 1.0, 1.0 / npoints);
538 }
539 meanfeas += minfeas - 1.0;
540 SCIPdebugMsg(scip, "meanfeas = %e\n", meanfeas);
541
542 /* keep all points with which have a feasibility not much below the geometric mean of infeasibilities */
543 for( i = 0; i < npoints; ++i )
544 {
545 if( SCIPisFeasLT(scip, feasibilities[i], 0.0)
546 && (feasibilities[i] <= 1.05 * meanfeas || SCIPisLE(scip, feasibilities[i], MINFEAS)) )
547 break;
548
549 ++(*nusefulpoints);
550 }
551
552 return SCIP_OKAY;
553}
554
555/** returns the relative distance between two points; considers a smaller bounded domain for unbounded variables */
556static
558 SCIP* scip, /**< SCIP data structure */
559 SCIP_SOL* x, /**< first point */
560 SCIP_SOL* y, /**< second point */
561 SCIP_Real maxboundsize /**< maximum variable domain size for unbounded variables */
562 )
563{
564 SCIP_VAR** vars;
565 int nvars;
566 SCIP_Real distance;
567 SCIP_Real solx;
568 SCIP_Real soly;
569 SCIP_Real lb;
570 SCIP_Real ub;
571 int i;
572
573 assert(x != NULL);
574 assert(y != NULL);
575
576 vars = SCIPgetVars(scip);
577 nvars = SCIPgetNVars(scip);
578 distance = 0.0;
579
580 if( nvars == 0 )
581 return 0.0;
582
583 for( i = 0; i < nvars; ++i )
584 {
585 lb = SCIPvarGetLbLocal(vars[i]);
586 ub = SCIPvarGetUbLocal(vars[i]);
587 solx = SCIPgetSolVal(scip, x, vars[i]);
588 soly = SCIPgetSolVal(scip, y, vars[i]);
589
590 /* adjust lower and upper bounds for unbounded variables*/
591 if( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
592 {
593 lb = -maxboundsize / 2.0;
594 ub = +maxboundsize / 2.0;
595 }
596 else if( SCIPisInfinity(scip, -lb) )
597 {
598 lb = ub - maxboundsize;
599 }
600 else if( SCIPisInfinity(scip, ub) )
601 {
602 ub = lb + maxboundsize;
603 }
604
605 /* project solution values to the variable domain */
606 solx = MIN(MAX(solx, lb), ub);
607 soly = MIN(MAX(soly, lb), ub);
608
609 distance += REALABS(solx - soly) / MAX(1.0, ub - lb);
610 }
611
612 return distance / nvars;
613}
614
615/** cluster useful points with a greedy algorithm */
616static
618 SCIP* scip, /**< SCIP data structure */
619 SCIP_SOL** points, /**< array containing improved points */
620 int npoints, /**< total number of points */
621 int* clusteridx, /**< array to store for each point the index of the cluster */
622 int* ncluster, /**< pointer to store the total number of cluster */
623 SCIP_Real maxboundsize, /**< maximum variable domain size for unbounded variables */
624 SCIP_Real maxreldist, /**< maximum relative distance between any two points of the same cluster */
625 int maxncluster /**< maximum number of clusters to compute */
626 )
627{
628 int i;
629
630 assert(points != NULL);
631 assert(npoints > 0);
632 assert(clusteridx != NULL);
633 assert(ncluster != NULL);
634 assert(maxreldist >= 0.0);
635 assert(maxncluster >= 0);
636
637 /* initialize cluster indices */
638 for( i = 0; i < npoints; ++i )
639 clusteridx[i] = INT_MAX;
640
641 *ncluster = 0;
642
643 for( i = 0; i < npoints && (*ncluster < maxncluster); ++i )
644 {
645 int j;
646
647 /* point is already assigned to a cluster */
648 if( clusteridx[i] != INT_MAX )
649 continue;
650
651 /* create a new cluster for i */
652 clusteridx[i] = *ncluster;
653
654 for( j = i + 1; j < npoints; ++j )
655 {
656 if( clusteridx[j] == INT_MAX && getRelDistance(scip, points[i], points[j], maxboundsize) <= maxreldist )
657 clusteridx[j] = *ncluster;
658 }
659
660 ++(*ncluster);
661 }
662
663#ifndef NDEBUG
664 for( i = 0; i < npoints; ++i )
665 {
666 assert(clusteridx[i] >= 0);
667 assert(clusteridx[i] < *ncluster || clusteridx[i] == INT_MAX);
668 }
669#endif
670
671 return SCIP_OKAY;
672}
673
674/** calls the sub-NLP heuristic for a given cluster */
675static
677 SCIP* scip, /**< SCIP data structure */
678 SCIP_HEUR* heur, /**< multi-start heuristic */
679 SCIP_HEUR* nlpheur, /**< pointer to NLP local search heuristics */
680 SCIP_SOL** points, /**< array containing improved points */
681 int npoints, /**< total number of points */
682 SCIP_Bool* success /**< pointer to store if we could find a solution */
683 )
684{
685 SCIP_VAR** vars;
686 SCIP_SOL* refpoint;
687 SCIP_RESULT nlpresult;
688 SCIP_Real val;
689 int nbinvars;
690 int nintvars;
691 int nvars;
692 int i;
693
694 assert(points != NULL);
695 assert(npoints > 0);
696
697 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, &nintvars, NULL, NULL) );
698 *success = FALSE;
699
700 SCIP_CALL( SCIPcreateSol(scip, &refpoint, heur) );
701
702 /* compute reference point */
703 for( i = 0; i < nvars; ++i )
704 {
705 int p;
706
707 val = 0.0;
708
709 for( p = 0; p < npoints; ++p )
710 {
711 assert(points[p] != NULL);
712 val += SCIPgetSolVal(scip, points[p], vars[i]);
713 }
714
715 SCIP_CALL( SCIPsetSolVal(scip, refpoint, vars[i], val / npoints) );
716 }
717
718 /* round point for sub-NLP heuristic */
719 SCIP_CALL( SCIProundSol(scip, refpoint, success) );
720 SCIPdebugMsg(scip, "rounding of refpoint successfully? %u\n", *success);
721
722 /* round variables manually if the locks did not allow us to round them */
723 if( !(*success) )
724 {
725 for( i = 0; i < nbinvars + nintvars; ++i )
726 {
727 val = SCIPgetSolVal(scip, refpoint, vars[i]);
728
729 if( !SCIPisFeasIntegral(scip, val) )
730 {
731 assert(SCIPisFeasIntegral(scip, SCIPvarGetLbLocal(vars[i])));
732 assert(SCIPisFeasIntegral(scip, SCIPvarGetUbLocal(vars[i])));
733
734 /* round and adjust value */
735 val = SCIPround(scip, val);
736 val = MIN(val, SCIPvarGetUbLocal(vars[i])); /*lint !e666*/
737 val = MAX(val, SCIPvarGetLbLocal(vars[i])); /*lint !e666*/
738 assert(SCIPisFeasIntegral(scip, val));
739
740 SCIP_CALL( SCIPsetSolVal(scip, refpoint, vars[i], val) );
741 }
742 }
743 }
744
745 /* call sub-NLP heuristic */
746 SCIP_CALL( SCIPapplyHeurSubNlp(scip, nlpheur, &nlpresult, refpoint, NULL) );
747 SCIP_CALL( SCIPfreeSol(scip, &refpoint) );
748
749 /* let sub-NLP heuristic decide whether the solution is feasible or not */
750 *success = nlpresult == SCIP_FOUNDSOL;
751
752 return SCIP_OKAY;
753}
754
755/** recursive helper function to count the number of nodes in a sub-expr */
756static
758 SCIP_EXPR* expr /**< expression */
759 )
760{
761 int sum;
762 int i;
763
764 assert(expr != NULL);
765
766 sum = 0;
767 for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
768 {
769 SCIP_EXPR* child = SCIPexprGetChildren(expr)[i];
770 sum += getExprSize(child);
771 }
772 return 1 + sum;
773}
774
775/** main function of the multi-start heuristic (see @ref heur_multistart.h for more details); it consists of the
776 * following four steps:
777 *
778 * 1. sampling points in the current domain; for unbounded variables we use a bounded box
779 *
780 * 2. reduce infeasibility by using a gradient descent method
781 *
782 * 3. cluster points; filter points with a too large infeasibility
783 *
784 * 4. compute start point for each cluster and use it in the sub-NLP heuristic (@ref heur_subnlp.h)
785 */
786static
788 SCIP* scip, /**< SCIP data structure */
789 SCIP_HEUR* heur, /**< heuristic */
790 SCIP_HEURDATA* heurdata, /**< heuristic data */
791 SCIP_RESULT* result /**< pointer to store the result */
792 )
793{
794 SCIP_NLROW** nlrows;
795 SCIP_SOL** points;
796 SCIP_HASHMAP* varindex;
797 SCIP_Real* feasibilities;
798 SCIP_Real* nlrowgradcosts;
799 int* clusteridx;
800 SCIP_Real gradlimit;
801 SCIP_Real bestobj;
802 int nusefulpoints;
803 int nrndpoints;
804 int ncluster;
805 int nnlrows;
806 int npoints;
807 int start;
808 int i;
809
810 assert(scip != NULL);
811 assert(heur != NULL);
812 assert(result != NULL);
813 assert(heurdata != NULL);
814
815 SCIPdebugMsg(scip, "call applyHeur()\n");
816
817 nlrows = SCIPgetNLPNlRows(scip);
818 nnlrows = SCIPgetNNLPNlRows(scip);
820
821 SCIP_CALL( SCIPallocBufferArray(scip, &points, heurdata->nrndpoints) );
822 SCIP_CALL( SCIPallocBufferArray(scip, &nlrowgradcosts, nnlrows) );
823 SCIP_CALL( SCIPallocBufferArray(scip, &feasibilities, heurdata->nrndpoints) );
824 SCIP_CALL( SCIPallocBufferArray(scip, &clusteridx, heurdata->nrndpoints) );
826
827 /* create an unique mapping of all variables to 0,..,SCIPgetNVars(scip)-1 */
828 for( i = 0; i < SCIPgetNVars(scip); ++i )
829 {
830 SCIP_CALL( SCIPhashmapInsertInt(varindex, (void*)SCIPgetVars(scip)[i], i) );
831 }
832
833 /* compute estimated costs of computing a gradient for each nlrow */
834 for( i = 0; i < nnlrows; ++i )
835 {
836 nlrowgradcosts[i] = GRADCOSTFAC_LINEAR * SCIPnlrowGetNLinearVars(nlrows[i]);
837 if( SCIPnlrowGetExpr(nlrows[i]) != NULL )
838 nlrowgradcosts[i] += GRADCOSTFAC_NONLINEAR * getExprSize(SCIPnlrowGetExpr(nlrows[i]));
839 }
840
841 /*
842 * 1. sampling points in the current domain; for unbounded variables we use a bounded box
843 */
844 SCIP_CALL( sampleRandomPoints(scip, points, heurdata->nrndpoints, heurdata->maxboundsize, heurdata->randnumgen,
845 bestobj, &nrndpoints) );
846 assert(nrndpoints >= 0);
847
848 if( nrndpoints == 0 )
849 goto TERMINATE;
850
851 /*
852 * 2. improve points via consensus vectors
853 */
854 gradlimit = heurdata->gradlimit == 0.0 ? SCIPinfinity(scip) : heurdata->gradlimit;
855 for( npoints = 0; npoints < nrndpoints && gradlimit >= 0 && !SCIPisStopped(scip); ++npoints )
856 {
857 SCIP_Real gradcosts;
858
859 SCIP_CALL( improvePoint(scip, nlrows, nnlrows, varindex, points[npoints],
860 heurdata->maxiter, heurdata->minimprfac, heurdata->minimpriter, &feasibilities[npoints], nlrowgradcosts,
861 &gradcosts) );
862
863 gradlimit -= gradcosts;
864 SCIPdebugMsg(scip, "improve point %d / %d gradlimit = %g\n", npoints, nrndpoints, gradlimit);
865 }
866 assert(npoints >= 0 && npoints <= nrndpoints);
867
868 if( npoints == 0 )
869 goto TERMINATE;
870
871 /*
872 * 3. filter and cluster points
873 */
874 SCIP_CALL( filterPoints(scip, points, feasibilities, npoints, &nusefulpoints) );
875 assert(nusefulpoints >= 0);
876 SCIPdebugMsg(scip, "nusefulpoints = %d\n", nusefulpoints);
877
878 if( nusefulpoints == 0 )
879 goto TERMINATE;
880
881 SCIP_CALL( clusterPointsGreedy(scip, points, nusefulpoints, clusteridx, &ncluster, heurdata->maxboundsize,
882 heurdata->maxreldist, heurdata->maxncluster) );
883 assert(ncluster >= 0 && ncluster <= heurdata->maxncluster);
884 SCIPdebugMsg(scip, "ncluster = %d\n", ncluster);
885
886 SCIPsortIntPtr(clusteridx, (void**)points, nusefulpoints);
887
888 /*
889 * 4. compute start point for each cluster and use it in the sub-NLP heuristic (@ref heur_subnlp.h)
890 */
891 start = 0;
892 while( start < nusefulpoints && clusteridx[start] != INT_MAX && !SCIPisStopped(scip) )
893 {
894 SCIP_Bool success;
895 int end;
896
897 end = start;
898 while( end < nusefulpoints && clusteridx[start] == clusteridx[end] )
899 ++end;
900
901 assert(end - start > 0);
902
903 /* call sub-NLP heuristic */
904 SCIP_CALL( solveNLP(scip, heur, heurdata->heursubnlp, &points[start], end - start, &success) );
905 SCIPdebugMsg(scip, "solveNLP result = %u\n", success);
906
907 if( success )
908 *result = SCIP_FOUNDSOL;
909
910 /* go to the next cluster */
911 start = end;
912 }
913
914TERMINATE:
915 /* free memory */
916 for( i = nrndpoints - 1; i >= 0 ; --i )
917 {
918 assert(points[i] != NULL);
919 SCIP_CALL( SCIPfreeSol(scip, &points[i]) );
920 }
921
922 SCIPhashmapFree(&varindex);
923 SCIPfreeBufferArray(scip, &clusteridx);
924 SCIPfreeBufferArray(scip, &feasibilities);
925 SCIPfreeBufferArray(scip, &nlrowgradcosts);
926 SCIPfreeBufferArray(scip, &points);
927
928 return SCIP_OKAY;
929}
930
931/*
932 * Callback methods of primal heuristic
933 */
934
935/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
936static
937SCIP_DECL_HEURCOPY(heurCopyMultistart)
938{ /*lint --e{715}*/
939 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
940
941 /* call inclusion method of primal heuristic */
943
944 return SCIP_OKAY;
945}
946
947/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
948static
949SCIP_DECL_HEURFREE(heurFreeMultistart)
950{ /*lint --e{715}*/
951 SCIP_HEURDATA* heurdata;
952
953 /* free heuristic data */
954 heurdata = SCIPheurGetData(heur);
955
956 SCIPfreeBlockMemory(scip, &heurdata);
957 SCIPheurSetData(heur, NULL);
958
959 return SCIP_OKAY;
960}
961
962/** initialization method of primal heuristic (called after problem was transformed) */
963static
964SCIP_DECL_HEURINIT(heurInitMultistart)
965{ /*lint --e{715}*/
966 SCIP_HEURDATA* heurdata;
967
968 assert( heur != NULL );
969
970 heurdata = SCIPheurGetData(heur);
971 assert(heurdata != NULL);
972
973 SCIP_CALL( SCIPcreateRandom(scip, &heurdata->randnumgen,
975
976 /* try to find sub-NLP heuristic */
977 heurdata->heursubnlp = SCIPfindHeur(scip, "subnlp");
978
979 return SCIP_OKAY;
980}
981
982/** deinitialization method of primal heuristic (called before transformed problem is freed) */
983static
984SCIP_DECL_HEUREXIT(heurExitMultistart)
985{ /*lint --e{715}*/
986 SCIP_HEURDATA* heurdata;
987
988 assert( heur != NULL );
989
990 heurdata = SCIPheurGetData(heur);
991 assert(heurdata != NULL);
992 assert(heurdata->randnumgen != NULL);
993
994 SCIPfreeRandom(scip, &heurdata->randnumgen);
995
996 return SCIP_OKAY;
997}
998
999/** execution method of primal heuristic */
1000static
1001SCIP_DECL_HEUREXEC(heurExecMultistart)
1002{ /*lint --e{715}*/
1003 SCIP_HEURDATA* heurdata;
1004
1005 assert( heur != NULL );
1006
1007 heurdata = SCIPheurGetData(heur);
1008 assert(heurdata != NULL);
1009
1010 *result = SCIP_DIDNOTRUN;
1011
1012 /* check cases for which the heuristic is not applicable */
1013 if( !SCIPisNLPConstructed(scip) || heurdata->heursubnlp == NULL || SCIPgetNNlpis(scip) <= 0 )
1014 return SCIP_OKAY;
1015
1016 /* check whether the heuristic should be applied for a problem containing integer variables */
1017 if( heurdata->onlynlps && (SCIPgetNBinVars(scip) > 0 || SCIPgetNIntVars(scip) > 0) )
1018 return SCIP_OKAY;
1019
1020 *result = SCIP_DIDNOTFIND;
1021
1022 SCIP_CALL( applyHeur(scip, heur, heurdata, result) );
1023
1024 return SCIP_OKAY;
1025}
1026
1027/*
1028 * primal heuristic specific interface methods
1029 */
1030
1031/** creates the multistart primal heuristic and includes it in SCIP */
1033 SCIP* scip /**< SCIP data structure */
1034 )
1035{
1036 SCIP_HEURDATA* heurdata;
1037 SCIP_HEUR* heur;
1038
1039 /* create multistart primal heuristic data */
1040 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
1041 BMSclearMemory(heurdata);
1042
1043 /* include primal heuristic */
1046 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecMultistart, heurdata) );
1047
1048 assert(heur != NULL);
1049
1050 /* set non fundamental callbacks via setter functions */
1051 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyMultistart) );
1052 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeMultistart) );
1053 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitMultistart) );
1054 SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitMultistart) );
1055
1056 /* add multistart primal heuristic parameters */
1057 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/nrndpoints",
1058 "number of random points generated per execution call",
1059 &heurdata->nrndpoints, FALSE, DEFAULT_NRNDPOINTS, 0, INT_MAX, NULL, NULL) );
1060
1061 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/maxboundsize",
1062 "maximum variable domain size for unbounded variables",
1063 &heurdata->maxboundsize, FALSE, DEFAULT_MAXBOUNDSIZE, 0.0, SCIPinfinity(scip), NULL, NULL) );
1064
1065 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxiter",
1066 "number of iterations to reduce the maximum violation of a point",
1067 &heurdata->maxiter, FALSE, DEFAULT_MAXITER, 0, INT_MAX, NULL, NULL) );
1068
1069 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprfac",
1070 "minimum required improving factor to proceed in improvement of a single point",
1071 &heurdata->minimprfac, FALSE, DEFAULT_MINIMPRFAC, -SCIPinfinity(scip), SCIPinfinity(scip), NULL, NULL) );
1072
1073 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/minimpriter",
1074 "number of iteration when checking the minimum improvement",
1075 &heurdata->minimpriter, FALSE, DEFAULT_MINIMPRITER, 1, INT_MAX, NULL, NULL) );
1076
1077 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/maxreldist",
1078 "maximum distance between two points in the same cluster",
1079 &heurdata->maxreldist, FALSE, DEFAULT_MAXRELDIST, 0.0, SCIPinfinity(scip), NULL, NULL) );
1080
1081 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/gradlimit",
1082 "limit for gradient computations for all improvePoint() calls (0 for no limit)",
1083 &heurdata->gradlimit, FALSE, DEFAULT_GRADLIMIT, 0.0, SCIPinfinity(scip), NULL, NULL) );
1084
1085 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxncluster",
1086 "maximum number of considered clusters per heuristic call",
1087 &heurdata->maxncluster, FALSE, DEFAULT_MAXNCLUSTER, 0, INT_MAX, NULL, NULL) );
1088
1089 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/onlynlps",
1090 "should the heuristic run only on continuous problems?",
1091 &heurdata->onlynlps, FALSE, DEFAULT_ONLYNLPS, NULL, NULL) );
1092
1093 return SCIP_OKAY;
1094}
SCIP_VAR ** y
Definition: circlepacking.c:64
SCIP_Real * r
Definition: circlepacking.c:59
SCIP_VAR ** x
Definition: circlepacking.c:63
#define NULL
Definition: def.h:248
#define SCIP_INVALID
Definition: def.h:178
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:224
#define SCIP_Real
Definition: def.h:156
#define SQR(x)
Definition: def.h:199
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:220
#define REALABS(x)
Definition: def.h:182
#define SCIP_CALL(x)
Definition: def.h:355
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:759
int SCIPgetNIntVars(SCIP *scip)
Definition: scip_prob.c:2340
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip_prob.c:2115
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:2246
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:2201
int SCIPgetNBinVars(SCIP *scip)
Definition: scip_prob.c:2293
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3095
int SCIPhashmapGetImageInt(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3304
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3061
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3466
SCIP_RETCODE SCIPhashmapInsertInt(SCIP_HASHMAP *hashmap, void *origin, int image)
Definition: misc.c:3179
#define SCIPdebugMsg
Definition: scip_message.h:78
SCIP_RETCODE SCIPapplyHeurSubNlp(SCIP *scip, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_SOL *refpoint, SCIP_SOL *resultsol)
Definition: heur_subnlp.c:1762
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:83
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:139
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:57
SCIP_RETCODE SCIPincludeHeurMultistart(SCIP *scip)
int SCIPexprGetNChildren(SCIP_EXPR *expr)
Definition: expr.c:3872
SCIP_RETCODE SCIPevalExprGradient(SCIP *scip, SCIP_EXPR *expr, SCIP_SOL *sol, SCIP_Longint soltag)
Definition: scip_expr.c:1692
SCIP_Bool SCIPexpriterIsEnd(SCIP_EXPRITER *iterator)
Definition: expriter.c:969
SCIP_Real SCIPexprGetDerivative(SCIP_EXPR *expr)
Definition: expr.c:3972
SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1457
SCIP_RETCODE SCIPcreateExpriter(SCIP *scip, SCIP_EXPRITER **iterator)
Definition: scip_expr.c:2362
SCIP_EXPR * SCIPexpriterGetNext(SCIP_EXPRITER *iterator)
Definition: expriter.c:858
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
Definition: expr.c:3882
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition: expr_var.c:424
void SCIPfreeExpriter(SCIP_EXPRITER **iterator)
Definition: scip_expr.c:2376
SCIP_RETCODE SCIPexpriterInit(SCIP_EXPRITER *iterator, SCIP_EXPR *expr, SCIP_EXPRITER_TYPE type, SCIP_Bool allowrevisit)
Definition: expriter.c:501
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: scip_heur.c:167
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1368
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:122
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip_heur.c:183
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
Definition: scip_heur.c:215
SCIP_HEUR * SCIPfindHeur(SCIP *scip, const char *name)
Definition: scip_heur.c:263
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
Definition: scip_heur.c:199
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1467
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1378
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:89
int SCIPgetNNlpis(SCIP *scip)
Definition: scip_nlpi.c:205
SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
Definition: scip_nlp.c:110
int SCIPgetNNLPNlRows(SCIP *scip)
Definition: scip_nlp.c:341
SCIP_NLROW ** SCIPgetNLPNlRows(SCIP *scip)
Definition: scip_nlp.c:319
SCIP_Real SCIPnlrowGetRhs(SCIP_NLROW *nlrow)
Definition: nlp.c:1914
SCIP_RETCODE SCIPgetNlRowSolFeasibility(SCIP *scip, SCIP_NLROW *nlrow, SCIP_SOL *sol, SCIP_Real *feasibility)
Definition: scip_nlp.c:1558
int SCIPnlrowGetNLinearVars(SCIP_NLROW *nlrow)
Definition: nlp.c:1864
SCIP_VAR ** SCIPnlrowGetLinearVars(SCIP_NLROW *nlrow)
Definition: nlp.c:1874
SCIP_EXPR * SCIPnlrowGetExpr(SCIP_NLROW *nlrow)
Definition: nlp.c:1894
SCIP_Real * SCIPnlrowGetLinearCoefs(SCIP_NLROW *nlrow)
Definition: nlp.c:1884
SCIP_RETCODE SCIPgetNlRowSolActivity(SCIP *scip, SCIP_NLROW *nlrow, SCIP_SOL *sol, SCIP_Real *activity)
Definition: scip_nlp.c:1522
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition: scip_sol.c:2981
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:516
SCIP_RETCODE SCIPcreateSolCopy(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol)
Definition: scip_sol.c:884
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:1252
SCIP_RETCODE SCIPclearSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1475
int SCIPgetNSols(SCIP *scip)
Definition: scip_sol.c:2882
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition: scip_sol.c:3123
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition: scip_sol.c:1571
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1765
SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:2005
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisHugeValue(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPround(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPfeasRound(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:24268
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:23490
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:24234
void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
Definition: misc.c:10245
SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
void SCIPsortIntPtr(int *intarray, void **ptrarray, int len)
void SCIPsortDownRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
static SCIP_Real getRelDistance(SCIP *scip, SCIP_SOL *x, SCIP_SOL *y, SCIP_Real maxboundsize)
static SCIP_RETCODE getMinFeas(SCIP *scip, SCIP_NLROW **nlrows, int nnlrows, SCIP_SOL *sol, SCIP_Real *minfeas)
#define HEUR_TIMING
#define HEUR_FREQOFS
#define HEUR_DESC
static SCIP_DECL_HEURCOPY(heurCopyMultistart)
#define GRADCOSTFAC_NONLINEAR
#define DEFAULT_ONLYNLPS
#define DEFAULT_MINIMPRFAC
#define DEFAULT_MAXNCLUSTER
#define DEFAULT_MINIMPRITER
#define HEUR_DISPCHAR
static SCIP_RETCODE sampleRandomPoints(SCIP *scip, SCIP_SOL **rndpoints, int nmaxrndpoints, SCIP_Real maxboundsize, SCIP_RANDNUMGEN *randnumgen, SCIP_Real bestobj, int *nstored)
#define HEUR_MAXDEPTH
#define HEUR_PRIORITY
static int getVarIndex(SCIP_HASHMAP *varindex, SCIP_VAR *var)
#define MINIMPRFAC
#define HEUR_NAME
static SCIP_DECL_HEUREXIT(heurExitMultistart)
static SCIP_RETCODE filterPoints(SCIP *scip, SCIP_SOL **points, SCIP_Real *feasibilities, int npoints, int *nusefulpoints)
static SCIP_DECL_HEURINIT(heurInitMultistart)
#define DEFAULT_RANDSEED
static SCIP_DECL_HEUREXEC(heurExecMultistart)
static SCIP_RETCODE improvePoint(SCIP *scip, SCIP_NLROW **nlrows, int nnlrows, SCIP_HASHMAP *varindex, SCIP_SOL *point, int maxiter, SCIP_Real minimprfac, int minimpriter, SCIP_Real *minfeas, SCIP_Real *nlrowgradcosts, SCIP_Real *gradcosts)
#define DEFAULT_MAXRELDIST
#define GRADCOSTFAC_LINEAR
static SCIP_RETCODE computeGradient(SCIP *scip, SCIP_NLROW *nlrow, SCIP_SOL *sol, SCIP_HASHMAP *varindex, SCIP_EXPRITER *exprit, SCIP_Real *grad, SCIP_Real *norm)
static SCIP_RETCODE applyHeur(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_RESULT *result)
#define DEFAULT_NRNDPOINTS
static SCIP_RETCODE solveNLP(SCIP *scip, SCIP_HEUR *heur, SCIP_HEUR *nlpheur, SCIP_SOL **points, int npoints, SCIP_Bool *success)
#define HEUR_FREQ
static SCIP_DECL_HEURFREE(heurFreeMultistart)
#define DEFAULT_GRADLIMIT
#define HEUR_USESSUBSCIP
static SCIP_RETCODE clusterPointsGreedy(SCIP *scip, SCIP_SOL **points, int npoints, int *clusteridx, int *ncluster, SCIP_Real maxboundsize, SCIP_Real maxreldist, int maxncluster)
#define MINFEAS
#define DEFAULT_MAXITER
static int getExprSize(SCIP_EXPR *expr)
#define DEFAULT_MAXBOUNDSIZE
multistart heuristic for convex and nonconvex MINLPs
NLP local search primal heuristic using sub-SCIPs.
memory allocation routines
#define BMSclearMemory(ptr)
Definition: memory.h:129
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
public functions to work with algebraic expressions
public methods for primal heuristics
public methods for message output
public data structures and miscellaneous methods
methods for sorting joint arrays of various types
public methods for NLP management
public methods for problem variables
public functions to work with algebraic expressions
general public methods
public methods for primal heuristic plugins and divesets
public methods for memory management
public methods for message handling
public methods for nonlinear relaxation
public methods for NLPI solver interfaces
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for random numbers
public methods for solutions
public methods for timing
@ SCIP_EXPRITER_DFS
Definition: type_expr.h:718
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:77
@ SCIP_DIDNOTRUN
Definition: type_result.h:42
@ SCIP_DIDNOTFIND
Definition: type_result.h:44
@ SCIP_FOUNDSOL
Definition: type_result.h:56
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:61
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63