Scippy

SCIP

Solving Constraint Integer Programs

heur_completesol.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_completesol.c
26 * @ingroup DEFPLUGINS_HEUR
27 * @brief COMPLETESOL - primal heuristic trying to complete given partial solutions
28 * @author Jakob Witzig
29 */
30
31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32
34#include "scip/cons_linear.h"
36#include "scip/pub_event.h"
37#include "scip/pub_heur.h"
38#include "scip/pub_message.h"
39#include "scip/pub_misc.h"
40#include "scip/pub_sol.h"
41#include "scip/pub_var.h"
42#include "scip/scip_branch.h"
43#include "scip/scip_cons.h"
44#include "scip/scip_copy.h"
45#include "scip/scip_event.h"
46#include "scip/scip_general.h"
47#include "scip/scip_heur.h"
48#include "scip/scip_mem.h"
49#include "scip/scip_message.h"
50#include "scip/scip_nlp.h"
51#include "scip/scip_nodesel.h"
52#include "scip/scip_numerics.h"
53#include "scip/scip_param.h"
54#include "scip/scip_prob.h"
55#include "scip/scip_probing.h"
56#include "scip/scip_sol.h"
57#include "scip/scip_solve.h"
59#include "scip/scip_timing.h"
60#include "scip/scip_tree.h"
61#include "scip/scip_var.h"
62#include <string.h>
63
64#define HEUR_NAME "completesol"
65#define HEUR_DESC "primal heuristic trying to complete given partial solutions"
66#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
67#define HEUR_PRIORITY 0
68#define HEUR_FREQ 0
69#define HEUR_FREQOFS 0
70#define HEUR_MAXDEPTH 0
71#define HEUR_TIMING SCIP_HEURTIMING_BEFOREPRESOL | SCIP_HEURTIMING_BEFORENODE
72#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
73
74/* default values for heuristic plugins */
75#define DEFAULT_MAXNODES 5000LL /**< maximum number of nodes to regard in the subproblem */
76#define DEFAULT_MAXUNKRATE 0.85 /**< maximum percentage of unknown solution values */
77#define DEFAULT_ADDALLSOLS FALSE /**< should all subproblem solutions be added to the original SCIP? */
78#define DEFAULT_MINNODES 50LL /**< minimum number of nodes to regard in the subproblem */
79#define DEFAULT_NODESOFS 500LL /**< number of nodes added to the contingent of the total nodes */
80#define DEFAULT_NODESQUOT 0.1 /**< subproblem nodes in relation to nodes of the original problem */
81#define DEFAULT_LPLIMFAC 2.0 /**< factor by which the limit on the number of LP depends on the node limit */
82#define DEFAULT_OBJWEIGHT 1.0 /**< weight of the original objective function (1: only original objective) */
83#define DEFAULT_BOUNDWIDENING 0.1 /**< bound widening factor applied to continuous variables
84 * (0: round bounds to next integer, 1: relax to global bounds)
85 */
86#define DEFAULT_MINIMPROVE 0.01 /**< factor by which the incumbent should be improved at least */
87#define DEFAULT_MINOBJWEIGHT 1e-3 /**< minimal weight for original objective function (zero could lead to infinite solutions) */
88#define DEFAULT_IGNORECONT FALSE /**< should solution values for continuous variables be ignored? */
89#define DEFAULT_BESTSOLS 5 /**< heuristic stops, if the given number of improving solutions were found (-1: no limit) */
90#define DEFAULT_MAXPROPROUNDS 10 /**< maximal number of iterations in propagation (-1: no limit) */
91#define DEFAULT_MAXLPITER -1LL /**< maximal number of LP iterations (-1: no limit) */
92#define DEFAULT_MAXCONTVARS -1 /**< maximal number of continuous variables after presolving (-1: no limit) */
93#define DEFAULT_BEFOREPRESOL TRUE /**< should the heuristic run before presolving? */
94
95/* event handler properties */
96#define EVENTHDLR_NAME "Completesol"
97#define EVENTHDLR_DESC "LP event handler for " HEUR_NAME " heuristic"
98
99
100/** primal heuristic data */
101struct SCIP_HeurData
102{
103 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
104 SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
105 SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
106 SCIP_Longint maxlpiter; /**< maximal number of LP iterations (-1: no limit) */
107 SCIP_Real maxunknownrate; /**< maximal rate of changed coefficients in the objective function */
108 SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
109 SCIP_Real nodelimit; /**< the nodelimit employed in the current sub-SCIP, for the event handler*/
110 SCIP_Real lplimfac; /**< factor by which the limit on the number of LP depends on the node limit */
111 SCIP_Real objweight; /**< weight of the original objective function (1: only original obj, 0: try to keep to given solution) */
112 SCIP_Real boundwidening; /**< bound widening factor applied to continuous variables
113 * (0: fix variables to given solution values, 1: relax to global bounds)
114 */
115 SCIP_Real minimprove; /**< factor by which the incumbent should be improved at least */
116 SCIP_Bool addallsols; /**< should all subproblem solutions be added to the original SCIP? */
117 SCIP_Bool ignorecont; /**< should solution values for continuous variables be ignored? */
118 SCIP_Bool beforepresol; /**< should the heuristic run before presolving? */
119 int bestsols; /**< heuristic stops, if the given number of improving solutions were found (-1: no limit) */
120 int maxcontvars; /**< maximal number of continuous variables after presolving (-1: no limit) */
121 int maxproprounds; /**< maximal number of iterations in propagation (-1: no limit) */
122};
123
124/* ---------------- Callback methods of event handler ---------------- */
125
126/* exec the event handler
127 *
128 * we interrupt the solution process
129 */
130static
131SCIP_DECL_EVENTEXEC(eventExecCompletesol)
132{
133 SCIP_HEURDATA* heurdata;
134
135 assert(eventhdlr != NULL);
136 assert(eventdata != NULL);
137 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
138 assert(event != NULL);
140
141 heurdata = (SCIP_HEURDATA*)eventdata;
142 assert(heurdata != NULL);
143
144 /* interrupt solution process of sub-SCIP */
145 if( SCIPgetNLPs(scip) > heurdata->lplimfac * heurdata->nodelimit )
146 {
147 SCIPdebugMsg(scip, "interrupt after %" SCIP_LONGINT_FORMAT " LPs\n",SCIPgetNLPs(scip));
149 }
150
151 return SCIP_OKAY;
152}
153
154/** creates a subproblem by fixing a number of variables */
155static
157 SCIP* scip, /**< original SCIP data structure */
158 SCIP* subscip, /**< SCIP data structure for the subproblem */
159 SCIP_HEURDATA* heurdata, /**< heuristic's private data structure */
160 SCIP_VAR** subvars, /**< the variables of the subproblem */
161 SCIP_SOL* partialsol, /**< partial solution */
162 SCIP_Bool* tightened /**< array to store for which variables we have found bound tightenings */
163 )
164{
165 SCIP_VAR** vars;
166 SCIP_CONS* objcons;
167 SCIP_Real epsobj;
168 SCIP_Real cutoff;
169 SCIP_Real upperbound;
170 char consobjname[SCIP_MAXSTRLEN];
171 int nvars;
172 int i;
173
174 assert(scip != NULL);
175 assert(subscip != NULL);
176 assert(subvars != NULL);
177 assert(heurdata != NULL);
178
179 /* if there is already a solution, add an objective cutoff */
180 if( SCIPgetNSols(scip) > 0 )
181 {
183
184 upperbound = SCIPgetUpperbound(scip) - SCIPsumepsilon(scip);
185
187 cutoff = (1 - heurdata->minimprove) * SCIPgetUpperbound(scip) + heurdata->minimprove * SCIPgetLowerbound(scip);
188 else
189 {
190 if( SCIPgetUpperbound(scip) >= 0 )
191 cutoff = (1 - heurdata->minimprove) * SCIPgetUpperbound(scip);
192 else
193 cutoff = (1 + heurdata->minimprove) * SCIPgetUpperbound(scip);
194 }
195 cutoff = MIN(upperbound, cutoff);
196 SCIPdebugMsg(scip, "set cutoff=%g for sub-SCIP\n", cutoff);
197 }
198 else
199 cutoff = SCIPinfinity(scip);
200
201 /* calculate objective coefficients for all potential epsilons */
202 if( SCIPisEQ(scip, heurdata->objweight, 1.0) )
203 return SCIP_OKAY;
204 else if( !SCIPisInfinity(scip, cutoff) )
205 epsobj = 1.0;
206 else
207 {
208 /* divide by objweight to avoid changing objective coefficient of original problem variables */
209 epsobj = (1.0 - heurdata->objweight)/heurdata->objweight;
210
211 /* scale with -1 if we have a maximization problem */
213 epsobj *= -1.0;
214 }
215
216 /* get active variables */
217 vars = SCIPgetVars(scip);
218 nvars = SCIPgetNVars(scip);
219
220 objcons = NULL;
221
222 /* add constraints to measure the distance to the given partial solution */
223 for( i = 0; i < nvars; i++ )
224 {
225 SCIP_Real solval;
226 int idx;
227
228 assert(SCIPvarIsActive(vars[i]));
229
230 if( subvars[i] == NULL )
231 continue;
232
233 /* add objective function as a constraint, if a primal bound exists */
234 if( SCIPisInfinity(scip, cutoff) )
235 {
236 /* create the constraints */
237 if( objcons == NULL )
238 {
239 SCIP_Real lhs;
240 SCIP_Real rhs;
241
243 {
244 lhs = -SCIPinfinity(subscip);
245 rhs = cutoff;
246 }
247 else
248 {
249 lhs = cutoff;
250 rhs = SCIPinfinity(subscip);
251 }
252
253 (void)SCIPsnprintf(consobjname, SCIP_MAXSTRLEN, "obj");
254 SCIP_CALL( SCIPcreateConsBasicLinear(subscip, &objcons, consobjname, 0, NULL, NULL, lhs, rhs) );
255 }
256
257 /* add the variable to the constraints */
258 SCIP_CALL( SCIPaddCoefLinear(subscip, objcons, subvars[i], SCIPvarGetObj(subvars[i])) );
259
260 /* set objective coefficient to 0.0 */
261 SCIP_CALL( SCIPchgVarObj(subscip, subvars[i], 0.0) );
262 }
263
264 solval = SCIPgetSolVal(scip, partialsol, vars[i]);
265
266 /* skip variables with unknown solution value */
267 if( solval == SCIP_UNKNOWN ) /*lint !e777*/
268 continue;
269
270 idx = SCIPvarGetProbindex(vars[i]);
271 assert(idx >= 0);
272
273 /* skip variables where we already found some bound tightenings */
274 if( tightened[idx] == FALSE )
275 {
276 /* special case: vars[i] is binary; we do not add an extra variable, but we mimic the behavior we would get with it.
277 * E.g., if the solval is 0.3, setting the variable to 0 would give a cost of 0.3 * epsobj, setting it to 1 gives
278 * 0.7 * epsobj. Thus, 0.3 * epsobj can be treated as a constant in the objective function and the variable gets
279 * an objective coefficient of 0.4 * epsobj.
280 */
281 if( SCIPvarIsBinary(vars[i]) )
282 {
283 SCIP_Real frac = SCIPfeasFrac(scip, solval);
284 SCIP_Real objcoef;
285
286 frac = MIN(frac, 1-frac);
287 objcoef = (1 - 2*frac) * epsobj * (int)SCIPgetObjsense(scip);
288
289 if( solval > 0.5 )
290 {
291 SCIP_CALL( SCIPchgVarObj(scip, vars[i], -objcoef) );
292 }
293 else
294 {
295 SCIP_CALL( SCIPchgVarObj(scip, vars[i], objcoef) );
296 }
297 }
298 else
299 {
300 SCIP_CONS* conspos;
301 SCIP_CONS* consneg;
302 SCIP_VAR* eps;
303 char consnamepos[SCIP_MAXSTRLEN];
304 char consnameneg[SCIP_MAXSTRLEN];
305 char epsname[SCIP_MAXSTRLEN];
306
307 /* create two new variables */
308 (void)SCIPsnprintf(epsname, SCIP_MAXSTRLEN, "eps_%s", SCIPvarGetName(subvars[i]));
309
310 SCIP_CALL( SCIPcreateVarBasic(subscip, &eps, epsname, 0.0, SCIPinfinity(scip), epsobj, SCIP_VARTYPE_CONTINUOUS) );
311 SCIP_CALL( SCIPaddVar(subscip, eps) );
312
313 /* create two constraints */
314 (void)SCIPsnprintf(consnamepos, SCIP_MAXSTRLEN, "cons_%s_pos", SCIPvarGetName(subvars[i]));
315 (void)SCIPsnprintf(consnameneg, SCIP_MAXSTRLEN, "cons_%s_neq", SCIPvarGetName(subvars[i]));
316
317 /* x_{i} - s_{i} <= e_{i} <==> x_{i} - e_{i} <= s_{i} */
318 SCIP_CALL( SCIPcreateConsBasicLinear(subscip, &conspos, consnamepos, 0, NULL, NULL, -SCIPinfinity(scip), solval) );
319 SCIP_CALL( SCIPaddCoefLinear(subscip, conspos, subvars[i], 1.0) );
320 SCIP_CALL( SCIPaddCoefLinear(subscip, conspos, eps, -1.0) );
321 SCIP_CALL( SCIPaddCons(subscip, conspos) );
322 SCIP_CALL( SCIPreleaseCons(subscip, &conspos) );
323
324 /* s_{i} - x_{i} <= e_{i} <==> e_{i} - x_{i} >= s_{i} */
325 SCIP_CALL( SCIPcreateConsBasicLinear(subscip, &consneg, consnameneg, 0, NULL, NULL, solval, SCIPinfinity(scip)) );
326 SCIP_CALL( SCIPaddCoefLinear(subscip, consneg, subvars[i], -1.0) );
327 SCIP_CALL( SCIPaddCoefLinear(subscip, consneg, eps, 1.0) );
328 SCIP_CALL( SCIPaddCons(subscip, consneg) );
329 SCIP_CALL( SCIPreleaseCons(subscip, &consneg) );
330
331 /* release the variables */
332 SCIP_CALL( SCIPreleaseVar(subscip, &eps) );
333 }
334 }
335 }
336
337 /* add and release the constraint representing the original objective function */
338 if( objcons != NULL )
339 {
340 SCIP_CALL( SCIPaddCons(subscip, objcons) );
341 SCIP_CALL( SCIPreleaseCons(subscip, &objcons) );
342 }
343
344 return SCIP_OKAY;
345}
346
347/** perform a probing bound change or fixes the variable */
348static
350 SCIP* scip, /**< original SCIP data structure */
351 SCIP_VAR* var, /**< problem variable */
352 SCIP_Real newval, /**< new bound */
353 SCIP_BRANCHDIR branchdir, /**< bound change direction */
354 SCIP_Bool* success /**< pointer to store whether the bound could be tightened */
355 )
356{
357 SCIP_Real ub;
358 SCIP_Real lb;
359
360 assert(scip != NULL);
361 assert(var != NULL);
362
363 (*success) = FALSE;
364
365 ub = SCIPvarGetUbLocal(var);
366 lb = SCIPvarGetLbLocal(var);
367
368 switch (branchdir) {
370 if( SCIPisLT(scip, newval, ub) && SCIPisGE(scip, newval, lb) )
371 {
372 SCIP_CALL( SCIPchgVarUbProbing(scip, var, newval) );
373 (*success) = TRUE;
374 }
375 break;
377 if( SCIPisLE(scip, newval, ub) && SCIPisGT(scip, newval, lb) )
378 {
379 SCIP_CALL( SCIPchgVarLbProbing(scip, var, newval) );
380 (*success) = TRUE;
381 }
382 break;
384 if( SCIPisLE(scip, newval, ub) && SCIPisGE(scip, newval, lb) )
385 {
386 SCIP_CALL( SCIPfixVarProbing(scip, var, newval) );
387 (*success) = TRUE;
388 }
389 break;
390 default:
391 return SCIP_INVALIDDATA;
392 }/*lint !e788*/
393
394 return SCIP_OKAY;
395}
396
397/** tries variables bound changes guided by the given solution */
398static
400 SCIP* scip, /**< original SCIP data structure */
401 SCIP_HEURDATA* heurdata, /**< heuristic's private data structure */
402 SCIP_VAR** vars, /**< problem variables */
403 int nvars, /**< number of problem variables */
404 SCIP_SOL* sol, /**< solution to guide the bound changes */
405 SCIP_Bool* tightened, /**< array to store if variable bound could be tightened */
406 SCIP_Bool* infeasible /**< pointer to store whether subproblem is infeasible */
407 )
408{
409#ifndef NDEBUG
410 SCIP_Bool incontsection;
411#endif
412 SCIP_Bool abortearly;
413 SCIP_Bool cutoff;
414 SCIP_Bool probingsuccess;
415 SCIP_Longint ndomreds;
416 SCIP_Longint ndomredssum;
417 int nbndtightenings;
418 int v;
419
420 assert(scip != NULL);
421 assert(heurdata != NULL);
422 assert(vars != NULL);
423 assert(nvars >= 0);
424 assert(sol != NULL);
425 assert(tightened != NULL);
426
428
429 SCIPdebugMsg(scip, "> start probing along the solution values\n");
430
431 *infeasible = FALSE;
432 abortearly = FALSE;
433 nbndtightenings = 0;
434 ndomredssum = 0;
435#ifndef NDEBUG
436 incontsection = FALSE;
437#endif
438
439 /* there is at least one integral variable; open one probing node for all non-continuous variables */
440 if( nvars - SCIPgetNContVars(scip) > 0 )
441 {
443 }
444
445 for( v = 0; v < nvars && !abortearly; v++ )
446 {
447 SCIP_Real solval;
448
449 assert(SCIPvarIsActive(vars[v]));
450
451 cutoff = FALSE;
452 ndomreds = 0;
453
454#ifndef NDEBUG
455 incontsection |= (!SCIPvarIsIntegral(vars[v])); /*lint !e514*/
456 assert(!incontsection || !SCIPvarIsIntegral(vars[v]));
457#endif
458
459 /* return if we have found enough domain reductions tightenings */
460 if( ndomredssum > 0.3*nvars )
461 break;
462
463 solval = SCIPgetSolVal(scip, sol, vars[v]);
464
465 /* skip unknown variables */
466 if( solval == SCIP_UNKNOWN ) /*lint !e777*/
467 continue;
468 assert(!SCIPisInfinity(scip, solval) && !SCIPisInfinity(scip, -solval));
469
470 /* variable is binary or integer */
471 if( SCIPvarIsIntegral(vars[v]) )
472 {
473 /* the solution value is integral, try to fix them */
474 if( SCIPisIntegral(scip, solval) )
475 {
476 SCIP_CALL( chgProbingBound(scip, vars[v], solval, SCIP_BRANCHDIR_FIXED, &probingsuccess) );
477 tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
478 ++nbndtightenings;
479
480#ifdef SCIP_MORE_DEBUG
481 SCIPdebugMsg(scip, "> fix variable <%s> = [%g,%g] to %g \n", SCIPvarGetName(vars[v]),
482 SCIPvarGetLbGlobal(vars[v]), SCIPvarGetUbGlobal(vars[v]), solval);
483#endif
484 }
485 else
486 {
487 SCIP_Real ub = SCIPceil(scip, solval) + 1.0;
488 SCIP_Real lb = SCIPfloor(scip, solval) - 1.0;
489
490 /* try tightening of upper bound */
491 if( SCIPisLT(scip, ub, SCIPvarGetUbLocal(vars[v])) )
492 {
493 SCIP_CALL( chgProbingBound(scip, vars[v], solval, SCIP_BRANCHDIR_DOWNWARDS, &probingsuccess) );
494 tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
495 ++nbndtightenings;
496
497#ifdef SCIP_MORE_DEBUG
498 SCIPdebugMsg(scip, "> tighten upper bound of variable <%s>: %g to %g\n", SCIPvarGetName(vars[v]),
499 SCIPvarGetUbGlobal(vars[v]), ub);
500#endif
501 }
502
503 /* try tightening of lower bound */
504 if( SCIPisGT(scip, lb, SCIPvarGetLbLocal(vars[v])) )
505 {
506 SCIP_CALL( chgProbingBound(scip, vars[v], solval, SCIP_BRANCHDIR_UPWARDS, &probingsuccess) );
507 tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
508 ++nbndtightenings;
509
510#ifdef SCIP_MORE_DEBUG
511 SCIPdebugMsg(scip, "> tighten lower bound of variable <%s>: %g to %g\n", SCIPvarGetName(vars[v]),
512 SCIPvarGetLbGlobal(vars[v]), ub);
513#endif
514 }
515 }
516 }
517 /* variable is continuous */
518 else
519 {
520 /* fix to lb or ub */
521 if( SCIPisEQ(scip, solval, SCIPvarGetLbLocal(vars[v])) || SCIPisEQ(scip, solval, SCIPvarGetUbLocal(vars[v])) )
522 {
523 /* open a new probing node */
525 {
527
528 SCIP_CALL( chgProbingBound(scip, vars[v], solval, SCIP_BRANCHDIR_FIXED, &probingsuccess) );
529
530 /* skip propagation if the bound could not be changed, e.g., already tightened due to previous
531 * domain propagation
532 */
533 if( probingsuccess )
534 {
535 SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, &cutoff, &ndomreds) );
536 }
537
538 if( cutoff )
539 {
540 ndomreds = 0;
542 }
543 else
544 {
545 assert(SCIPvarGetProbindex(vars[v]) >= 0);
546 tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
547 ++nbndtightenings;
548#ifdef SCIP_MORE_DEBUG
549 SCIPdebugMsg(scip, "> fix variable <%s> = [%g,%g] to %g (ndomreds=%lld)\n", SCIPvarGetName(vars[v]),
550 SCIPvarGetLbGlobal(vars[v]), SCIPvarGetUbGlobal(vars[v]), solval, ndomreds);
551#endif
552 }
553 }
554 else
555 /* abort probing */
556 abortearly = TRUE;
557 }
558 else
559 {
560 SCIP_Real offset;
561 SCIP_Real newub = SCIPvarGetUbGlobal(vars[v]);
562 SCIP_Real newlb = SCIPvarGetLbGlobal(vars[v]);
563
564 /* both bound are finite */
565 if( !SCIPisInfinity(scip, -newlb) && !SCIPisInfinity(scip, newub) )
566 offset = REALABS(heurdata->boundwidening * (newub-newlb));
567 else
568 {
569 offset = 0.0;
570
571 /* if exactly one bound is finite, widen bound w.r.t. solution value and finite bound */
572 if( !SCIPisInfinity(scip, -newlb) )
573 offset = REALABS(heurdata->boundwidening * (solval-newlb));
574 else if( !SCIPisInfinity(scip, newub) )
575 offset = REALABS(heurdata->boundwidening * (newub-solval));
576 }
577
578 /* update bounds */
579 newub = SCIPceil(scip, solval) + offset;
580 newlb = SCIPfloor(scip, solval) - offset;
581
582 /* try tightening of upper bound */
583 if( SCIPisLT(scip, newub, SCIPvarGetUbLocal(vars[v])) )
584 {
585 /* open a new probing node */
587 {
589 SCIP_CALL( chgProbingBound(scip, vars[v], newub, SCIP_BRANCHDIR_DOWNWARDS, &probingsuccess) );
590
591 /* skip propagation if the bound could not be changed, e.g., already tightened due to previous
592 * domain propagation
593 */
594 if( probingsuccess )
595 {
596 SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, &cutoff, &ndomreds) );
597 }
598
599 if( cutoff )
600 {
601 ndomreds = 0;
602
603 /* backtrack to last feasible probing node */
605
606 /* we can tighten the lower bound by newub */
607 SCIP_CALL( chgProbingBound(scip, vars[v], newub, SCIP_BRANCHDIR_UPWARDS, &probingsuccess) );
608
609 /* propagate the new bound */
610 SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, &cutoff, &ndomreds) );
611
612 /* there is no feasible solution w.r.t. the current bounds */
613 if( cutoff )
614 {
615 SCIPdebugMsg(scip, "> subproblem is infeasible within the local bounds\n");
616 *infeasible = TRUE;
617 return SCIP_OKAY;
618 }
619#ifdef SCIP_MORE_DEBUG
620 SCIPdebugMsg(scip, "> tighten lower bound of variable <%s>: %g to %g\n",
621 SCIPvarGetName(vars[v]), SCIPvarGetLbGlobal(vars[v]), newub);
622#endif
623 }
624 else
625 {
626 assert(SCIPvarGetProbindex(vars[v]) >= 0);
627 tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
628 ++nbndtightenings;
629#ifdef SCIP_MORE_DEBUG
630 SCIPdebugMsg(scip, "> tighten upper bound of variable <%s>: %g to %g (ndomreds=%lld)\n",
631 SCIPvarGetName(vars[v]), SCIPvarGetUbGlobal(vars[v]), newub, ndomreds);
632#endif
633 }
634 }
635 else
636 /* abort probing */
637 abortearly = TRUE;
638 }
639
640 /* try tightening of lower bound */
641 if( SCIPisGT(scip, newlb, SCIPvarGetLbLocal(vars[v])) )
642 {
643 /* open a new probing node */
645 {
647 SCIP_CALL( chgProbingBound(scip, vars[v], newlb, SCIP_BRANCHDIR_UPWARDS, &probingsuccess) );
648
649 /* skip propagation if the bound could not be changed, e.g., already tightened due to previous
650 * domain propagation
651 */
652 if( probingsuccess )
653 {
654 SCIP_CALL( SCIPpropagateProbing(scip, -1, &cutoff, &ndomreds) );
655 }
656
657 if( cutoff )
658 {
659 ndomreds = 0;
660
661 /* backtrack to last feasible probing node */
663
664 /* we can tighten the upper bound by newlb */
665 SCIP_CALL( chgProbingBound(scip, vars[v], newlb, SCIP_BRANCHDIR_DOWNWARDS, &probingsuccess) );
666
667 /* propagate the new bound */
668 SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, &cutoff, &ndomreds) );
669
670 /* there is no feasible solution w.r.t. the current bounds */
671 if( cutoff )
672 {
673 SCIPdebugMsg(scip, "> subproblem is infeasible within the local bounds\n");
674 *infeasible = TRUE;
675 return SCIP_OKAY;
676 }
677#ifdef SCIP_MORE_DEBUG
678 SCIPdebugMsg(scip, "> tighten upper bound of variable <%s>: %g to %g\n",
679 SCIPvarGetName(vars[v]), SCIPvarGetUbGlobal(vars[v]), newlb);
680#endif
681 }
682 else
683 {
684 assert(SCIPvarGetProbindex(vars[v]) >= 0);
685 tightened[SCIPvarGetProbindex(vars[v])] = TRUE;
686 ++nbndtightenings;
687#ifdef SCIP_MORE_DEBUG
688 SCIPdebugMsg(scip, "> tighten lower bound of variable <%s>: %g to %g (ndomreds=%lld)\n",
689 SCIPvarGetName(vars[v]), SCIPvarGetLbGlobal(vars[v]), newlb, ndomreds);
690#endif
691 }
692 }
693 else
694 /* abort probing */
695 abortearly = TRUE;
696 }
697 }
698 }
699
700 ndomredssum += ndomreds;
701 }
702
703 SCIPdebugMsg(scip, "> found %d bound tightenings and %lld induced domain reductions (abort=%u).\n", nbndtightenings,
704 ndomredssum, abortearly);
705
706 return SCIP_OKAY;
707}
708
709/* setup and solve the sub-SCIP */
710static
712 SCIP* scip, /**< original SCIP data structure */
713 SCIP* subscip, /**< sub-SCIP data structure */
714 SCIP_HEUR* heur, /**< heuristic data structure */
715 SCIP_HEURDATA* heurdata, /**< heuristic's private data structure */
716 SCIP_RESULT* result, /**< result data structure */
717 SCIP_Longint nstallnodes, /**< number of stalling nodes for the subproblem */
718 SCIP_SOL* partialsol, /**< partial solution */
719 SCIP_Bool* tightened /**< array to store whether a variable was already tightened */
720 )
721{
722 SCIP_HASHMAP* varmapf;
723 SCIP_VAR** vars;
724 SCIP_VAR** subvars = NULL;
725 SCIP_EVENTHDLR* eventhdlr;
726 int nvars;
727 int i;
728
729 SCIP_SOL** subsols;
730 int nsubsols;
731
732 SCIP_Bool valid;
733 SCIP_Bool success;
734 SCIP_RETCODE retcode;
735
736 assert(scip != NULL);
737 assert(subscip != NULL);
738 assert(heur != NULL);
739 assert(heurdata != NULL);
740 assert(result != NULL);
741 assert(partialsol != NULL);
742
743 vars = SCIPgetVars(scip);
744 nvars = SCIPgetNVars(scip);
745
746 /* create the variable mapping hash map */
747 SCIP_CALL( SCIPhashmapCreate(&varmapf, SCIPblkmem(subscip), nvars) );
748
749 eventhdlr = NULL;
750 valid = FALSE;
751
752 /* copy complete SCIP instance */
753 SCIP_CALL( SCIPcopyConsCompression(scip, subscip, varmapf, NULL, "completesol", NULL, NULL, 0, FALSE, FALSE, FALSE,
754 TRUE, &valid) );
755 SCIPdebugMsg(scip, "Copying the SCIP instance returned with valid=%u.\n", valid);
756
757 /* create event handler for LP events */
758 SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecCompletesol, NULL) );
759 if( eventhdlr == NULL )
760 {
761 SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
762 return SCIP_PLUGINNOTFOUND;
763 }
764
765 /* allocate memory to align the SCIP and the sub-SCIP variables */
766 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
767
768 /* map all variables */
769 for( i = 0; i < nvars; i++ )
770 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapf, vars[i]);
771
772 /* free hash map */
773 SCIPhashmapFree(&varmapf);
774
775 /* create a new problem, which fixes variables with same value in bestsol and LP relaxation */
776 SCIP_CALL( createSubproblem(scip, subscip, heurdata, subvars, partialsol, tightened) );
777 SCIPdebugMsg(scip, "Completesol subproblem: %d vars, %d cons\n", SCIPgetNVars(subscip), SCIPgetNConss(subscip));
778
779 /* do not abort subproblem on CTRL-C */
780 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
781
782#ifdef SCIP_DEBUG
783 /* for debugging, enable full output */
784 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", SCIP_VERBLEVEL_FULL) );
785 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", -1) );
786#else
787 /* disable statistic timing inside sub SCIP and output to console */
788 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", (int) SCIP_VERBLEVEL_NONE) );
789 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
790#endif
791
792 /* set limits for the subproblem */
793 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
794 heurdata->nodelimit = heurdata->maxnodes;
795 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/stallnodes", nstallnodes) );
796 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", heurdata->maxnodes) );
797 SCIP_CALL( SCIPsetIntParam(subscip, "limits/bestsol", heurdata->bestsols) );
798
799 /* limit the number of LP iterations */
800 SCIP_CALL( SCIPsetLongintParam(subscip, "lp/iterlim", heurdata->maxlpiter) );
801 SCIP_CALL( SCIPsetLongintParam(subscip, "lp/rootiterlim", heurdata->maxlpiter) );
802
803 /* forbid recursive call of heuristics and separators solving sub-SCIPs */
804 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
805
806 /* disable cutting plane separation */
808
809 /* disable expensive presolving */
811
812 /* use best estimate node selection */
813 if( SCIPfindNodesel(subscip, "estimate") != NULL && !SCIPisParamFixed(subscip, "nodeselection/estimate/stdpriority") )
814 {
815 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/estimate/stdpriority", INT_MAX/4) );
816 }
817
818 /* use inference branching */
819 if( SCIPfindBranchrule(subscip, "inference") != NULL && !SCIPisParamFixed(subscip, "branching/inference/priority") )
820 {
821 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
822 }
823
824 /* disable conflict analysis */
825 if( !SCIPisParamFixed(subscip, "conflict/enable") )
826 {
827 SCIP_CALL( SCIPsetBoolParam(subscip, "conflict/enable", FALSE) );
828 }
829
830 /* speed up sub-SCIP by not checking dual LP feasibility */
831 SCIP_CALL( SCIPsetBoolParam(subscip, "lp/checkdualfeas", FALSE) );
832
833 SCIP_CALL( SCIPtransformProb(subscip) );
834 SCIP_CALL( SCIPcatchEvent(subscip, SCIP_EVENTTYPE_LPSOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, NULL) );
835
836 /* solve the subproblem */
837 SCIPdebugMsg(scip, "solving subproblem: nstallnodes=%" SCIP_LONGINT_FORMAT ", maxnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->maxnodes);
838
839 /* errors in solving the subproblem should not kill the overall solving process;
840 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
841 */
842
843 retcode = SCIPpresolve(subscip);
844
845 /* errors in presolving the subproblem should not kill the overall solving process;
846 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
847 */
848 if( retcode != SCIP_OKAY )
849 {
850 SCIPwarningMessage(scip, "Error while presolving subproblem in %s heuristic; sub-SCIP terminated with code <%d>\n", HEUR_NAME, retcode);
851
852 SCIPABORT(); /*lint --e{527}*/
853
854 goto TERMINATE;
855 }
856
857 if( SCIPgetStage(subscip) == SCIP_STAGE_PRESOLVED )
858 {
859 SCIPdebugMsg(scip, "presolved instance has bin=%d, int=%d, cont=%d variables\n",
860 SCIPgetNBinVars(subscip) + SCIPgetNBinImplVars(subscip),
861 SCIPgetNIntVars(subscip) + SCIPgetNIntImplVars(subscip),
862 SCIPgetNContVars(subscip) + SCIPgetNContImplVars(subscip));
863
864 /* check whether the presolved instance is small enough */
865 if( heurdata->maxcontvars >= 0 && SCIPgetNContVars(subscip) > heurdata->maxcontvars )
866 {
867 SCIPdebugMsg(scip, "presolved instance has too many continuous variables (maxcontvars: %d)\n", heurdata->maxcontvars);
868 goto TERMINATE;
869 }
870
871 /* set node limit of 1 if the presolved problem is an LP, otherwise we would start branching if an LP iteration
872 * limit was set by the user.
873 */
874 if( !SCIPisNLPEnabled(subscip) && SCIPgetNContVars(subscip) == SCIPgetNVars(subscip) )
875 {
876 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", 1LL) );
877 }
878
879 retcode = SCIPsolve(subscip);
880
881 /* errors in solving the subproblem should not kill the overall solving process;
882 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
883 */
884 if( retcode != SCIP_OKAY )
885 {
886 SCIPwarningMessage(scip, "Error while solving subproblem in %s heuristic; sub-SCIP terminated with code <%d>\n", HEUR_NAME, retcode);
887
888 SCIPABORT(); /*lint --e{527}*/
889
890 goto TERMINATE;
891 }
892 }
893
894 SCIP_CALL( SCIPdropEvent(subscip, SCIP_EVENTTYPE_LPSOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, -1) );
895
896 /* print solving statistics of subproblem if we are in SCIP's debug mode */
898
899 /* check, whether a solution was found;
900 * due to numerics, it might happen that not all solutions are feasible -> try all solutions until one was accepted
901 */
902 nsubsols = SCIPgetNSols(subscip);
903 subsols = SCIPgetSols(subscip);
904 success = FALSE;
905 for( i = 0; i < nsubsols && (!success || heurdata->addallsols); i++ )
906 {
907 SCIP_SOL* newsol;
908
909 /* create new solution, try to add to SCIP, and free it immediately */
910 SCIP_CALL( SCIPtranslateSubSol(scip, subscip, subsols[i], heur, subvars, &newsol) );
911 SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, FALSE, TRUE, TRUE, TRUE, &success) );
912
913 if( success )
914 *result = SCIP_FOUNDSOL;
915 }
916
917 SCIPstatisticPrintf("%s statistic: fixed %6.3f integer variables, needed %6.1f seconds, %" SCIP_LONGINT_FORMAT " nodes, solution %10.4f found at node %" SCIP_LONGINT_FORMAT "\n",
918 HEUR_NAME, 0.0, SCIPgetSolvingTime(subscip), SCIPgetNNodes(subscip), success ? SCIPgetPrimalbound(scip) : SCIPinfinity(scip),
919 nsubsols > 0 ? SCIPsolGetNodenum(SCIPgetBestSol(subscip)) : -1 );
920
921 /* print message if the completion of a partial solution failed */
922 if( *result != SCIP_FOUNDSOL )
923 {
924 switch( SCIPgetStatus(subscip) )
925 {
927 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (subproblem is infeasible)\n");
928 break;
930 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (node limit exceeded)\n");
931 break;
933 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (time limit exceeded)\n");
934 break;
936 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (memory limit exceeded)\n");
937 break;
938 default:
939 break;
940 } /*lint !e788*/
941 }
942
943TERMINATE:
944 SCIPfreeBufferArray(scip, &subvars);
945
946 return SCIP_OKAY;
947}
948
949/** main procedure of the completesol heuristic, creates and solves a sub-SCIP */
950static
952 SCIP* scip, /**< original SCIP data structure */
953 SCIP_HEUR* heur, /**< heuristic data structure */
954 SCIP_HEURDATA* heurdata, /**< heuristic's private data structure */
955 SCIP_RESULT* result, /**< result data structure */
956 SCIP_Longint nstallnodes, /**< number of stalling nodes for the subproblem */
957 SCIP_SOL* partialsol /**< partial solution */
958 )
959{
960 SCIP* subscip;
961 SCIP_VAR** vars;
962 SCIP_Bool* tightened;
963 SCIP_Bool infeasible;
964 SCIP_Bool success;
965 SCIP_RETCODE retcode;
966 int nvars;
967
968 assert(scip != NULL);
969 assert(heur != NULL);
970 assert(heurdata != NULL);
971 assert(result != NULL);
972 assert(partialsol != NULL);
973
974 *result = SCIP_DIDNOTRUN;
975
976 SCIPdebugMsg(scip, "+---+ Start Completesol heuristic +---+\n");
977
978 /* check whether there is enough time and memory left */
979 SCIP_CALL( SCIPcheckCopyLimits(scip, &success) );
980
981 if( !success )
982 return SCIP_OKAY;
983
984 *result = SCIP_DIDNOTFIND;
985
986 /* get variable data */
987 vars = SCIPgetVars(scip);
988 nvars = SCIPgetNVars(scip);
989
990 /* get buffer memory and initialize it to FALSE */
991 SCIP_CALL( SCIPallocClearBufferArray(scip, &tightened, nvars) );
992
994
995 SCIP_CALL( tightenVariables(scip, heurdata, vars, nvars, partialsol, tightened, &infeasible) );
996
997 if( infeasible )
998 {
999 SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "completion of a partial solution failed (subproblem is infeasible)\n");
1000 goto ENDPROBING;
1001 }
1002
1003 /* initialize the subproblem */
1004 SCIP_CALL( SCIPcreate(&subscip) );
1005
1006 retcode = setupAndSolve(scip, subscip, heur, heurdata, result, nstallnodes, partialsol, tightened);
1007
1008 /* free subproblem */
1009 SCIP_CALL( SCIPfree(&subscip) );
1010
1011 SCIP_CALL( retcode );
1012
1013 ENDPROBING:
1014 SCIPfreeBufferArray(scip, &tightened);
1016
1017 return SCIP_OKAY;
1018}
1019
1020
1021/*
1022 * Callback methods of primal heuristic
1023 */
1024
1025/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
1026static
1027SCIP_DECL_HEURCOPY(heurCopyCompletesol)
1028{ /*lint --e{715}*/
1029 assert(scip != NULL);
1030 assert(heur != NULL);
1031 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
1032
1033 /* call inclusion method of primal heuristic */
1035
1036 return SCIP_OKAY;
1037}
1038
1039/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
1040static
1041SCIP_DECL_HEURFREE(heurFreeCompletesol)
1042{ /*lint --e{715}*/
1043 SCIP_HEURDATA* heurdata;
1044
1045 assert(heur != NULL);
1046 assert(scip != NULL);
1047
1048 /* get heuristic data */
1049 heurdata = SCIPheurGetData(heur);
1050 assert(heurdata != NULL);
1051
1052 /* free heuristic data */
1053 SCIPfreeBlockMemory(scip, &heurdata);
1054 SCIPheurSetData(heur, NULL);
1055
1056 return SCIP_OKAY;
1057}
1058
1059/** execution method of primal heuristic */
1060static
1061SCIP_DECL_HEUREXEC(heurExecCompletesol)
1062{/*lint --e{715}*/
1063 SCIP_HEURDATA* heurdata;
1064 SCIP_VAR** vars;
1065 SCIP_SOL** partialsols;
1066 SCIP_Longint nstallnodes;
1067 int npartialsols;
1068 int nunknown;
1069 int nfracints;
1070 int nvars;
1071 int s;
1072 int v;
1073
1074 assert( heur != NULL );
1075 assert( scip != NULL );
1076 assert( result != NULL );
1077
1078 *result = SCIP_DELAYED;
1079
1080 /* do not call heuristic if node was already detected to be infeasible */
1081 if( nodeinfeasible )
1082 return SCIP_OKAY;
1083
1084 /* get heuristic data */
1085 heurdata = SCIPheurGetData(heur);
1086 assert( heurdata != NULL );
1087
1088 *result = SCIP_DIDNOTRUN;
1089
1090 if( SCIPisStopped(scip) )
1091 return SCIP_OKAY;
1092
1093 /* do not run after restart */
1094 if( SCIPgetNRuns(scip) > 1 )
1095 return SCIP_OKAY;
1096
1097 /* check whether we want to run before presolving */
1098 if( (heurtiming & SCIP_HEURTIMING_BEFOREPRESOL) && !heurdata->beforepresol )
1099 return SCIP_OKAY;
1100
1101 /* only run before root node */
1102 if( (heurtiming & SCIP_HEURTIMING_BEFORENODE)
1103 && (heurdata->beforepresol || SCIPgetCurrentNode(scip) != SCIPgetRootNode(scip)) )
1104 return SCIP_OKAY;
1105
1106 /* get variable data and return if no variables are left in the problem */
1107 vars = SCIPgetVars(scip);
1108 nvars = SCIPgetNVars(scip);
1109 if( heurdata->ignorecont )
1111 assert(nvars >= 0);
1112
1113 if( nvars == 0 )
1114 return SCIP_OKAY;
1115
1116 /* calculate the maximal number of branching nodes until heuristic is aborted */
1117 nstallnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
1118
1119 /* reward Completesol if it succeeded often */
1120 nstallnodes = (SCIP_Longint)(nstallnodes * 3.0 * (SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur) + 1.0));
1121 nstallnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-SCIP as 100 nodes */
1122 nstallnodes += heurdata->nodesofs;
1123
1124 /* determine the node limit for the current process */
1125 nstallnodes = MIN(nstallnodes, heurdata->maxnodes);
1126
1127 /* check whether we have enough nodes left to call subproblem solving */
1128 if( nstallnodes < heurdata->minnodes )
1129 {
1130 SCIPdebugMsg(scip, "skipping Complete: nstallnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n",
1131 nstallnodes, heurdata->minnodes);
1132 return SCIP_OKAY;
1133 }
1134
1135 /* check the number of variables with unknown value and continuous variables with fractional value */
1136 nfracints = 0;
1137
1138 /* get all partial sols */
1139 npartialsols = SCIPgetNPartialSols(scip);
1140 partialsols = SCIPgetPartialSols(scip);
1141
1142 /* loop over all partial solutions */
1143 for( s = 0; s < npartialsols; s++ )
1144 {
1145 SCIP_SOL* sol;
1146 SCIP_Real solval;
1147 SCIP_Real unknownrate;
1148
1149 sol = partialsols[s];
1150 assert(sol != NULL);
1151 assert(SCIPsolIsPartial(sol));
1152
1153 nunknown = 0;
1154 /* loop over all variables */
1155 for( v = 0; v < nvars; v++ )
1156 {
1157 assert(SCIPvarIsActive(vars[v]));
1158
1159 solval = SCIPgetSolVal(scip, sol, vars[v]);
1160
1161 /* we only want to count variables that are unfixed after the presolving */
1162 if( solval == SCIP_UNKNOWN ) /*lint !e777*/
1163 ++nunknown;
1164 else if( SCIPvarGetType(vars[v]) != SCIP_VARTYPE_CONTINUOUS && !SCIPisIntegral(scip, solval) )
1165 ++nfracints;
1166 }
1167
1168 unknownrate = nunknown / ((SCIP_Real)nvars);
1169
1170 SCIPdebugMsg(scip, "%d (rate %.4f) unknown solution values\n", nunknown, unknownrate);
1171
1172 /* run the heuristic, if not too many unknown variables exist */
1173 if( unknownrate > heurdata->maxunknownrate )
1174 {
1175 SCIPwarningMessage(scip, "ignore partial solution (%d) because unknown rate is too large (%g > %g)\n", s,
1176 unknownrate, heurdata->maxunknownrate);
1177 continue;
1178 }
1179
1180 /* all variables have a finite/known solution value all integer variables have an integral solution value,
1181 * and there are no continuous variables
1182 * in the sub-SCIP, all variables would be fixed, so create a new solution without solving a sub-SCIP
1183 */
1184 if( nunknown == 0 && nfracints == 0 && nvars == SCIPgetNVars(scip) )
1185 {
1186 SCIP_SOL* newsol;
1187 SCIP_Bool stored;
1188
1189 assert(vars != NULL);
1190 assert(nvars >= 0);
1191
1192 SCIP_CALL( SCIPcreateSol(scip, &newsol, heur) );
1193
1194 for( v = 0; v < nvars; v++ )
1195 {
1196 solval = SCIPgetSolVal(scip, sol, vars[v]);
1197 assert(solval != SCIP_UNKNOWN); /*lint !e777*/
1198
1199 SCIP_CALL( SCIPsetSolVal(scip, newsol, vars[v], solval) );
1200 }
1201
1202 SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, FALSE, TRUE, TRUE, TRUE, &stored) );
1203 if( stored )
1204 *result = SCIP_FOUNDSOL;
1205 }
1206 else
1207 {
1208 /* run the heuristic */
1209 SCIP_CALL( applyCompletesol(scip, heur, heurdata, result, nstallnodes, sol) );
1210 }
1211 }
1212
1213 return SCIP_OKAY;
1214}
1215
1216
1217/*
1218 * primal heuristic specific interface methods
1219 */
1220
1221/** creates the completesol primal heuristic and includes it in SCIP */
1223 SCIP* scip /**< SCIP data structure */
1224 )
1225{
1226 SCIP_HEURDATA* heurdata;
1227 SCIP_HEUR* heur;
1228
1229 /* create completesol primal heuristic data */
1230 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
1231 assert(heurdata != NULL);
1232
1233 /* include primal heuristic */
1236 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecCompletesol, heurdata) );
1237
1238 assert(heur != NULL);
1239
1240 /* primal heuristic is safe to use in exact solving mode */
1241 SCIPheurMarkExact(heur);
1242
1243 /* set non fundamental callbacks via setter functions */
1244 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyCompletesol) );
1245 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeCompletesol) );
1246
1247 /* add completesol primal heuristic parameters */
1248
1249 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
1250 "maximum number of nodes to regard in the subproblem",
1251 &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1252
1253 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
1254 "minimum number of nodes required to start the subproblem",
1255 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1256
1257 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/maxunknownrate",
1258 "maximal rate of unknown solution values",
1259 &heurdata->maxunknownrate, FALSE, DEFAULT_MAXUNKRATE, 0.0, 1.0, NULL, NULL) );
1260
1261 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/addallsols",
1262 "should all subproblem solutions be added to the original SCIP?",
1263 &heurdata->addallsols, TRUE, DEFAULT_ADDALLSOLS, NULL, NULL) );
1264
1265 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
1266 "number of nodes added to the contingent of the total nodes",
1267 &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1268
1269 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
1270 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
1271 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
1272
1273 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lplimfac",
1274 "factor by which the limit on the number of LP depends on the node limit",
1275 &heurdata->lplimfac, TRUE, DEFAULT_LPLIMFAC, 1.0, SCIP_REAL_MAX, NULL, NULL) );
1276
1277 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/objweight",
1278 "weight of the original objective function (1: only original objective)",
1279 &heurdata->objweight, TRUE, DEFAULT_OBJWEIGHT, DEFAULT_MINOBJWEIGHT, 1.0, NULL, NULL) );
1280
1281 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/boundwidening",
1282 "bound widening factor applied to continuous variables (0: fix variables to given solution values, 1: relax to global bounds)",
1283 &heurdata->boundwidening, TRUE, DEFAULT_BOUNDWIDENING, 0.0, 1.0, NULL, NULL) );
1284
1285 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
1286 "factor by which the incumbent should be improved at least",
1287 &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
1288
1289 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/ignorecont",
1290 "should number of continuous variables be ignored?",
1291 &heurdata->ignorecont, FALSE, DEFAULT_IGNORECONT, NULL, NULL) );
1292
1293 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/solutions",
1294 "heuristic stops, if the given number of improving solutions were found (-1: no limit)",
1295 &heurdata->bestsols, FALSE, DEFAULT_BESTSOLS, -1, INT_MAX, NULL, NULL) );
1296
1297 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxproprounds",
1298 "maximal number of iterations in propagation (-1: no limit)",
1299 &heurdata->maxproprounds, FALSE, DEFAULT_MAXPROPROUNDS, -1, INT_MAX, NULL, NULL) );
1300
1301 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/beforepresol",
1302 "should the heuristic run before presolving?",
1303 &heurdata->beforepresol, FALSE, DEFAULT_BEFOREPRESOL, NULL, NULL) );
1304
1305 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxlpiter",
1306 "maximal number of LP iterations (-1: no limit)",
1307 &heurdata->maxlpiter, FALSE, DEFAULT_MAXLPITER, -1LL, SCIP_LONGINT_MAX, NULL, NULL) );
1308
1309 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxcontvars",
1310 "maximal number of continuous variables after presolving",
1311 &heurdata->maxcontvars, FALSE, DEFAULT_MAXCONTVARS, -1, INT_MAX, NULL, NULL) );
1312
1313 return SCIP_OKAY;
1314}
Constraint handler for linear constraints in their most general form, .
#define NULL
Definition: def.h:248
#define SCIP_MAXSTRLEN
Definition: def.h:269
#define SCIP_Longint
Definition: def.h:141
#define SCIP_MAXTREEDEPTH
Definition: def.h:297
#define SCIP_REAL_MAX
Definition: def.h:158
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:224
#define SCIP_Real
Definition: def.h:156
#define SCIP_UNKNOWN
Definition: def.h:179
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIP_LONGINT_FORMAT
Definition: def.h:148
#define SCIPABORT()
Definition: def.h:327
#define REALABS(x)
Definition: def.h:182
#define SCIP_LONGINT_MAX
Definition: def.h:142
#define SCIP_CALL(x)
Definition: def.h:355
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_RETCODE SCIPcreateConsBasicLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
SCIP_RETCODE SCIPcopyConsCompression(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool threadsafe, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
Definition: scip_copy.c:2961
SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
Definition: scip_copy.c:3249
SCIP_RETCODE SCIPtranslateSubSol(SCIP *scip, SCIP *subscip, SCIP_SOL *subsol, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_SOL **newsol)
Definition: scip_copy.c:1397
SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
Definition: scip_copy.c:3292
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:759
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip_general.c:402
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip_general.c:370
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip_general.c:562
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:444
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1907
int SCIPgetNIntVars(SCIP *scip)
Definition: scip_prob.c:2340
int SCIPgetNContVars(SCIP *scip)
Definition: scip_prob.c:2569
int SCIPgetNBinImplVars(SCIP *scip)
Definition: scip_prob.c:2432
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:2246
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:3274
int SCIPgetNConss(SCIP *scip)
Definition: scip_prob.c:3620
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:2201
int SCIPgetNIntImplVars(SCIP *scip)
Definition: scip_prob.c:2477
int SCIPgetNContImplVars(SCIP *scip)
Definition: scip_prob.c:2522
SCIP_OBJSENSE SCIPgetObjsense(SCIP *scip)
Definition: scip_prob.c:1400
int SCIPgetNBinVars(SCIP *scip)
Definition: scip_prob.c:2293
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3095
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3284
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3061
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:225
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:111
SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
Definition: scip_param.c:219
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 SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition: scip_param.c:545
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 SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip_param.c:487
SCIP_RETCODE SCIPsetSubscipsOff(SCIP *scip, SCIP_Bool quiet)
Definition: scip_param.c:904
SCIP_RETCODE SCIPsetPresolving(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip_param.c:956
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 SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition: scip_param.c:429
SCIP_RETCODE SCIPsetSeparating(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip_param.c:985
SCIP_RETCODE SCIPincludeHeurCompletesol(SCIP *scip)
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
Definition: scip_branch.c:304
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1173
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: scip_event.c:111
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:396
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:1194
SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip_event.c:293
SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip_event.c:333
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_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition: heur.c:1613
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition: heur.c:1593
void SCIPheurMarkExact(SCIP_HEUR *heur)
Definition: heur.c:1457
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 SCIPallocClearBufferArray(scip, ptr, num)
Definition: scip_mem.h:126
#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
SCIP_Bool SCIPisNLPEnabled(SCIP *scip)
Definition: scip_nlp.c:74
SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
Definition: scip_nodesel.c:242
int SCIPgetProbingDepth(SCIP *scip)
Definition: scip_probing.c:199
SCIP_RETCODE SCIPchgVarUbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:346
SCIP_RETCODE SCIPchgVarLbProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_probing.c:302
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip_probing.c:581
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip_probing.c:226
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
Definition: scip_probing.c:120
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip_probing.c:166
SCIP_RETCODE SCIPfixVarProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval)
Definition: scip_probing.c:419
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip_probing.c:261
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_SOLORIGIN SCIPsolGetOrigin(SCIP_SOL *sol)
Definition: sol.c:4130
SCIP_SOL ** SCIPgetPartialSols(SCIP *scip)
Definition: scip_sol.c:4263
SCIP_Longint SCIPsolGetNodenum(SCIP_SOL *sol)
Definition: sol.c:4239
int SCIPgetNPartialSols(SCIP *scip)
Definition: scip_sol.c:4285
int SCIPgetNSols(SCIP *scip)
Definition: scip_sol.c:2882
SCIP_Bool SCIPsolIsPartial(SCIP_SOL *sol)
Definition: sol.c:4160
SCIP_SOL ** SCIPgetSols(SCIP *scip)
Definition: scip_sol.c:2931
SCIP_RETCODE SCIPtrySolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip_sol.c:4109
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_RETCODE SCIPtransformProb(SCIP *scip)
Definition: scip_solve.c:232
SCIP_RETCODE SCIPpresolve(SCIP *scip)
Definition: scip_solve.c:2449
SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
Definition: scip_solve.c:3548
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip_solve.c:2635
SCIP_Real SCIPgetPrimalbound(SCIP *scip)
SCIP_Real SCIPgetUpperbound(SCIP *scip)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
SCIP_Real SCIPgetLowerbound(SCIP *scip)
int SCIPgetNRuns(SCIP *scip)
SCIP_Longint SCIPgetNLPs(SCIP *scip)
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
Definition: scip_timing.c:378
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeasFrac(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPsumepsilon(SCIP *scip)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip_tree.c:91
SCIP_NODE * SCIPgetRootNode(SCIP *scip)
Definition: scip_tree.c:110
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:23642
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:23478
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:24268
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:23900
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:23453
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:24142
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:23662
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:23267
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1887
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:23490
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:24234
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:24120
SCIP_RETCODE SCIPcreateVarBasic(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype)
Definition: scip_var.c:184
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:5372
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10827
static SCIP_RETCODE createSubproblem(SCIP *scip, SCIP *subscip, SCIP_HEURDATA *heurdata, SCIP_VAR **subvars, SCIP_SOL *partialsol, SCIP_Bool *tightened)
#define DEFAULT_BESTSOLS
#define DEFAULT_NODESQUOT
static SCIP_DECL_HEURCOPY(heurCopyCompletesol)
static SCIP_DECL_HEURFREE(heurFreeCompletesol)
#define DEFAULT_MAXCONTVARS
static SCIP_RETCODE chgProbingBound(SCIP *scip, SCIP_VAR *var, SCIP_Real newval, SCIP_BRANCHDIR branchdir, SCIP_Bool *success)
#define DEFAULT_OBJWEIGHT
#define DEFAULT_NODESOFS
static SCIP_RETCODE tightenVariables(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR **vars, int nvars, SCIP_SOL *sol, SCIP_Bool *tightened, SCIP_Bool *infeasible)
#define DEFAULT_MAXNODES
static SCIP_DECL_EVENTEXEC(eventExecCompletesol)
#define HEUR_TIMING
#define DEFAULT_MINNODES
#define DEFAULT_MAXUNKRATE
#define DEFAULT_IGNORECONT
#define HEUR_FREQOFS
#define HEUR_DESC
#define DEFAULT_LPLIMFAC
#define DEFAULT_ADDALLSOLS
static SCIP_RETCODE setupAndSolve(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_RESULT *result, SCIP_Longint nstallnodes, SCIP_SOL *partialsol, SCIP_Bool *tightened)
static SCIP_RETCODE applyCompletesol(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_RESULT *result, SCIP_Longint nstallnodes, SCIP_SOL *partialsol)
#define HEUR_DISPCHAR
#define HEUR_MAXDEPTH
#define HEUR_PRIORITY
#define DEFAULT_MINOBJWEIGHT
#define DEFAULT_MINIMPROVE
#define HEUR_NAME
#define DEFAULT_MAXLPITER
static SCIP_DECL_HEUREXEC(heurExecCompletesol)
#define DEFAULT_BEFOREPRESOL
#define EVENTHDLR_DESC
#define HEUR_FREQ
#define HEUR_USESSUBSCIP
#define DEFAULT_MAXPROPROUNDS
#define EVENTHDLR_NAME
#define DEFAULT_BOUNDWIDENING
primal heuristic trying to complete given partial solutions
memory allocation routines
real eps
public methods for managing events
public methods for primal heuristics
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
#define SCIPdebug(x)
Definition: pub_message.h:93
#define SCIPstatisticPrintf
Definition: pub_message.h:126
public data structures and miscellaneous methods
public methods for primal CIP solutions
public methods for problem variables
public methods for branching rule plugins and branching
public methods for constraint handler plugins and constraints
public methods for problem copies
public methods for event handler plugins and event handlers
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 node selector plugins
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for the probing mode
public methods for solutions
public solving methods
public methods for querying solving statistics
public methods for timing
public methods for the branch-and-bound tree
public methods for SCIP variables
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:179
#define SCIP_EVENTTYPE_LPSOLVED
Definition: type_event.h:102
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:77
@ SCIP_BRANCHDIR_DOWNWARDS
Definition: type_history.h:43
@ SCIP_BRANCHDIR_FIXED
Definition: type_history.h:45
@ SCIP_BRANCHDIR_UPWARDS
Definition: type_history.h:44
enum SCIP_BranchDir SCIP_BRANCHDIR
Definition: type_history.h:48
@ SCIP_VERBLEVEL_NONE
Definition: type_message.h:57
@ SCIP_VERBLEVEL_HIGH
Definition: type_message.h:61
@ SCIP_VERBLEVEL_FULL
Definition: type_message.h:62
@ SCIP_PARAMSETTING_OFF
Definition: type_paramset.h:63
@ SCIP_PARAMSETTING_FAST
Definition: type_paramset.h:62
@ SCIP_OBJSENSE_MAXIMIZE
Definition: type_prob.h:47
@ SCIP_OBJSENSE_MINIMIZE
Definition: type_prob.h:48
@ SCIP_DIDNOTRUN
Definition: type_result.h:42
@ SCIP_DELAYED
Definition: type_result.h:43
@ 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_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_PLUGINNOTFOUND
Definition: type_retcode.h:54
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_STAGE_PRESOLVED
Definition: type_set.h:51
@ SCIP_SOLORIGIN_PARTIAL
Definition: type_sol.h:48
@ SCIP_STATUS_TIMELIMIT
Definition: type_stat.h:54
@ SCIP_STATUS_INFEASIBLE
Definition: type_stat.h:44
@ SCIP_STATUS_NODELIMIT
Definition: type_stat.h:49
@ SCIP_STATUS_MEMLIMIT
Definition: type_stat.h:55
#define SCIP_HEURTIMING_BEFOREPRESOL
Definition: type_timing.h:92
#define SCIP_HEURTIMING_BEFORENODE
Definition: type_timing.h:80
@ SCIP_VARTYPE_CONTINUOUS
Definition: type_var.h:71