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
57
58#define HEUR_NAME "multistart"
59#define HEUR_DESC "multistart heuristic for convex and nonconvex MINLPs"
60#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
61#define HEUR_PRIORITY -2100000
62#define HEUR_FREQ 0
63#define HEUR_FREQOFS 0
64#define HEUR_MAXDEPTH -1
65#define HEUR_TIMING SCIP_HEURTIMING_AFTERNODE
66#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
67
68#define DEFAULT_RANDSEED 131 /**< initial random seed */
69#define DEFAULT_NRNDPOINTS 100 /**< default number of generated random points per call */
70#define DEFAULT_MAXBOUNDSIZE 2e+4 /**< default maximum variable domain size for unbounded variables */
71#define DEFAULT_MAXITER 300 /**< default number of iterations to reduce the violation of a point */
72#define DEFAULT_MINIMPRFAC 0.05 /**< default minimum required improving factor to proceed in improvement of a point */
73#define DEFAULT_MINIMPRITER 10 /**< default number of iteration when checking the minimum improvement */
74#define DEFAULT_MAXRELDIST 0.15 /**< default maximum distance between two points in the same cluster */
75#define DEFAULT_GRADLIMIT 5e+6 /**< default limit for gradient computations for all improvePoint() calls */
76#define DEFAULT_MAXNCLUSTER 3 /**< default maximum number of considered clusters per heuristic call */
77#define DEFAULT_ONLYNLPS TRUE /**< should the heuristic run only on continuous problems? */
78
79#define MINFEAS -1e+4 /**< minimum feasibility for a point; used for filtering and improving
80 * feasibility */
81#define MINIMPRFAC 0.95 /**< improvement factor used to discard randomly generated points with a
82 * too large objective value */
83#define GRADCOSTFAC_LINEAR 1.0 /**< gradient cost factor for the number of linear variables */
84#define GRADCOSTFAC_NONLINEAR 3.0 /**< gradient cost factor for the number of nodes in nonlinear expression */
85
86/*
87 * Data structures
88 */
89
90/** primal heuristic data */
91struct SCIP_HeurData
92{
93 int nrndpoints; /**< number of random points generated per execution call */
94 SCIP_Real maxboundsize; /**< maximum variable domain size for unbounded variables */
95 SCIP_RANDNUMGEN* randnumgen; /**< random number generator */
96 SCIP_HEUR* heursubnlp; /**< sub-NLP heuristic */
97
98 int maxiter; /**< number of iterations to reduce the maximum violation of a point */
99 SCIP_Real minimprfac; /**< minimum required improving factor to proceed in the improvement of a single point */
100 int minimpriter; /**< number of iteration when checking the minimum improvement */
101
102 SCIP_Real maxreldist; /**< maximum distance between two points in the same cluster */
103 SCIP_Real gradlimit; /**< limit for gradient computations for all improvePoint() calls (0 for no limit) */
104 int maxncluster; /**< maximum number of considered clusters per heuristic call */
105 SCIP_Bool onlynlps; /**< should the heuristic run only on continuous problems? */
106};
107
108
109/*
110 * Local methods
111 */
112
113
114/** returns an unique index of a variable in the range of 0,..,SCIPgetNVars(scip)-1 */
115#ifndef NDEBUG
116static
118 SCIP_HASHMAP* varindex, /**< maps variables to indicies between 0,..,SCIPgetNVars(scip)-1 */
119 SCIP_VAR* var /**< variable */
120 )
121{
122 assert(varindex != NULL);
123 assert(var != NULL);
124 assert(SCIPhashmapExists(varindex, (void*)var));
125
126 return SCIPhashmapGetImageInt(varindex, (void*)var);
127}
128#else
129#define getVarIndex(varindex,var) (SCIPhashmapGetImageInt((varindex), (void*)(var)))
130#endif
131
132/** samples and stores random points; stores points which have a better objective value than the current incumbent
133 * solution
134 */
135static
137 SCIP* scip, /**< SCIP data structure */
138 SCIP_SOL** rndpoints, /**< array to store all random points */
139 int nmaxrndpoints, /**< maximum number of random points to compute */
140 SCIP_Real maxboundsize, /**< maximum variable domain size for unbounded variables */
141 SCIP_RANDNUMGEN* randnumgen, /**< random number generator */
142 SCIP_Real bestobj, /**< objective value in the transformed space of the current incumbent */
143 int* nstored /**< pointer to store the number of randomly generated points */
144 )
145{
146 SCIP_VAR** vars;
147 SCIP_SOL* sol;
148 SCIP_Real val;
149 SCIP_Real lb;
150 SCIP_Real ub;
151 int nvars;
152 int niter;
153 int i;
154
155 assert(scip != NULL);
156 assert(rndpoints != NULL);
157 assert(nmaxrndpoints > 0);
158 assert(maxboundsize > 0.0);
159 assert(randnumgen != NULL);
160 assert(nstored != NULL);
161
164 *nstored = 0;
165
167
168 for( niter = 0; niter < 3 * nmaxrndpoints && *nstored < nmaxrndpoints; ++niter )
169 {
170 /* reset solution, in case the old one had infinite objective, which can give difficulties in updating the obj value */
172
173 for( i = 0; i < nvars; ++i )
174 {
175 lb = MIN(SCIPvarGetLbLocal(vars[i]), SCIPvarGetUbLocal(vars[i])); /*lint !e666*/
176 ub = MAX(SCIPvarGetLbLocal(vars[i]), SCIPvarGetUbLocal(vars[i])); /*lint !e666*/
177
178 if( SCIPisFeasEQ(scip, lb, ub) )
179 val = (lb + ub) / 2.0;
180 /* use a smaller domain for unbounded variables */
181 else if( !SCIPisInfinity(scip, -lb) && !SCIPisInfinity(scip, ub) )
182 val = SCIPrandomGetReal(randnumgen, lb, ub);
183 else if( !SCIPisInfinity(scip, -lb) )
184 val = lb + SCIPrandomGetReal(randnumgen, 0.0, maxboundsize);
185 else if( !SCIPisInfinity(scip, ub) )
186 val = ub - SCIPrandomGetReal(randnumgen, 0.0, maxboundsize);
187 else
188 {
190 val = SCIPrandomGetReal(randnumgen, -0.5*maxboundsize, 0.5*maxboundsize);
191 }
192 assert(SCIPisFeasGE(scip, val, lb) && SCIPisFeasLE(scip, val, ub));
193
194 /* set solution value; round the sampled point for integer variables */
195 if( SCIPvarIsIntegral(vars[i]) )
196 val = SCIPfeasRound(scip, val);
197 SCIP_CALL( SCIPsetSolVal(scip, sol, vars[i], val) );
198 }
199
200 /* add solution if it is good enough */
201 if( SCIPisLE(scip, SCIPgetSolTransObj(scip, sol), bestobj) )
202 {
203 SCIP_CALL( SCIPcreateSolCopy(scip, &rndpoints[*nstored], sol) );
204 ++(*nstored);
205 }
206 }
207 assert(*nstored <= nmaxrndpoints);
208 SCIPdebugMsg(scip, "found %d randomly generated points\n", *nstored);
209
211
212 return SCIP_OKAY;
213}
214
215/** computes the minimum feasibility of a given point; a negative value means that there is an infeasibility */
216static
218 SCIP* scip, /**< SCIP data structure */
219 SCIP_NLROW** nlrows, /**< array containing all nlrows */
220 int nnlrows, /**< total number of nlrows */
221 SCIP_SOL* sol, /**< solution */
222 SCIP_Real* minfeas /**< buffer to store the minimum feasibility */
223 )
224{
225 SCIP_Real tmp;
226 int i;
227
228 assert(scip != NULL);
229 assert(sol != NULL);
230 assert(minfeas != NULL);
231 assert(nlrows != NULL);
232 assert(nnlrows > 0);
233
234 *minfeas = SCIPinfinity(scip);
235
236 for( i = 0; i < nnlrows; ++i )
237 {
238 assert(nlrows[i] != NULL);
239
240 SCIP_CALL( SCIPgetNlRowSolFeasibility(scip, nlrows[i], sol, &tmp) );
241 if( tmp == SCIP_INVALID ) /*lint !e777*/
242 {
243 *minfeas = -SCIPinfinity(scip);
244 return SCIP_OKAY;
245 }
246 *minfeas = MIN(*minfeas, tmp);
247 }
248
249 return SCIP_OKAY;
250}
251
252/** computes the gradient for a given point and nonlinear row */
253static
255 SCIP* scip, /**< SCIP data structure */
256 SCIP_NLROW* nlrow, /**< nonlinear row */
257 SCIP_SOL* sol, /**< solution to compute the gradient for */
258 SCIP_HASHMAP* varindex, /**< maps variables to indicies between 0,..,SCIPgetNVars(scip)-1 uniquely */
259 SCIP_EXPRITER* exprit, /**< expression iterator that can be used */
260 SCIP_Real* grad, /**< buffer to store the gradient; grad[varindex(i)] corresponds to SCIPgetVars(scip)[i] */
261 SCIP_Real* norm /**< buffer to store ||grad||^2, or SCIP_INVALID if function not differentiable */
262 )
263{
264 SCIP_EXPR* expr;
265 SCIP_VAR* var;
266 int i;
267
268 assert(scip != NULL);
269 assert(nlrow != NULL);
270 assert(varindex != NULL);
271 assert(sol != NULL);
272 assert(norm != NULL);
273
275 *norm = 0.0;
276
277 /* linear part */
278 for( i = 0; i < SCIPnlrowGetNLinearVars(nlrow); i++ )
279 {
280 var = SCIPnlrowGetLinearVars(nlrow)[i];
281 assert(var != NULL);
282 assert(getVarIndex(varindex, var) >= 0 && getVarIndex(varindex, var) < SCIPgetNVars(scip));
283
284 grad[getVarIndex(varindex, var)] += SCIPnlrowGetLinearCoefs(nlrow)[i];
285 }
286
287 /* expression part */
288 expr = SCIPnlrowGetExpr(nlrow);
289
290 if( expr != NULL )
291 {
292 assert(exprit != NULL);
293
294 SCIP_CALL( SCIPevalExprGradient(scip, expr, sol, 0L) );
295
296 /* TODO: change this when nlrows store the vars */
298 for( ; !SCIPexpriterIsEnd(exprit); expr = SCIPexpriterGetNext(exprit) ) /*lint !e441*/ /*lint !e440*/
299 {
300 if( !SCIPisExprVar(scip, expr) )
301 continue;
302
303 var = SCIPgetVarExprVar(expr);
304 assert(var != NULL);
305 assert(getVarIndex(varindex, var) >= 0 && getVarIndex(varindex, var) < SCIPgetNVars(scip));
306
307 if( SCIPexprGetDerivative(expr) == SCIP_INVALID ) /*lint !e777*/
308 {
309 *norm = SCIP_INVALID;
310 return SCIP_OKAY;
311 }
312
313 grad[getVarIndex(varindex, var)] += SCIPexprGetDerivative(expr);
314 }
315 }
316
317 /* compute ||grad||^2 */
318 for( i = 0; i < SCIPgetNVars(scip); ++i )
319 *norm += SQR(grad[i]);
320
321 return SCIP_OKAY;
322}
323
324/** use consensus vectors to improve feasibility for a given starting point */
325static
327 SCIP* scip, /**< SCIP data structure */
328 SCIP_NLROW** nlrows, /**< array containing all nlrows */
329 int nnlrows, /**< total number of nlrows */
330 SCIP_HASHMAP* varindex, /**< maps variables to indicies between 0,..,SCIPgetNVars(scip)-1 */
331 SCIP_SOL* point, /**< random generated point */
332 int maxiter, /**< maximum number of iterations */
333 SCIP_Real minimprfac, /**< minimum required improving factor to proceed in the improvement of a single point */
334 int minimpriter, /**< number of iteration when checking the minimum improvement */
335 SCIP_Real* minfeas, /**< pointer to store the minimum feasibility */
336 SCIP_Real* nlrowgradcosts, /**< estimated costs for each gradient computation */
337 SCIP_Real* gradcosts /**< pointer to store the estimated gradient costs */
338 )
339{
340 SCIP_VAR** vars;
341 SCIP_EXPRITER* exprit;
342 SCIP_Real* grad;
343 SCIP_Real* updatevec;
344 SCIP_Real lastminfeas;
345 int nvars;
346 int r;
347 int i;
348
349 assert(varindex != NULL);
350 assert(point != NULL);
351 assert(maxiter > 0);
352 assert(minfeas != NULL);
353 assert(nlrows != NULL);
354 assert(nnlrows > 0);
355 assert(nlrowgradcosts != NULL);
356 assert(gradcosts != NULL);
357
358 *gradcosts = 0.0;
359
360 SCIP_CALL( getMinFeas(scip, nlrows, nnlrows, point, minfeas) );
361#ifdef SCIP_DEBUG_IMPROVEPOINT
362 printf("start minfeas = %e\n", *minfeas);
363#endif
364
365 /* stop since start point is feasible */
366 if( !SCIPisFeasLT(scip, *minfeas, 0.0) )
367 {
368#ifdef SCIP_DEBUG_IMPROVEPOINT
369 printf("start point is feasible");
370#endif
371 return SCIP_OKAY;
372 }
373
374 lastminfeas = *minfeas;
377
379 SCIP_CALL( SCIPallocBufferArray(scip, &updatevec, nvars) );
380 SCIP_CALL( SCIPcreateExpriter(scip, &exprit) );
381
382 /* main loop */
383 for( r = 0; r < maxiter && SCIPisFeasLT(scip, *minfeas, 0.0); ++r )
384 {
385 SCIP_Real feasibility;
386 SCIP_Real activity;
387 SCIP_Real nlrownorm;
388 SCIP_Real scale;
389 int nviolnlrows;
390
391 BMSclearMemoryArray(updatevec, nvars);
392 nviolnlrows = 0;
393
394 for( i = 0; i < nnlrows; ++i )
395 {
396 int j;
397
398 SCIP_CALL( SCIPgetNlRowSolFeasibility(scip, nlrows[i], point, &feasibility) );
399
400 if( feasibility == SCIP_INVALID ) /*lint !e777*/
401 {
402#ifdef SCIP_DEBUG_IMPROVEPOINT
403 printf("nlrow cannot be evaluated at current point -> skip nlrow\n");
404#endif
405 continue;
406 }
407
408 /* do not consider non-violated constraints */
409 if( SCIPisFeasGE(scip, feasibility, 0.0) )
410 continue;
411
412 SCIP_CALL( computeGradient(scip, nlrows[i], point, varindex, exprit, grad, &nlrownorm) );
413
414 /* update estimated costs for computing gradients */
415 *gradcosts += nlrowgradcosts[i];
416
417 /* skip nlrow if gradient is not available at the current point */
418 if( nlrownorm == SCIP_INVALID ) /*lint !e777*/
419 {
420#ifdef SCIP_DEBUG_IMPROVEPOINT
421 printf("gradient not available at current point -> skip nlrow\n");
422#endif
423 continue;
424 }
425
426 /* increase number of violated differentiable nlrows */
427 ++nviolnlrows;
428
429 /* stop if the gradient disappears at the current point */
430 if( SCIPisZero(scip, nlrownorm) )
431 {
432#ifdef SCIP_DEBUG_IMPROVEPOINT
433 printf("gradient vanished at current point -> stop\n");
434#endif
435 goto TERMINATE;
436 }
437
438 SCIP_CALL( SCIPgetNlRowSolActivity(scip, nlrows[i], point, &activity) );
439 assert(activity != SCIP_INVALID); /*lint !e777*/
440
441 /* compute -g(x_k) / ||grad(g)(x_k)||^2 for a constraint g(x_k) <= 0 */
442 scale = -feasibility / nlrownorm;
443 if( !SCIPisInfinity(scip, SCIPnlrowGetRhs(nlrows[i])) && SCIPisGT(scip, activity, SCIPnlrowGetRhs(nlrows[i])) )
444 scale *= -1.0;
445
446 /* skip nonlinear row if the scale is too small or too large */
447 if( SCIPisEQ(scip, scale, 0.0) || SCIPisHugeValue(scip, REALABS(scale)) )
448 continue;
449
450 for( j = 0; j < nvars; ++j )
451 updatevec[j] += scale * grad[j];
452 }
453
454 /* if there are no violated differentiable rows, stop since start point is feasible or we have no direction for improvement */
455 if( nviolnlrows == 0 )
456 {
457 assert(updatevec[i] == 0.0);
458 goto TERMINATE;
459 }
460
461 for( i = 0; i < nvars; ++i )
462 {
463 /* adjust point */
464 updatevec[i] = SCIPgetSolVal(scip, point, vars[i]) + updatevec[i] / nviolnlrows;
465 updatevec[i] = MIN(updatevec[i], SCIPvarGetUbLocal(vars[i])); /*lint !e666*/
466 updatevec[i] = MAX(updatevec[i], SCIPvarGetLbLocal(vars[i])); /*lint !e666*/
467
468 SCIP_CALL( SCIPsetSolVal(scip, point, vars[i], updatevec[i]) );
469 }
470
471 /* update feasibility */
472 SCIP_CALL( getMinFeas(scip, nlrows, nnlrows, point, minfeas) );
473
474 /* check stopping criterion */
475 if( r % minimpriter == 0 && r > 0 )
476 {
477 if( *minfeas <= MINFEAS
478 || (*minfeas-lastminfeas) / MAX(REALABS(*minfeas), REALABS(lastminfeas)) < minimprfac ) /*lint !e666*/
479 break;
480 lastminfeas = *minfeas;
481 }
482 }
483
484TERMINATE:
485#ifdef SCIP_DEBUG_IMPROVEPOINT
486 printf("niter=%d minfeas=%e\n", r, *minfeas);
487#endif
488
489 SCIPfreeExpriter(&exprit);
490
491 SCIPfreeBufferArray(scip, &updatevec);
493
494 return SCIP_OKAY;
495}
496
497/** sorts points w.r.t their feasibilities; points with a feasibility which is too small (w.r.t. the geometric mean of
498 * all feasibilities) will be filtered out
499 */
500static
502 SCIP* scip, /**< SCIP data structure */
503 SCIP_SOL** points, /**< array containing improved points */
504 SCIP_Real* feasibilities, /**< array containing feasibility for each point (sorted) */
505 int npoints, /**< total number of points */
506 int* nusefulpoints /**< pointer to store the total number of useful points */
507 )
508{
509 SCIP_Real minfeas;
510 SCIP_Real meanfeas;
511 int i;
512
513 assert(points != NULL);
514 assert(feasibilities != NULL);
515 assert(npoints > 0);
516 assert(nusefulpoints != NULL);
517
518 /* sort points w.r.t their feasibilities; non-negative feasibility correspond to feasible points for the NLP */
519 SCIPsortDownRealPtr(feasibilities, (void**)points, npoints);
520 minfeas = feasibilities[npoints - 1];
521
522 /* check if all points are feasible */
523 if( SCIPisFeasGE(scip, minfeas, 0.0) )
524 {
525 *nusefulpoints = npoints;
526 return SCIP_OKAY;
527 }
528
529 *nusefulpoints = 0;
530
531 /* compute shifted geometric mean of feasibilities (shift value = 1 - minfeas) */
532 meanfeas = 1.0;
533 for( i = 0; i < npoints; ++i )
534 {
535 assert(feasibilities[i] - minfeas + 1.0 > 0.0);
536 meanfeas *= pow(feasibilities[i] - minfeas + 1.0, 1.0 / npoints);
537 }
538 meanfeas += minfeas - 1.0;
539 SCIPdebugMsg(scip, "meanfeas = %e\n", meanfeas);
540
541 /* keep all points with which have a feasibility not much below the geometric mean of infeasibilities */
542 for( i = 0; i < npoints; ++i )
543 {
544 if( SCIPisFeasLT(scip, feasibilities[i], 0.0)
545 && (feasibilities[i] <= 1.05 * meanfeas || SCIPisLE(scip, feasibilities[i], MINFEAS)) )
546 break;
547
548 ++(*nusefulpoints);
549 }
550
551 return SCIP_OKAY;
552}
553
554/** returns the relative distance between two points; considers a smaller bounded domain for unbounded variables */
555static
557 SCIP* scip, /**< SCIP data structure */
558 SCIP_SOL* x, /**< first point */
559 SCIP_SOL* y, /**< second point */
560 SCIP_Real maxboundsize /**< maximum variable domain size for unbounded variables */
561 )
562{
563 SCIP_VAR** vars;
564 int nvars;
565 SCIP_Real distance;
566 SCIP_Real solx;
567 SCIP_Real soly;
568 SCIP_Real lb;
569 SCIP_Real ub;
570 int i;
571
572 assert(x != NULL);
573 assert(y != NULL);
574
577 distance = 0.0;
578
579 if( nvars == 0 )
580 return 0.0;
581
582 for( i = 0; i < nvars; ++i )
583 {
584 lb = SCIPvarGetLbLocal(vars[i]);
585 ub = SCIPvarGetUbLocal(vars[i]);
586 solx = SCIPgetSolVal(scip, x, vars[i]);
587 soly = SCIPgetSolVal(scip, y, vars[i]);
588
589 /* adjust lower and upper bounds for unbounded variables*/
590 if( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
591 {
592 lb = -maxboundsize / 2.0;
593 ub = +maxboundsize / 2.0;
594 }
595 else if( SCIPisInfinity(scip, -lb) )
596 {
597 lb = ub - maxboundsize;
598 }
599 else if( SCIPisInfinity(scip, ub) )
600 {
601 ub = lb + maxboundsize;
602 }
603
604 /* project solution values to the variable domain */
605 solx = MIN(MAX(solx, lb), ub);
606 soly = MIN(MAX(soly, lb), ub);
607
608 distance += REALABS(solx - soly) / MAX(1.0, ub - lb);
609 }
610
611 return distance / nvars;
612}
613
614/** cluster useful points with a greedy algorithm */
615static
617 SCIP* scip, /**< SCIP data structure */
618 SCIP_SOL** points, /**< array containing improved points */
619 int npoints, /**< total number of points */
620 int* clusteridx, /**< array to store for each point the index of the cluster */
621 int* ncluster, /**< pointer to store the total number of cluster */
622 SCIP_Real maxboundsize, /**< maximum variable domain size for unbounded variables */
623 SCIP_Real maxreldist, /**< maximum relative distance between any two points of the same cluster */
624 int maxncluster /**< maximum number of clusters to compute */
625 )
626{
627 int i;
628
629 assert(points != NULL);
630 assert(npoints > 0);
631 assert(clusteridx != NULL);
632 assert(ncluster != NULL);
633 assert(maxreldist >= 0.0);
634 assert(maxncluster >= 0);
635
636 /* initialize cluster indices */
637 for( i = 0; i < npoints; ++i )
638 clusteridx[i] = INT_MAX;
639
640 *ncluster = 0;
641
642 for( i = 0; i < npoints && (*ncluster < maxncluster); ++i )
643 {
644 int j;
645
646 /* point is already assigned to a cluster */
647 if( clusteridx[i] != INT_MAX )
648 continue;
649
650 /* create a new cluster for i */
651 clusteridx[i] = *ncluster;
652
653 for( j = i + 1; j < npoints; ++j )
654 {
655 if( clusteridx[j] == INT_MAX && getRelDistance(scip, points[i], points[j], maxboundsize) <= maxreldist )
656 clusteridx[j] = *ncluster;
657 }
658
659 ++(*ncluster);
660 }
661
662#ifndef NDEBUG
663 for( i = 0; i < npoints; ++i )
664 {
665 assert(clusteridx[i] >= 0);
666 assert(clusteridx[i] < *ncluster || clusteridx[i] == INT_MAX);
667 }
668#endif
669
670 return SCIP_OKAY;
671}
672
673/** calls the sub-NLP heuristic for a given cluster */
674static
676 SCIP* scip, /**< SCIP data structure */
677 SCIP_HEUR* heur, /**< multi-start heuristic */
678 SCIP_HEUR* nlpheur, /**< pointer to NLP local search heuristics */
679 SCIP_SOL** points, /**< array containing improved points */
680 int npoints, /**< total number of points */
681 SCIP_Bool* success /**< pointer to store if we could find a solution */
682 )
683{
684 SCIP_VAR** vars;
685 SCIP_SOL* refpoint;
686 SCIP_RESULT nlpresult;
687 SCIP_Real val;
688 int nbinvars;
689 int nintvars;
690 int nvars;
691 int i;
692
693 assert(points != NULL);
694 assert(npoints > 0);
695
696 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, &nintvars, NULL, NULL) );
697 *success = FALSE;
698
699 SCIP_CALL( SCIPcreateSol(scip, &refpoint, heur) );
700
701 /* compute reference point */
702 for( i = 0; i < nvars; ++i )
703 {
704 int p;
705
706 val = 0.0;
707
708 for( p = 0; p < npoints; ++p )
709 {
710 assert(points[p] != NULL);
711 val += SCIPgetSolVal(scip, points[p], vars[i]);
712 }
713
714 SCIP_CALL( SCIPsetSolVal(scip, refpoint, vars[i], val / npoints) );
715 }
716
717 /* round point for sub-NLP heuristic */
718 SCIP_CALL( SCIProundSol(scip, refpoint, success) );
719 SCIPdebugMsg(scip, "rounding of refpoint successfully? %u\n", *success);
720
721 /* round variables manually if the locks did not allow us to round them */
722 if( !(*success) )
723 {
724 for( i = 0; i < nbinvars + nintvars; ++i )
725 {
726 val = SCIPgetSolVal(scip, refpoint, vars[i]);
727
728 if( !SCIPisFeasIntegral(scip, val) )
729 {
732
733 /* round and adjust value */
734 val = SCIPround(scip, val);
735 val = MIN(val, SCIPvarGetUbLocal(vars[i])); /*lint !e666*/
736 val = MAX(val, SCIPvarGetLbLocal(vars[i])); /*lint !e666*/
738
739 SCIP_CALL( SCIPsetSolVal(scip, refpoint, vars[i], val) );
740 }
741 }
742 }
743
744 /* call sub-NLP heuristic */
745 SCIP_CALL( SCIPapplyHeurSubNlp(scip, nlpheur, &nlpresult, refpoint, NULL) );
746 SCIP_CALL( SCIPfreeSol(scip, &refpoint) );
747
748 /* let sub-NLP heuristic decide whether the solution is feasible or not */
749 *success = nlpresult == SCIP_FOUNDSOL;
750
751 return SCIP_OKAY;
752}
753
754/** recursive helper function to count the number of nodes in a sub-expr */
755static
757 SCIP_EXPR* expr /**< expression */
758 )
759{
760 int sum;
761 int i;
762
763 assert(expr != NULL);
764
765 sum = 0;
766 for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
767 {
768 SCIP_EXPR* child = SCIPexprGetChildren(expr)[i];
769 sum += getExprSize(child);
770 }
771 return 1 + sum;
772}
773
774/** main function of the multi-start heuristic (see @ref heur_multistart.h for more details); it consists of the
775 * following four steps:
776 *
777 * 1. sampling points in the current domain; for unbounded variables we use a bounded box
778 *
779 * 2. reduce infeasibility by using a gradient descent method
780 *
781 * 3. cluster points; filter points with a too large infeasibility
782 *
783 * 4. compute start point for each cluster and use it in the sub-NLP heuristic (@ref heur_subnlp.h)
784 */
785static
787 SCIP* scip, /**< SCIP data structure */
788 SCIP_HEUR* heur, /**< heuristic */
789 SCIP_HEURDATA* heurdata, /**< heuristic data */
790 SCIP_RESULT* result /**< pointer to store the result */
791 )
792{
793 SCIP_NLROW** nlrows;
794 SCIP_SOL** points;
795 SCIP_HASHMAP* varindex;
796 SCIP_Real* feasibilities;
797 SCIP_Real* nlrowgradcosts;
798 int* clusteridx;
799 SCIP_Real gradlimit;
800 SCIP_Real bestobj;
801 int nusefulpoints;
802 int nrndpoints;
803 int ncluster;
804 int nnlrows;
805 int npoints;
806 int start;
807 int i;
808
809 assert(scip != NULL);
810 assert(heur != NULL);
811 assert(result != NULL);
812 assert(heurdata != NULL);
813
814 SCIPdebugMsg(scip, "call applyHeur()\n");
815
816 nlrows = SCIPgetNLPNlRows(scip);
817 nnlrows = SCIPgetNNLPNlRows(scip);
819
820 SCIP_CALL( SCIPallocBufferArray(scip, &points, heurdata->nrndpoints) );
821 SCIP_CALL( SCIPallocBufferArray(scip, &nlrowgradcosts, nnlrows) );
822 SCIP_CALL( SCIPallocBufferArray(scip, &feasibilities, heurdata->nrndpoints) );
823 SCIP_CALL( SCIPallocBufferArray(scip, &clusteridx, heurdata->nrndpoints) );
825
826 /* create an unique mapping of all variables to 0,..,SCIPgetNVars(scip)-1 */
827 for( i = 0; i < SCIPgetNVars(scip); ++i )
828 {
829 SCIP_CALL( SCIPhashmapInsertInt(varindex, (void*)SCIPgetVars(scip)[i], i) );
830 }
831
832 /* compute estimated costs of computing a gradient for each nlrow */
833 for( i = 0; i < nnlrows; ++i )
834 {
835 nlrowgradcosts[i] = GRADCOSTFAC_LINEAR * SCIPnlrowGetNLinearVars(nlrows[i]);
836 if( SCIPnlrowGetExpr(nlrows[i]) != NULL )
837 nlrowgradcosts[i] += GRADCOSTFAC_NONLINEAR * getExprSize(SCIPnlrowGetExpr(nlrows[i]));
838 }
839
840 /*
841 * 1. sampling points in the current domain; for unbounded variables we use a bounded box
842 */
843 SCIP_CALL( sampleRandomPoints(scip, points, heurdata->nrndpoints, heurdata->maxboundsize, heurdata->randnumgen,
844 bestobj, &nrndpoints) );
845 assert(nrndpoints >= 0);
846
847 if( nrndpoints == 0 )
848 goto TERMINATE;
849
850 /*
851 * 2. improve points via consensus vectors
852 */
853 gradlimit = heurdata->gradlimit == 0.0 ? SCIPinfinity(scip) : heurdata->gradlimit;
854 for( npoints = 0; npoints < nrndpoints && gradlimit >= 0 && !SCIPisStopped(scip); ++npoints )
855 {
856 SCIP_Real gradcosts;
857
858 SCIP_CALL( improvePoint(scip, nlrows, nnlrows, varindex, points[npoints],
859 heurdata->maxiter, heurdata->minimprfac, heurdata->minimpriter, &feasibilities[npoints], nlrowgradcosts,
860 &gradcosts) );
861
862 gradlimit -= gradcosts;
863 SCIPdebugMsg(scip, "improve point %d / %d gradlimit = %g\n", npoints, nrndpoints, gradlimit);
864 }
865 assert(npoints >= 0 && npoints <= nrndpoints);
866
867 if( npoints == 0 )
868 goto TERMINATE;
869
870 /*
871 * 3. filter and cluster points
872 */
873 SCIP_CALL( filterPoints(scip, points, feasibilities, npoints, &nusefulpoints) );
874 assert(nusefulpoints >= 0);
875 SCIPdebugMsg(scip, "nusefulpoints = %d\n", nusefulpoints);
876
877 if( nusefulpoints == 0 )
878 goto TERMINATE;
879
880 SCIP_CALL( clusterPointsGreedy(scip, points, nusefulpoints, clusteridx, &ncluster, heurdata->maxboundsize,
881 heurdata->maxreldist, heurdata->maxncluster) );
882 assert(ncluster >= 0 && ncluster <= heurdata->maxncluster);
883 SCIPdebugMsg(scip, "ncluster = %d\n", ncluster);
884
885 SCIPsortIntPtr(clusteridx, (void**)points, nusefulpoints);
886
887 /*
888 * 4. compute start point for each cluster and use it in the sub-NLP heuristic (@ref heur_subnlp.h)
889 */
890 start = 0;
891 while( start < nusefulpoints && clusteridx[start] != INT_MAX && !SCIPisStopped(scip) )
892 {
893 SCIP_Bool success;
894 int end;
895
896 end = start;
897 while( end < nusefulpoints && clusteridx[start] == clusteridx[end] )
898 ++end;
899
900 assert(end - start > 0);
901
902 /* call sub-NLP heuristic */
903 SCIP_CALL( solveNLP(scip, heur, heurdata->heursubnlp, &points[start], end - start, &success) );
904 SCIPdebugMsg(scip, "solveNLP result = %u\n", success);
905
906 if( success )
908
909 /* go to the next cluster */
910 start = end;
911 }
912
913TERMINATE:
914 /* free memory */
915 for( i = nrndpoints - 1; i >= 0 ; --i )
916 {
917 assert(points[i] != NULL);
918 SCIP_CALL( SCIPfreeSol(scip, &points[i]) );
919 }
920
921 SCIPhashmapFree(&varindex);
922 SCIPfreeBufferArray(scip, &clusteridx);
923 SCIPfreeBufferArray(scip, &feasibilities);
924 SCIPfreeBufferArray(scip, &nlrowgradcosts);
925 SCIPfreeBufferArray(scip, &points);
926
927 return SCIP_OKAY;
928}
929
930/*
931 * Callback methods of primal heuristic
932 */
933
934/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
935static
936SCIP_DECL_HEURCOPY(heurCopyMultistart)
937{ /*lint --e{715}*/
938
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:257
#define SCIP_INVALID
Definition def.h:187
#define SCIP_Bool
Definition def.h:100
#define MIN(x, y)
Definition def.h:233
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define SQR(x)
Definition def.h:208
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define MAX(x, y)
Definition def.h:229
#define REALABS(x)
Definition def.h:191
#define SCIP_CALL(x)
Definition def.h:364
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:423
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:2986
SCIP_RETCODE SCIPcreateSolCopy(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol)
Definition scip_sol.c:882
SCIP_RETCODE SCIPclearSol(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:1473
int SCIPgetNSols(SCIP *scip)
Definition scip_sol.c:2887
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition scip_sol.c:3128
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition scip_sol.c:1569
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1763
SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:2003
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:24300
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition var.c:23522
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:24266
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:74
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
@ SCIP_INVALIDCALL
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