SCIP Doxygen Documentation
Loading...
Searching...
No Matches
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-2026 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
165 *nstored = 0;
166
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 */
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 {
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
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;
378
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
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 {
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*/
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 )
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}*/
952
953 /* free heuristic data */
955
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}*/
967
968 assert( heur != NULL );
969
971 assert(heurdata != NULL);
972
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}*/
987
988 assert( heur != NULL );
989
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}*/
1004
1005 assert( heur != NULL );
1006
1007 heurdata = SCIPheurGetData(heur);
1008 assert(heurdata != NULL);
1009
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
1021
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{
1037 SCIP_HEUR* heur;
1038
1039 /* create multistart primal heuristic data */
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",
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
SCIP_VAR ** x
#define DEFAULT_RANDSEED
#define NULL
Definition def.h:255
#define SCIP_INVALID
Definition def.h:185
#define SCIP_Bool
Definition def.h:98
#define MIN(x, y)
Definition def.h:231
#define SCIP_Real
Definition def.h:163
#define SQR(x)
Definition def.h:206
#define TRUE
Definition def.h:100
#define FALSE
Definition def.h:101
#define MAX(x, y)
Definition def.h:227
#define REALABS(x)
Definition def.h:189
#define SCIP_CALL(x)
Definition def.h:362
SCIP_Bool SCIPisStopped(SCIP *scip)
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
SCIP_RETCODE SCIPapplyHeurSubNlp(SCIP *scip, SCIP_HEUR *heur, SCIP_RESULT *result, SCIP_SOL *refpoint, SCIP_SOL *resultsol)
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 SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:183
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 SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:167
SCIP_HEUR * SCIPfindHeur(SCIP *scip, const char *name)
Definition scip_heur.c:263
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:215
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur,)
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:2988
SCIP_RETCODE SCIPcreateSolCopy(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol)
Definition scip_sol.c:884
SCIP_RETCODE SCIPclearSol(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:1475
int SCIPgetNSols(SCIP *scip)
Definition scip_sol.c:2889
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition scip_sol.c:3130
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
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
Definition misc.c:10245
void SCIPsortIntPtr(int *intarray, void **ptrarray, int len)
void SCIPsortDownRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
#define HEUR_TIMING
return SCIP_OKAY
#define HEUR_FREQOFS
#define HEUR_DESC
#define HEUR_DISPCHAR
#define HEUR_MAXDEPTH
#define HEUR_PRIORITY
SCIPfreeSol(scip, &heurdata->sol))
#define HEUR_NAME
#define HEUR_FREQ
#define HEUR_USESSUBSCIP
SCIPcreateSol(scip, &heurdata->sol, heur))
SCIPfreeRandom(scip, &heurdata->randnumgen)
SCIPcreateRandom(scip, &heurdata->randnumgen, DEFAULT_RANDSEED, TRUE))
static SCIP_SOL * sol
int r
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
#define DEFAULT_MAXITER
Definition heur_mpec.c:75
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 GRADCOSTFAC_NONLINEAR
#define DEFAULT_ONLYNLPS
#define DEFAULT_MINIMPRFAC
#define DEFAULT_MAXNCLUSTER
#define DEFAULT_MINIMPRITER
static SCIP_RETCODE sampleRandomPoints(SCIP *scip, SCIP_SOL **rndpoints, int nmaxrndpoints, SCIP_Real maxboundsize, SCIP_RANDNUMGEN *randnumgen, SCIP_Real bestobj, int *nstored)
#define MINIMPRFAC
static SCIP_RETCODE filterPoints(SCIP *scip, SCIP_SOL **points, SCIP_Real *feasibilities, int npoints, int *nusefulpoints)
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 DEFAULT_GRADLIMIT
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
static int getExprSize(SCIP_EXPR *expr)
#define DEFAULT_MAXBOUNDSIZE
multistart heuristic for convex and nonconvex MINLPs
SCIP_VAR * var
static SCIP_VAR ** vars
NLP local search primal heuristic using sub-SCIPs.
#define getVarIndex(idx)
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
struct SCIP_Expr SCIP_EXPR
Definition type_expr.h:55
struct SCIP_ExprIter SCIP_EXPRITER
Definition type_expr.h:722
@ SCIP_EXPRITER_DFS
Definition type_expr.h:718
#define SCIP_DECL_HEURCOPY(x)
Definition type_heur.h:97
struct SCIP_HeurData SCIP_HEURDATA
Definition type_heur.h:77
struct SCIP_Heur SCIP_HEUR
Definition type_heur.h:76
#define SCIP_DECL_HEURINIT(x)
Definition type_heur.h:113
#define SCIP_DECL_HEUREXIT(x)
Definition type_heur.h:121
#define SCIP_DECL_HEURFREE(x)
Definition type_heur.h:105
#define SCIP_DECL_HEUREXEC(x)
Definition type_heur.h:163
struct SCIP_HashMap SCIP_HASHMAP
Definition type_misc.h:106
struct SCIP_RandNumGen SCIP_RANDNUMGEN
Definition type_misc.h:127
struct SCIP_NlRow SCIP_NLROW
Definition type_nlp.h:41
@ 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
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
struct SCIP_Var SCIP_VAR
Definition type_var.h:166