Scippy

SCIP

Solving Constraint Integer Programs

heur_oneopt.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_oneopt.c
26 * @ingroup DEFPLUGINS_HEUR
27 * @brief improvement heuristic that alters single variable values
28 * @author Timo Berthold
29 */
30
31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32
34#include "scip/heur_oneopt.h"
35#include "scip/pub_heur.h"
36#include "scip/pub_lp.h"
37#include "scip/pub_message.h"
38#include "scip/pub_misc.h"
39#include "scip/pub_misc_sort.h"
40#include "scip/pub_sol.h"
41#include "scip/pub_var.h"
43#include "scip/scip_copy.h"
44#include "scip/scip_exact.h"
45#include "scip/scip_general.h"
46#include "scip/scip_heur.h"
47#include "scip/scip_lp.h"
48#include "scip/scip_mem.h"
49#include "scip/scip_message.h"
50#include "scip/scip_numerics.h"
51#include "scip/scip_param.h"
52#include "scip/scip_prob.h"
53#include "scip/scip_sol.h"
54#include "scip/scip_solve.h"
56#include "scip/scip_tree.h"
57#include <string.h>
58
59/* @note If the heuristic runs in the root node, the timing is changed to (SCIP_HEURTIMING_DURINGLPLOOP |
60 * SCIP_HEURTIMING_BEFORENODE), see SCIP_DECL_HEURINITSOL callback.
61 */
62
63#define HEUR_NAME "oneopt"
64#define HEUR_DESC "1-opt heuristic which tries to improve setting of single integer variables"
65#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_ITERATIVE
66#define HEUR_PRIORITY -20000
67#define HEUR_FREQ 1
68#define HEUR_FREQOFS 0
69#define HEUR_MAXDEPTH -1
70#define HEUR_TIMING SCIP_HEURTIMING_BEFOREPRESOL | SCIP_HEURTIMING_AFTERNODE
71#define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
72
73#define DEFAULT_WEIGHTEDOBJ TRUE /**< should the objective be weighted with the potential shifting value when sorting the shifting candidates? */
74#define DEFAULT_DURINGROOT TRUE /**< should the heuristic be called before and during the root node? */
75#define DEFAULT_BEFOREPRESOL FALSE /**< should the heuristic be called before presolving */
76#define DEFAULT_FORCELPCONSTRUCTION FALSE /**< should the construction of the LP be forced even if LP solving is deactivated? */
77#define DEFAULT_USELOOP TRUE /**< should the heuristic continue to run as long as improvements are found? */
78/*
79 * Data structures
80 */
81
82/** primal heuristic data */
83struct SCIP_HeurData
84{
85 int lastsolindex; /**< index of the last solution for which oneopt was performed */
86 SCIP_Bool weightedobj; /**< should the objective be weighted with the potential shifting value when sorting the shifting candidates? */
87 SCIP_Bool duringroot; /**< should the heuristic be called before and during the root node? */
88 SCIP_Bool forcelpconstruction;/**< should the construction of the LP be forced even if LP solving is deactivated? */
89 SCIP_Bool beforepresol; /**< should the heuristic be called before presolving */
90 SCIP_Bool useloop; /**< should the heuristic continue to run as long as improvements are found? */
91};
92
93
94/*
95 * Local methods
96 */
97
98/** compute value by which the solution of variable @p var can be shifted */
99static
101 SCIP* scip, /**< SCIP data structure */
102 SCIP_VAR* var, /**< variable that should be shifted */
103 SCIP_Real solval, /**< current solution value */
104 SCIP_Real* activities /**< LP row activities */
105 )
106{
107 SCIP_Real lb;
108 SCIP_Real ub;
109 SCIP_Real obj;
110 SCIP_Real newsolval;
111
112 SCIP_COL* col;
113 SCIP_ROW** colrows;
114 SCIP_Real* colvals;
115 SCIP_Bool shiftdown;
116
117 int ncolrows;
118
119 /* get variable's solution value, global bounds and objective coefficient */
120 lb = SCIPvarGetLbGlobal(var);
121 ub = SCIPvarGetUbGlobal(var);
122 obj = SCIPvarGetObj(var);
123 shiftdown = TRUE;
124
125 /* determine shifting direction and maximal possible shifting w.r.t. corresponding bound */
126 if( obj > 0.0 )
127 newsolval = SCIPfeasCeil(scip, lb);
128 else if( obj < 0.0 )
129 {
130 newsolval = SCIPfeasFloor(scip, ub);
131 shiftdown = FALSE;
132 }
133 else
134 newsolval = solval;
135
136 /* newsolval might be bounding solval -> avoid numerical shifting */
137 if( ( shiftdown && SCIPisFeasGE(scip, newsolval, solval) )
138 || ( !shiftdown && SCIPisFeasLE(scip, newsolval, solval) ) )
139 return 0.0;
140
141 SCIPdebugMsg(scip, "Try to shift %s variable <%s> with\n", shiftdown ? "down" : "up", SCIPvarGetName(var) );
142 SCIPdebugMsg(scip, " lb:<%g> <= val:<%g> <= ub:<%g> and obj:<%g> by at most: <%g>\n", lb, solval, ub, obj, newsolval - solval );
143
144 /* get data of LP column */
145 col = SCIPvarGetCol(var);
146 colrows = SCIPcolGetRows(col);
147 colvals = SCIPcolGetVals(col);
148 ncolrows = SCIPcolGetNLPNonz(col);
149
150 assert(ncolrows == 0 || (colrows != NULL && colvals != NULL));
151
152 /* find maximal shift value, st. all rows stay valid */
153 for( int i = 0; i < ncolrows; ++i )
154 {
155 SCIP_ROW* row;
156 int rowpos;
157
158 row = colrows[i];
159 rowpos = SCIProwGetLPPos(row);
160 assert( -1 <= rowpos && rowpos < SCIPgetNLPRows(scip) );
161
162 /* only global rows need to be valid */
163 if( rowpos >= 0 && !SCIProwIsLocal(row) )
164 {
165 SCIP_Real side;
166 SCIP_Bool left;
167
168 left = shiftdown == ( colvals[i] > 0 );
169 side = left ? SCIProwGetLhs(row) : SCIProwGetRhs(row);
170
171 /* only finite bounds need to be considered */
172 if( !SCIPisInfinity(scip, left ? -side : side) )
173 {
174 SCIP_Real newsolvalrow;
175
176 assert( SCIProwIsInLP(row) );
177 newsolvalrow = solval + (side - activities[rowpos]) / colvals[i];
178
179 /* update shifting value */
180 if( ( shiftdown && newsolvalrow > newsolval ) || ( !shiftdown && newsolvalrow < newsolval ) )
181 {
182 SCIP_Real activity;
183
184 activity = activities[rowpos] + colvals[i] * ((shiftdown ? floor(newsolvalrow) : ceil(newsolvalrow)) - solval);
185
186 /* ensure that shifting preserves feasibility */
187 if( shiftdown == ( ( left && SCIPisFeasGE(scip, activity, side) )
188 || ( !left && SCIPisFeasLE(scip, activity, side) ) ) )
189 newsolval = floor(newsolvalrow);
190 else
191 newsolval = ceil(newsolvalrow);
192
193 SCIPdebugMsg(scip, " -> The shift value has to be set to <%g>, because of row <%s>.\n",
194 newsolval - solval, SCIProwGetName(row));
195 SCIPdebugMsg(scip, " lhs:<%g> <= act:<%g> <= rhs:<%g>, colval:<%g>\n",
196 SCIProwGetLhs(row), activities[rowpos], SCIProwGetRhs(row), colvals[i]);
197
198 /* newsolval might have reached solval -> avoid numerical shifting */
199 if( ( shiftdown && SCIPisFeasGE(scip, newsolval, solval) )
200 || ( !shiftdown && SCIPisFeasLE(scip, newsolval, solval) ) )
201 return 0.0;
202 }
203 }
204 }
205 }
206
207 /* we must not shift variables to infinity */
208 return SCIPisInfinity(scip, shiftdown ? -newsolval : newsolval) ? 0.0 : newsolval - solval;
209}
210
211
212/** update row activities after a variable's solution value changed */
213static
215 SCIP* scip, /**< SCIP data structure */
216 SCIP_Real* activities, /**< LP row activities */
217 SCIP_VAR* var, /**< variable that has been changed */
218 SCIP_Real shiftval /**< value that is added to variable */
219 )
220{
221 SCIP_Real* colvals;
222 SCIP_ROW** colrows;
223 SCIP_COL* col;
224
225 int ncolrows;
226
227 assert(activities != NULL);
228
229 /* get data of column associated to variable */
230 col = SCIPvarGetCol(var);
231 colrows = SCIPcolGetRows(col);
232 colvals = SCIPcolGetVals(col);
233 ncolrows = SCIPcolGetNLPNonz(col);
234 assert(ncolrows == 0 || (colrows != NULL && colvals != NULL));
235
236 /* enumerate all rows with nonzero entry in this column */
237 for( int i = 0; i < ncolrows; ++i )
238 {
239 SCIP_ROW* row;
240 int rowpos;
241
242 row = colrows[i];
243 rowpos = SCIProwGetLPPos(row);
244 assert(-1 <= rowpos && rowpos < SCIPgetNLPRows(scip) );
245
246 /* update row activity, only regard global rows in the LP */
247 if( rowpos >= 0 && !SCIProwIsLocal(row) )
248 {
249 activities[rowpos] += shiftval * colvals[i];
250
251 if( SCIPisInfinity(scip, activities[rowpos]) )
252 activities[rowpos] = SCIPinfinity(scip);
253 else if( SCIPisInfinity(scip, -activities[rowpos]) )
254 activities[rowpos] = -SCIPinfinity(scip);
255 }
256 }
257
258 return SCIP_OKAY;
259}
260
261/** setup and solve oneopt sub-SCIP */
262static
264 SCIP* scip, /**< SCIP data structure */
265 SCIP* subscip, /**< sub-SCIP data structure */
266 SCIP_HEUR* heur, /**< oneopt heuristic */
267 SCIP_VAR** vars, /**< SCIP variables */
268 SCIP_VAR** subvars, /**< subproblem's variables */
269 SCIP_SOL* bestsol, /**< incumbent solution */
270 SCIP_RESULT* result, /**< pointer to store the result */
271 SCIP_Bool* valid /**< pointer to store the valid value */
272 )
273{
274 SCIP_HASHMAP* varmapfw; /* mapping of SCIP variables to sub-SCIP variables */
275 SCIP_SOL* startsol;
276 int nvars; /* number of original problem's variables */
277
278 assert(scip != NULL);
279 assert(subscip != NULL);
280 assert(heur != NULL);
281
282 nvars = SCIPgetNVars(scip);
283
284 /* create the variable mapping hash map */
285 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
286
287 /* copy complete SCIP instance */
288 *valid = FALSE;
289 SCIP_CALL( SCIPcopy(scip, subscip, varmapfw, NULL, "oneopt", TRUE, FALSE, FALSE, TRUE, valid) );
290 SCIP_CALL( SCIPtransformProb(subscip) );
291
292 /* get variable image and create start solution for the subproblem */
293 SCIP_CALL( SCIPcreateOrigSol(subscip, &startsol, NULL) );
294 for( int i = 0; i < nvars; ++i )
295 {
296 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
297 if( subvars[i] != NULL )
298 SCIP_CALL( SCIPsetSolVal(subscip, startsol, subvars[i], SCIPgetSolVal(scip, bestsol, vars[i])) );
299 }
300
301 /* try to add new solution to sub-SCIP and free it immediately */
302 *valid = FALSE;
303 SCIP_CALL( SCIPtrySolFree(subscip, &startsol, FALSE, FALSE, FALSE, FALSE, FALSE, valid) );
304 SCIPhashmapFree(&varmapfw);
305
306 /* deactivate basically everything except oneopt in the sub-SCIP */
310
311 /* set limits for the subproblem */
312 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
313 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", 1LL) );
314
315 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
316
317#ifdef SCIP_DEBUG
318 /* for debugging, enable full output */
319 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
320 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 100000000) );
321#else
322 /* disable statistic timing inside sub SCIP and output to console */
323 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
324 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
325#endif
326
327 /* if necessary, some of the parameters have to be unfixed first */
328 if( SCIPisParamFixed(subscip, "lp/solvefreq") )
329 {
330 SCIPwarningMessage(scip, "unfixing parameter lp/solvefreq in subscip of oneopt heuristic\n");
331 SCIP_CALL( SCIPunfixParam(subscip, "lp/solvefreq") );
332 }
333 SCIP_CALL( SCIPsetIntParam(subscip, "lp/solvefreq", -1) );
334
335 if( SCIPisParamFixed(subscip, "heuristics/oneopt/freq") )
336 {
337 SCIPwarningMessage(scip, "unfixing parameter heuristics/oneopt/freq in subscip of oneopt heuristic\n");
338 SCIP_CALL( SCIPunfixParam(subscip, "heuristics/oneopt/freq") );
339 }
340 SCIP_CALL( SCIPsetIntParam(subscip, "heuristics/oneopt/freq", 1) );
341
342 if( SCIPisParamFixed(subscip, "heuristics/oneopt/forcelpconstruction") )
343 {
344 SCIPwarningMessage(scip, "unfixing parameter heuristics/oneopt/forcelpconstruction in subscip of oneopt heuristic\n");
345 SCIP_CALL( SCIPunfixParam(subscip, "heuristics/oneopt/forcelpconstruction") );
346 }
347 SCIP_CALL( SCIPsetBoolParam(subscip, "heuristics/oneopt/forcelpconstruction", TRUE) );
348
349 /* avoid recursive call, which would lead to an endless loop */
350 if( SCIPisParamFixed(subscip, "heuristics/oneopt/beforepresol") )
351 {
352 SCIPwarningMessage(scip, "unfixing parameter heuristics/oneopt/beforepresol in subscip of oneopt heuristic\n");
353 SCIP_CALL( SCIPunfixParam(subscip, "heuristics/oneopt/beforepresol") );
354 }
355 SCIP_CALL( SCIPsetBoolParam(subscip, "heuristics/oneopt/beforepresol", FALSE) );
356
357 /* speed up sub-SCIP by not checking dual LP feasibility */
358 SCIP_CALL( SCIPsetBoolParam(subscip, "lp/checkdualfeas", FALSE) );
359
360 if( *valid )
361 {
362 /* errors in solving the subproblem should not kill the overall solving process;
363 * hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
364 */
365 SCIP_CALL_ABORT( SCIPsolve(subscip) );
366
367#ifdef SCIP_DEBUG
369#endif
370
371 /* check, whether a solution was found;
372 * due to numerics, it might happen that not all solutions are feasible -> try all solutions until one was accepted
373 */
374 SCIP_CALL( SCIPtranslateSubSols(scip, subscip, heur, subvars, valid, NULL) );
375 if( *valid )
376 *result = SCIP_FOUNDSOL;
377 }
378
379 return SCIP_OKAY;
380}
381
382/*
383 * Callback methods of primal heuristic
384 */
385
386/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
387static
388SCIP_DECL_HEURCOPY(heurCopyOneopt)
389{ /*lint --e{715}*/
390 assert(scip != NULL);
391 assert(heur != NULL);
392 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
393
394 /* call inclusion method of primal heuristic */
396
397 return SCIP_OKAY;
398}
399
400/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
401static
402SCIP_DECL_HEURFREE(heurFreeOneopt)
403{ /*lint --e{715}*/
404 SCIP_HEURDATA* heurdata;
405
406 assert(heur != NULL);
407 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
408 assert(scip != NULL);
409
410 /* free heuristic data */
411 heurdata = SCIPheurGetData(heur);
412 assert(heurdata != NULL);
413 SCIPfreeBlockMemory(scip, &heurdata);
414 SCIPheurSetData(heur, NULL);
415
416 return SCIP_OKAY;
417}
418
419
420/** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
421static
422SCIP_DECL_HEURINITSOL(heurInitsolOneopt)
423{
424 SCIP_HEURDATA* heurdata;
425
426 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
427
428 /* create heuristic data */
429 heurdata = SCIPheurGetData(heur);
430 assert(heurdata != NULL);
431
432 /* if the heuristic is called at the root node, we may want to be called during the cut-and-price loop and even before the first LP solve */
433 if( heurdata->duringroot && SCIPheurGetFreqofs(heur) == 0 )
435
436 return SCIP_OKAY;
437}
438
439/** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
440static
441SCIP_DECL_HEUREXITSOL(heurExitsolOneopt)
442{
443 assert(heur != NULL);
444 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
445
446 /* reset the timing mask to its default value */
448
449 return SCIP_OKAY;
450}
451
452/** initialization method of primal heuristic (called after problem was transformed) */
453static
454SCIP_DECL_HEURINIT(heurInitOneopt)
455{ /*lint --e{715}*/
456 SCIP_HEURDATA* heurdata;
457
458 assert(heur != NULL);
459 assert(scip != NULL);
460
461 /* get heuristic data */
462 heurdata = SCIPheurGetData(heur);
463 assert(heurdata != NULL);
464
465 /* initialize last solution index */
466 heurdata->lastsolindex = -1;
467
468 return SCIP_OKAY;
469}
470
471/** execution method of primal heuristic */
472static
473SCIP_DECL_HEUREXEC(heurExecOneopt)
474{ /*lint --e{715}*/
475 SCIP_HEURDATA* heurdata;
476 SCIP_VAR** vars; /* SCIP variables */
477 SCIP_VAR** shiftcands; /* shiftable variables */
478 SCIP_ROW** lprows; /* SCIP LP rows */
479 SCIP_SOL* bestsol; /* incumbent solution */
480 SCIP_SOL* worksol; /* heuristic's working solution */
481 SCIP_Real* activities; /* row activities for working solution */
482 SCIP_Real* shiftvals;
483 SCIP_Bool shifted;
484 SCIP_RETCODE retcode;
485 SCIP_Real lb;
486 SCIP_Real ub;
487 SCIP_Bool valid;
488 int nchgbound;
489 int nvars;
490 int nenfovars;
491 int nlprows;
492 int nshiftcands;
493 int shiftcandssize;
494 int nsuccessfulshifts;
495 int niterations;
496
497 assert(heur != NULL);
498 assert(scip != NULL);
499 assert(result != NULL);
500
501 /* get heuristic's data */
502 heurdata = SCIPheurGetData(heur);
503 assert(heurdata != NULL);
504
505 *result = SCIP_DELAYED;
506
507 /* we only want to process each solution once */
508 bestsol = SCIPgetBestSol(scip);
509 if( bestsol == NULL || heurdata->lastsolindex == SCIPsolGetIndex(bestsol) || SCIPsolIsExact(bestsol) )
510 return SCIP_OKAY;
511
512 /* reset the timing mask to its default value (at the root node it could be different) */
513 if( SCIPgetNNodes(scip) > 1 )
515
516 /* get problem variables */
517 vars = SCIPgetVars(scip);
518 nvars = SCIPgetNVars(scip);
519 nenfovars = nvars - SCIPgetNContVars(scip) - SCIPgetNContImplVars(scip);
520 assert(nenfovars >= 0);
521
522 /* do not run if there are no discrete variables */
523 if( nenfovars == 0 )
524 {
525 *result = SCIP_DIDNOTRUN;
526 return SCIP_OKAY;
527 }
528
529 if( heurtiming == SCIP_HEURTIMING_BEFOREPRESOL )
530 {
531 SCIP* subscip; /* the subproblem created by oneopt */
532 SCIP_VAR** subvars; /* subproblem's variables */
533
534 SCIP_Bool success;
535
536 if( !heurdata->beforepresol )
537 return SCIP_OKAY;
538
539 /* check whether there is enough time and memory left */
540 SCIP_CALL( SCIPcheckCopyLimits(scip, &success) );
541
542 if( !success )
543 return SCIP_OKAY;
544
545 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
546
547 /* initialize the subproblem */
548 SCIP_CALL( SCIPcreate(&subscip) );
549
550 /* setup and solve the subproblem and catch the return code */
551 retcode = setupAndSolveSubscipOneopt(scip, subscip, heur, vars, subvars, bestsol, result, &valid);
552
553 /* free the subscip in any case */
554 SCIP_CALL( SCIPfree(&subscip) );
555 SCIP_CALL( retcode );
556
557 SCIPfreeBufferArray(scip, &subvars);
558
559 return SCIP_OKAY;
560 }
561
562 /* we can only work on solutions valid in the transformed space */
563 if( SCIPsolIsOriginal(bestsol) )
564 return SCIP_OKAY;
565
566 if( heurtiming == SCIP_HEURTIMING_BEFORENODE && (SCIPhasCurrentNodeLP(scip) || heurdata->forcelpconstruction) )
567 {
568 SCIP_Bool cutoff;
569
570 SCIP_CALL( SCIPconstructLP(scip, &cutoff) );
571
572 /* manually cut off the node if the LP construction detected infeasibility (heuristics cannot return such a
573 * result); the cutoff result is safe to use in exact solving mode, but we don't have enough information to
574 * give a certificate for the cutoff
575 */
576 if( cutoff && !SCIPisCertified(scip) )
577 {
579 return SCIP_OKAY;
580 }
581
583
584 /* get problem variables again, SCIPconstructLP() might have added new variables */
585 vars = SCIPgetVars(scip);
586 nvars = SCIPgetNVars(scip);
587 nenfovars = nvars - SCIPgetNContVars(scip) - SCIPgetNContImplVars(scip);
588 assert(nenfovars >= 0);
589 }
590
591 /* we need an LP */
592 if( SCIPgetNLPRows(scip) == 0 )
593 return SCIP_OKAY;
594
595 *result = SCIP_DIDNOTFIND;
596
597 heurdata->lastsolindex = SCIPsolGetIndex(bestsol);
598 SCIP_CALL( SCIPcreateSolCopy(scip, &worksol, bestsol) );
599 SCIPsolSetHeur(worksol,heur);
600
601 SCIPdebugMsg(scip, "Starting bound adjustment in 1-opt heuristic\n");
602
603 nchgbound = 0;
604 /* change solution values due to possible global bound changes first */
605 for( int i = nvars - 1; i >= 0; --i )
606 {
607 SCIP_VAR* var;
608 SCIP_Real solval;
609
610 var = vars[i];
611 lb = SCIPvarGetLbGlobal(var);
612 ub = SCIPvarGetUbGlobal(var);
613
614 solval = SCIPgetSolVal(scip, worksol, var);
615 /* old solution value is smaller than the actual lower bound */
616 if( SCIPisFeasLT(scip, solval, lb) )
617 {
618 /* set the solution value to the global lower bound */
619 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, lb) );
620 ++nchgbound;
621 SCIPdebugMsg(scip, "var <%s> type %d, old solval %g now fixed to lb %g\n", SCIPvarGetName(var), SCIPvarGetType(var), solval, lb);
622 }
623 /* old solution value is greater than the actual upper bound */
624 else if( SCIPisFeasGT(scip, solval, SCIPvarGetUbGlobal(var)) )
625 {
626 /* set the solution value to the global upper bound */
627 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, ub) );
628 ++nchgbound;
629 SCIPdebugMsg(scip, "var <%s> type %d, old solval %g now fixed to ub %g\n", SCIPvarGetName(var), SCIPvarGetType(var), solval, ub);
630 }
631 }
632
633 SCIPdebugMsg(scip, "number of bound changes (due to global bounds) = %d\n", nchgbound);
634
635 SCIP_CALL( SCIPgetLPRowsData(scip, &lprows, &nlprows) );
636 SCIP_CALL( SCIPallocBufferArray(scip, &activities, nlprows) );
637
638 valid = TRUE;
639
640 /* initialize LP row activities */
641 for( int i = 0; i < nlprows; ++i )
642 {
643 SCIP_ROW* row;
644
645 row = lprows[i];
646 assert(SCIProwGetLPPos(row) == i);
647
648 if( !SCIProwIsLocal(row) )
649 {
650 activities[i] = SCIPgetRowSolActivity(scip, row, worksol);
651 SCIPdebugMsg(scip, "Row <%s> has activity %g\n", SCIProwGetName(row), activities[i]);
652 if( SCIPisFeasLT(scip, activities[i], SCIProwGetLhs(row)) || SCIPisFeasGT(scip, activities[i], SCIProwGetRhs(row)) )
653 {
654 valid = FALSE;
656 SCIPdebugMsg(scip, "row <%s> activity %g violates bounds, lhs = %g, rhs = %g\n", SCIProwGetName(row), activities[i], SCIProwGetLhs(row), SCIProwGetRhs(row));
657 break;
658 }
659 }
660 }
661
662 if( !valid )
663 {
664 /** @todo try to correct lp rows */
665 SCIPdebugMsg(scip, "Some global bound changes were not valid in lp rows.\n");
666
667 SCIPfreeBufferArray(scip, &activities);
668 SCIP_CALL( SCIPfreeSol(scip, &worksol) );
669
670 return SCIP_OKAY;
671 }
672
673 /* allocate buffer storage for possible shift candidates */
674 shiftcandssize = 8;
675 SCIP_CALL( SCIPallocBufferArray(scip, &shiftcands, shiftcandssize) );
676 SCIP_CALL( SCIPallocBufferArray(scip, &shiftvals, shiftcandssize) );
677 nsuccessfulshifts = 0;
678 niterations = 0;
679 do
680 {
681 /* initialize data */
682 shifted = FALSE;
683 nshiftcands = 0;
684 ++niterations;
685 SCIPdebugMsg(scip, "Starting 1-opt heuristic iteration #%d\n", niterations);
686
687 /* enumerate all integer variables and find out which of them are shiftable */
688 /* @todo if useloop=TRUE store for each variable which constraint blocked it and only iterate over those variables
689 * in the following rounds for which the constraint slack was increased by previous shifts
690 */
691 for( int i = 0; i < nenfovars; ++i )
692 {
694 {
695 SCIP_Real shiftval;
696 SCIP_Real solval;
697
698 /* find out whether the variable can be shifted */
699 solval = SCIPgetSolVal(scip, worksol, vars[i]);
700 shiftval = calcShiftVal(scip, vars[i], solval, activities);
701
702 /* insert the variable into the list of shifting candidates */
703 if( !SCIPisFeasZero(scip, shiftval) )
704 {
705 SCIPdebugMsg(scip, " -> Variable <%s> can be shifted by <%1.1f> \n", SCIPvarGetName(vars[i]), shiftval);
706
707 if( nshiftcands == shiftcandssize)
708 {
709 shiftcandssize *= 8;
710 SCIP_CALL( SCIPreallocBufferArray(scip, &shiftcands, shiftcandssize) );
711 SCIP_CALL( SCIPreallocBufferArray(scip, &shiftvals, shiftcandssize) );
712 }
713 shiftcands[nshiftcands] = vars[i];
714 shiftvals[nshiftcands] = shiftval;
715 nshiftcands++;
716 }
717 }
718 }
719
720 /* if at least one variable can be shifted, shift variables sorted by their objective */
721 if( nshiftcands > 0 )
722 {
723 SCIP_Real shiftval;
724 SCIP_Real solval;
725 SCIP_VAR* var;
726
727 /* the case that exactly one variable can be shifted is slightly easier */
728 if( nshiftcands == 1 )
729 {
730 var = shiftcands[0];
731 assert(var != NULL);
732 solval = SCIPgetSolVal(scip, worksol, var);
733 shiftval = shiftvals[0];
734 assert(!SCIPisFeasZero(scip,shiftval));
735 SCIPdebugMsg(scip, " Only one shiftcand found, var <%s>, which is now shifted by<%1.1f> \n",
736 SCIPvarGetName(var), shiftval);
737 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, solval+shiftval) );
738 SCIP_CALL( updateRowActivities(scip, activities, var, shiftval) );
739 ++nsuccessfulshifts;
740 }
741 else
742 {
743 SCIP_Real* objcoeffs;
744
745 SCIP_CALL( SCIPallocBufferArray(scip, &objcoeffs, nshiftcands) );
746
747 SCIPdebugMsg(scip, " %d shiftcands found \n", nshiftcands);
748
749 /* sort the variables by their objective, optionally weighted with the shiftval */
750 if( heurdata->weightedobj )
751 {
752 for( int i = 0; i < nshiftcands; ++i )
753 objcoeffs[i] = SCIPvarGetObj(shiftcands[i])*shiftvals[i];
754 }
755 else
756 {
757 for( int i = 0; i < nshiftcands; ++i )
758 objcoeffs[i] = SCIPvarGetObj(shiftcands[i]);
759 }
760
761 /* sort arrays with respect to the first one */
762 SCIPsortRealPtr(objcoeffs, (void**)shiftcands, nshiftcands);
763
764 /* try to shift each variable -> Activities have to be updated */
765 for( int i = 0; i < nshiftcands; ++i )
766 {
767 var = shiftcands[i];
768 assert(var != NULL);
769 solval = SCIPgetSolVal(scip, worksol, var);
770 shiftval = calcShiftVal(scip, var, solval, activities);
771 assert(i > 0 || !SCIPisFeasZero(scip, shiftval));
772 assert(SCIPisFeasGE(scip, solval+shiftval, SCIPvarGetLbGlobal(var)) && SCIPisFeasLE(scip, solval+shiftval, SCIPvarGetUbGlobal(var)));
773
774 /* update data structures for nonzero shift value */
775 if( ! SCIPisFeasZero(scip, shiftval) )
776 {
777 SCIPdebugMsg(scip, " -> Variable <%s> is now shifted by <%1.1f> \n", SCIPvarGetName(vars[i]), shiftval);
778 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, solval+shiftval) );
779 SCIP_CALL( updateRowActivities(scip, activities, var, shiftval) );
780 ++nsuccessfulshifts;
781 }
782 }
783
784 SCIPfreeBufferArray(scip, &objcoeffs);
785 }
786 shifted = TRUE;
787 }
788 }
789 while( heurdata->useloop && shifted );
790
791 if( nsuccessfulshifts > 0 )
792 {
793 /* if the problem is a pure IP, try to install the solution, if it is a MIP, solve LP again to set the continuous
794 * variables to the best possible value
795 */
796 if( nvars == nenfovars || !SCIPhasCurrentNodeLP(scip) || SCIPgetLPSolstat(scip) != SCIP_LPSOLSTAT_OPTIMAL )
797 {
798 SCIP_Bool success;
799
800 /* since activities are maintained iteratively, we cannot guarantee the feasibility of the shiftings and have
801 * to set the checklprows flag to TRUE
802 */
803 SCIP_CALL( SCIPtrySol(scip, worksol, FALSE, FALSE, FALSE, FALSE, TRUE, &success) );
804
805 if( success )
806 {
807 SCIPdebugMsg(scip, "found feasible shifted solution:\n");
808 SCIPdebug( SCIP_CALL( SCIPprintSol(scip, worksol, NULL, FALSE) ) );
809 *result = SCIP_FOUNDSOL;
810 }
811 }
812 else
813 {
814 SCIP_Bool lperror;
815#ifdef NDEBUG
816 SCIP_RETCODE retstat;
817#endif
818
819 SCIPdebugMsg(scip, "shifted solution should be feasible -> solve LP to fix continuous variables to best values\n");
820
821 /* start diving to calculate the LP relaxation */
823
824 /* set the bounds of the variables: fixed for integers, global bounds for continuous */
825 for( int i = 0; i < nvars; ++i )
826 {
828 {
829 SCIP_CALL( SCIPchgVarLbDive(scip, vars[i], SCIPvarGetLbGlobal(vars[i])) );
830 SCIP_CALL( SCIPchgVarUbDive(scip, vars[i], SCIPvarGetUbGlobal(vars[i])) );
831 }
832 }
833 /* apply this after global bounds to not cause an error with intermediate empty domains */
834 for( int i = 0; i < nenfovars; ++i )
835 {
837 {
838 SCIP_Real solval;
839 solval = SCIPgetSolVal(scip, worksol, vars[i]);
840 SCIP_CALL( SCIPchgVarLbDive(scip, vars[i], solval) );
841 SCIP_CALL( SCIPchgVarUbDive(scip, vars[i], solval) );
842 }
843 }
844
845 /* solve LP */
846 SCIPdebugMsg(scip, " -> old LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
847
848 /**@todo in case of an MINLP, if SCIPisNLPConstructed() is TRUE, say, rather solve the NLP instead of the LP */
849 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
850 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
851 */
852#ifdef NDEBUG
853 retstat = SCIPsolveDiveLP(scip, -1, &lperror, NULL);
854 if( retstat != SCIP_OKAY )
855 {
856 SCIPwarningMessage(scip, "Error while solving LP in 1-opt heuristic; LP solve terminated with code <%d>\n",retstat);
857 }
858#else
859 SCIP_CALL( SCIPsolveDiveLP(scip, -1, &lperror, NULL) );
860#endif
861
862 SCIPdebugMsg(scip, " -> new LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
863 SCIPdebugMsg(scip, " -> error=%u, status=%d\n", lperror, SCIPgetLPSolstat(scip));
864
865 /* check if this is a feasible solution */
866 if( !lperror && SCIPgetLPSolstat(scip) == SCIP_LPSOLSTAT_OPTIMAL )
867 {
868 SCIP_Bool success;
869
870 /* copy the current LP solution to the working solution */
871 SCIP_CALL( SCIPlinkLPSol(scip, worksol) );
872
873 /* in exact mode we have to end diving prior to trying the solution */
874 if( SCIPisExact(scip) )
875 {
876 SCIP_CALL( SCIPunlinkSol(scip, worksol) );
878 }
879
880 SCIP_CALL( SCIPtrySol(scip, worksol, FALSE, FALSE, FALSE, FALSE, FALSE, &success) );
881
882 /* check solution for feasibility */
883 if( success )
884 {
885 SCIPdebugMsg(scip, "found feasible shifted solution:\n");
886 SCIPdebug( SCIP_CALL( SCIPprintSol(scip, worksol, NULL, FALSE) ) );
887 *result = SCIP_FOUNDSOL;
888 }
889 }
890
891 /* terminate the diving */
892 if( SCIPinDive(scip) )
893 {
895 }
896 }
897 }
898
899 /* heuristic should not rerun on this incumbent because the heuristic loop finishes only after no further
900 * improvements of the incumbent solution are possible
901 */
902 if( heurdata->useloop )
903 heurdata->lastsolindex = SCIPsolGetIndex(SCIPgetBestSol(scip));
904
905 SCIPfreeBufferArray(scip, &shiftvals);
906 SCIPfreeBufferArray(scip, &shiftcands);
907 SCIPfreeBufferArray(scip, &activities);
908
909 SCIP_CALL( SCIPfreeSol(scip, &worksol) );
910
911 SCIPdebugMsg(scip, "Finished 1-opt heuristic\n");
912
913 return SCIP_OKAY;
914}
915
916/*
917 * primal heuristic specific interface methods
918 */
919
920/** creates the oneopt primal heuristic and includes it in SCIP */
922 SCIP* scip /**< SCIP data structure */
923 )
924{
925 SCIP_HEURDATA* heurdata;
926 SCIP_HEUR* heur;
927
928 /* create Oneopt primal heuristic data */
929 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
930
931 /* include primal heuristic */
934 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecOneopt, heurdata) );
935
936 assert(heur != NULL);
937
938 /* primal heuristic is safe to use in exact solving mode */
939 SCIPheurMarkExact(heur);
940
941 /* set non-NULL pointers to callback methods */
942 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyOneopt) );
943 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeOneopt) );
944 SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolOneopt) );
945 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolOneopt) );
946 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitOneopt) );
947
948 /* add oneopt primal heuristic parameters */
949 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/weightedobj",
950 "should the objective be weighted with the potential shifting value when sorting the shifting candidates?",
951 &heurdata->weightedobj, TRUE, DEFAULT_WEIGHTEDOBJ, NULL, NULL) );
952
953 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/duringroot",
954 "should the heuristic be called before and during the root node?",
955 &heurdata->duringroot, TRUE, DEFAULT_DURINGROOT, NULL, NULL) );
956
957 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/forcelpconstruction",
958 "should the construction of the LP be forced even if LP solving is deactivated?",
959 &heurdata->forcelpconstruction, TRUE, DEFAULT_FORCELPCONSTRUCTION, NULL, NULL) );
960
961 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/beforepresol",
962 "should the heuristic be called before presolving?",
963 &heurdata->beforepresol, TRUE, DEFAULT_BEFOREPRESOL, NULL, NULL) );
964
965 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/useloop",
966 "should the heuristic continue to run as long as improvements are found?",
967 &heurdata->useloop, TRUE, DEFAULT_USELOOP, NULL, NULL) );
968
969 return SCIP_OKAY;
970}
#define NULL
Definition: def.h:248
#define SCIP_Bool
Definition: def.h:91
#define SCIP_Real
Definition: def.h:156
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIP_CALL_ABORT(x)
Definition: def.h:334
#define SCIP_LONGINT_FORMAT
Definition: def.h:148
#define SCIP_CALL(x)
Definition: def.h:355
SCIP_RETCODE SCIPtranslateSubSols(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_Bool *success, int *solindex)
Definition: scip_copy.c:1437
SCIP_RETCODE SCIPcopy(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool threadsafe, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
Definition: scip_copy.c:2865
SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
Definition: scip_copy.c:3249
SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
Definition: scip_copy.c:3292
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip_general.c:402
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip_general.c:370
int SCIPgetNContVars(SCIP *scip)
Definition: scip_prob.c:2569
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:2246
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:2201
int SCIPgetNContImplVars(SCIP *scip)
Definition: scip_prob.c:2522
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
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
Definition: scip_param.c:219
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition: scip_param.c:545
SCIP_RETCODE SCIPsetHeuristics(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip_param.c:930
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip_param.c:487
SCIP_RETCODE SCIPunfixParam(SCIP *scip, const char *name)
Definition: scip_param.c:385
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 SCIPincludeHeurOneopt(SCIP *scip)
Definition: heur_oneopt.c:921
SCIP_Bool SCIPisCertified(SCIP *scip)
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition: lp.c:17555
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition: lp.c:17545
int SCIPcolGetNLPNonz(SCIP_COL *col)
Definition: lp.c:17534
SCIP_Bool SCIPisExact(SCIP *scip)
Definition: scip_exact.c:193
SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
Definition: scip_heur.c:247
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
void SCIPheurSetTimingmask(SCIP_HEUR *heur, SCIP_HEURTIMING timingmask)
Definition: heur.c:1507
SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINITSOL((*heurinitsol)))
Definition: scip_heur.c:231
int SCIPheurGetFreqofs(SCIP_HEUR *heur)
Definition: heur.c:1573
void SCIPheurMarkExact(SCIP_HEUR *heur)
Definition: heur.c:1457
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
Definition: scip_heur.c:199
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1467
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1378
SCIP_RETCODE SCIPchgVarLbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_lp.c:2384
SCIP_RETCODE SCIPchgVarUbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_lp.c:2416
SCIP_RETCODE SCIPstartDive(SCIP *scip)
Definition: scip_lp.c:2206
SCIP_RETCODE SCIPsolveDiveLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_lp.c:2643
SCIP_RETCODE SCIPendDive(SCIP *scip)
Definition: scip_lp.c:2255
SCIP_Bool SCIPinDive(SCIP *scip)
Definition: scip_lp.c:2740
SCIP_RETCODE SCIPflushLP(SCIP *scip)
Definition: scip_lp.c:154
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip_lp.c:87
SCIP_RETCODE SCIPconstructLP(SCIP *scip, SCIP_Bool *cutoff)
Definition: scip_lp.c:130
SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
Definition: scip_lp.c:576
int SCIPgetNLPRows(SCIP *scip)
Definition: scip_lp.c:632
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition: scip_lp.c:174
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:128
#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_Real SCIProwGetLhs(SCIP_ROW *row)
Definition: lp.c:17686
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition: lp.c:17696
int SCIProwGetLPPos(SCIP_ROW *row)
Definition: lp.c:17895
SCIP_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition: lp.c:17795
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
Definition: scip_lp.c:2176
const char * SCIProwGetName(SCIP_ROW *row)
Definition: lp.c:17745
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17917
SCIP_Real SCIPgetRowSolActivity(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip_lp.c:2108
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition: scip_sol.c:2981
SCIP_RETCODE SCIPcreateSolCopy(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol)
Definition: scip_sol.c:884
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:1252
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition: scip_sol.c:2349
SCIP_RETCODE SCIPcreateOrigSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:831
SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1506
SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
Definition: sol.c:4140
int SCIPsolGetIndex(SCIP_SOL *sol)
Definition: sol.c:4290
SCIP_RETCODE SCIPtrySol(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:4012
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 SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1295
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
void SCIPsolSetHeur(SCIP_SOL *sol, SCIP_HEUR *heur)
Definition: sol.c:4304
SCIP_Bool SCIPsolIsExact(SCIP_SOL *sol)
Definition: sol.c:4150
SCIP_RETCODE SCIPtransformProb(SCIP *scip)
Definition: scip_solve.c:232
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip_solve.c:2635
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPcutoffNode(SCIP *scip, SCIP_NODE *node)
Definition: scip_tree.c:436
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition: scip_tree.c:91
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition: var.c:23683
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:23386
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
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:23267
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:24120
void SCIPsortRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
static SCIP_RETCODE setupAndSolveSubscipOneopt(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_VAR **vars, SCIP_VAR **subvars, SCIP_SOL *bestsol, SCIP_RESULT *result, SCIP_Bool *valid)
Definition: heur_oneopt.c:263
#define DEFAULT_FORCELPCONSTRUCTION
Definition: heur_oneopt.c:76
static SCIP_DECL_HEUREXEC(heurExecOneopt)
Definition: heur_oneopt.c:473
#define HEUR_TIMING
Definition: heur_oneopt.c:70
#define HEUR_FREQOFS
Definition: heur_oneopt.c:68
#define HEUR_DESC
Definition: heur_oneopt.c:64
static SCIP_RETCODE updateRowActivities(SCIP *scip, SCIP_Real *activities, SCIP_VAR *var, SCIP_Real shiftval)
Definition: heur_oneopt.c:214
static SCIP_DECL_HEURINITSOL(heurInitsolOneopt)
Definition: heur_oneopt.c:422
#define DEFAULT_WEIGHTEDOBJ
Definition: heur_oneopt.c:73
#define HEUR_DISPCHAR
Definition: heur_oneopt.c:65
#define HEUR_MAXDEPTH
Definition: heur_oneopt.c:69
#define HEUR_PRIORITY
Definition: heur_oneopt.c:66
#define DEFAULT_DURINGROOT
Definition: heur_oneopt.c:74
#define HEUR_NAME
Definition: heur_oneopt.c:63
static SCIP_Real calcShiftVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solval, SCIP_Real *activities)
Definition: heur_oneopt.c:100
static SCIP_DECL_HEURFREE(heurFreeOneopt)
Definition: heur_oneopt.c:402
#define DEFAULT_BEFOREPRESOL
Definition: heur_oneopt.c:75
static SCIP_DECL_HEUREXITSOL(heurExitsolOneopt)
Definition: heur_oneopt.c:441
static SCIP_DECL_HEURCOPY(heurCopyOneopt)
Definition: heur_oneopt.c:388
#define HEUR_FREQ
Definition: heur_oneopt.c:67
static SCIP_DECL_HEURINIT(heurInitOneopt)
Definition: heur_oneopt.c:454
#define HEUR_USESSUBSCIP
Definition: heur_oneopt.c:71
#define DEFAULT_USELOOP
Definition: heur_oneopt.c:77
Improvement heuristic that alters single variable values.
memory allocation routines
public methods for primal heuristics
public methods for LP management
public methods for message output
#define SCIPdebug(x)
Definition: pub_message.h:93
public data structures and miscellaneous methods
methods for sorting joint arrays of various types
public methods for primal CIP solutions
public methods for problem variables
public methods for certified solving
public methods for problem copies
public methods for exact solving
general public methods
public methods for primal heuristic plugins and divesets
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for solutions
public solving methods
public methods for querying solving statistics
public methods for the branch-and-bound tree
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:77
@ SCIP_LPSOLSTAT_OPTIMAL
Definition: type_lp.h:44
@ SCIP_PARAMSETTING_OFF
Definition: type_paramset.h:63
@ 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_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
#define SCIP_HEURTIMING_BEFOREPRESOL
Definition: type_timing.h:92
#define SCIP_HEURTIMING_DURINGLPLOOP
Definition: type_timing.h:81
#define SCIP_HEURTIMING_BEFORENODE
Definition: type_timing.h:80
@ SCIP_VARSTATUS_COLUMN
Definition: type_var.h:53