SCIP Doxygen Documentation
Loading...
Searching...
No Matches
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-2026 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file heur_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
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;
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 */
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
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
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 )
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
394
395 /* call inclusion method of primal heuristic */
397
398 return SCIP_OKAY;
399}
400
401/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
402static
403SCIP_DECL_HEURFREE(heurFreeOneopt)
404{ /*lint --e{715}*/
406
407 assert(heur != NULL);
408 assert(scip != NULL);
409
411
412 /* free heuristic data */
414 assert(heurdata != NULL);
416 SCIPheurSetData(heur, NULL);
417
418 return SCIP_OKAY;
419}
420
421
422/** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
423static
424SCIP_DECL_HEURINITSOL(heurInitsolOneopt)
425{
427
429
430 /* create heuristic data */
432 assert(heurdata != NULL);
433
434 /* 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 */
435 if( heurdata->duringroot && SCIPheurGetFreqofs(heur) == 0 )
437
438 return SCIP_OKAY;
439}
440
441/** solving process deinitialization method of primal heuristic (called before branch and bound process data is freed) */
442static
443SCIP_DECL_HEUREXITSOL(heurExitsolOneopt)
444{
445 assert(heur != NULL);
446
448
449 /* reset the timing mask to its default value */
451
452 return SCIP_OKAY;
453}
454
455/** initialization method of primal heuristic (called after problem was transformed) */
456static
457SCIP_DECL_HEURINIT(heurInitOneopt)
458{ /*lint --e{715}*/
460
461 assert(heur != NULL);
462 assert(scip != NULL);
463
464 /* get heuristic data */
466 assert(heurdata != NULL);
467
468 /* initialize last solution index */
469 heurdata->lastsolindex = -1;
470
471 return SCIP_OKAY;
472}
473
474/** execution method of primal heuristic */
475static
476SCIP_DECL_HEUREXEC(heurExecOneopt)
477{ /*lint --e{715}*/
479 SCIP_VAR** vars; /* SCIP variables */
480 SCIP_VAR** shiftcands; /* shiftable variables */
481 SCIP_ROW** lprows; /* SCIP LP rows */
482 SCIP_SOL* bestsol; /* incumbent solution */
483 SCIP_SOL* worksol; /* heuristic's working solution */
484 SCIP_Real* activities; /* row activities for working solution */
485 SCIP_Real* shiftvals;
486 SCIP_Bool shifted;
487 SCIP_RETCODE retcode;
488 SCIP_Real lb;
489 SCIP_Real ub;
491 int nchgbound;
492 int nvars;
493 int nenfovars;
494 int nlprows;
495 int nshiftcands;
496 int shiftcandssize;
497 int nsuccessfulshifts;
498 int niterations;
499
500 assert(heur != NULL);
501 assert(scip != NULL);
502 assert(result != NULL);
503
504 /* get heuristic's data */
506 assert(heurdata != NULL);
507
509
510 /* we only want to process each solution once */
511 bestsol = SCIPgetBestSol(scip);
512 if( bestsol == NULL || heurdata->lastsolindex == SCIPsolGetIndex(bestsol) || SCIPsolIsExact(bestsol) )
513 return SCIP_OKAY;
514
515 /* reset the timing mask to its default value (at the root node it could be different) */
516 if( SCIPgetNNodes(scip) > 1 )
518
519 /* get problem variables */
523 assert(nenfovars >= 0);
524
525 /* do not run if there are no discrete variables */
526 if( nenfovars == 0 )
527 {
529 return SCIP_OKAY;
530 }
531
532 if( heurtiming == SCIP_HEURTIMING_BEFOREPRESOL )
533 {
534 SCIP* subscip; /* the subproblem created by oneopt */
535 SCIP_VAR** subvars; /* subproblem's variables */
536
537 SCIP_Bool success;
538
539 if( !heurdata->beforepresol )
540 return SCIP_OKAY;
541
542 /* check whether there is enough time and memory left */
543 SCIP_CALL( SCIPcheckCopyLimits(scip, &success) );
544
545 if( !success )
546 return SCIP_OKAY;
547
549
550 /* initialize the subproblem */
551 SCIP_CALL( SCIPcreate(&subscip) );
552
553 /* setup and solve the subproblem and catch the return code */
554 retcode = setupAndSolveSubscipOneopt(scip, subscip, heur, vars, subvars, bestsol, result, &valid);
555
556 /* free the subscip in any case */
557 SCIP_CALL( SCIPfree(&subscip) );
558 SCIP_CALL( retcode );
559
560 SCIPfreeBufferArray(scip, &subvars);
561
562 return SCIP_OKAY;
563 }
564
565 /* we can only work on solutions valid in the transformed space */
566 if( SCIPsolIsOriginal(bestsol) )
567 return SCIP_OKAY;
568
569 if( heurtiming == SCIP_HEURTIMING_BEFORENODE && (SCIPhasCurrentNodeLP(scip) || heurdata->forcelpconstruction) )
570 {
572
574
575 /* manually cut off the node if the LP construction detected infeasibility (heuristics cannot return such a
576 * result); the cutoff result is safe to use in exact solving mode, but we don't have enough information to
577 * give a certificate for the cutoff
578 */
579 if( cutoff && !SCIPisCertified(scip) )
580 {
582 return SCIP_OKAY;
583 }
584
586
587 /* get problem variables again, SCIPconstructLP() might have added new variables */
591 assert(nenfovars >= 0);
592 }
593
594 /* we need an LP */
595 if( SCIPgetNLPRows(scip) == 0 )
596 return SCIP_OKAY;
597
599
600 heurdata->lastsolindex = SCIPsolGetIndex(bestsol);
601 SCIP_CALL( SCIPcreateSolCopy(scip, &worksol, bestsol) );
602 SCIPsolSetHeur(worksol,heur);
603
604 SCIPdebugMsg(scip, "Starting bound adjustment in 1-opt heuristic\n");
605
606 nchgbound = 0;
607 /* change solution values due to possible global bound changes first */
608 for( int i = nvars - 1; i >= 0; --i )
609 {
610 SCIP_VAR* var;
611 SCIP_Real solval;
612
613 var = vars[i];
616
617 solval = SCIPgetSolVal(scip, worksol, var);
618 /* old solution value is smaller than the actual lower bound */
619 if( SCIPisFeasLT(scip, solval, lb) )
620 {
621 /* set the solution value to the global lower bound */
622 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, lb) );
623 ++nchgbound;
624 SCIPdebugMsg(scip, "var <%s> type %d, old solval %g now fixed to lb %g\n", SCIPvarGetName(var), SCIPvarGetType(var), solval, lb);
625 }
626 /* old solution value is greater than the actual upper bound */
627 else if( SCIPisFeasGT(scip, solval, SCIPvarGetUbGlobal(var)) )
628 {
629 /* set the solution value to the global upper bound */
630 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, ub) );
631 ++nchgbound;
632 SCIPdebugMsg(scip, "var <%s> type %d, old solval %g now fixed to ub %g\n", SCIPvarGetName(var), SCIPvarGetType(var), solval, ub);
633 }
634 }
635
636 SCIPdebugMsg(scip, "number of bound changes (due to global bounds) = %d\n", nchgbound);
637
640
641 valid = TRUE;
642
643 /* initialize LP row activities */
644 for( int i = 0; i < nlprows; ++i )
645 {
646 SCIP_ROW* row;
647
648 row = lprows[i];
649 assert(SCIProwGetLPPos(row) == i);
650
651 if( !SCIProwIsLocal(row) )
652 {
653 activities[i] = SCIPgetRowSolActivity(scip, row, worksol);
654 SCIPdebugMsg(scip, "Row <%s> has activity %g\n", SCIProwGetName(row), activities[i]);
656 {
657 valid = FALSE;
659 SCIPdebugMsg(scip, "row <%s> activity %g violates bounds, lhs = %g, rhs = %g\n", SCIProwGetName(row), activities[i], SCIProwGetLhs(row), SCIProwGetRhs(row));
660 break;
661 }
662 }
663 }
664
665 if( !valid )
666 {
667 /** @todo try to correct lp rows */
668 SCIPdebugMsg(scip, "Some global bound changes were not valid in lp rows.\n");
669
671 SCIP_CALL( SCIPfreeSol(scip, &worksol) );
672
673 return SCIP_OKAY;
674 }
675
676 /* allocate buffer storage for possible shift candidates */
677 shiftcandssize = 8;
678 SCIP_CALL( SCIPallocBufferArray(scip, &shiftcands, shiftcandssize) );
679 SCIP_CALL( SCIPallocBufferArray(scip, &shiftvals, shiftcandssize) );
680 nsuccessfulshifts = 0;
681 niterations = 0;
682 do
683 {
684 /* initialize data */
685 shifted = FALSE;
686 nshiftcands = 0;
687 ++niterations;
688 SCIPdebugMsg(scip, "Starting 1-opt heuristic iteration #%d\n", niterations);
689
690 /* enumerate all integer variables and find out which of them are shiftable */
691 /* @todo if useloop=TRUE store for each variable which constraint blocked it and only iterate over those variables
692 * in the following rounds for which the constraint slack was increased by previous shifts
693 */
694 for( int i = 0; i < nenfovars; ++i )
695 {
697 {
698 SCIP_Real shiftval;
699 SCIP_Real solval;
700
701 /* find out whether the variable can be shifted */
702 solval = SCIPgetSolVal(scip, worksol, vars[i]);
703 shiftval = calcShiftVal(scip, vars[i], solval, activities);
704
705 /* insert the variable into the list of shifting candidates */
706 if( !SCIPisFeasZero(scip, shiftval) )
707 {
708 SCIPdebugMsg(scip, " -> Variable <%s> can be shifted by <%1.1f> \n", SCIPvarGetName(vars[i]), shiftval);
709
710 if( nshiftcands == shiftcandssize)
711 {
712 shiftcandssize *= 8;
713 SCIP_CALL( SCIPreallocBufferArray(scip, &shiftcands, shiftcandssize) );
714 SCIP_CALL( SCIPreallocBufferArray(scip, &shiftvals, shiftcandssize) );
715 }
716 shiftcands[nshiftcands] = vars[i];
717 shiftvals[nshiftcands] = shiftval;
718 nshiftcands++;
719 }
720 }
721 }
722
723 /* if at least one variable can be shifted, shift variables sorted by their objective */
724 if( nshiftcands > 0 )
725 {
726 SCIP_Real shiftval;
727 SCIP_Real solval;
728 SCIP_VAR* var;
729
730 /* the case that exactly one variable can be shifted is slightly easier */
731 if( nshiftcands == 1 )
732 {
733 var = shiftcands[0];
734 assert(var != NULL);
735 solval = SCIPgetSolVal(scip, worksol, var);
736 shiftval = shiftvals[0];
737 assert(!SCIPisFeasZero(scip,shiftval));
738 SCIPdebugMsg(scip, " Only one shiftcand found, var <%s>, which is now shifted by<%1.1f> \n",
739 SCIPvarGetName(var), shiftval);
740 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, solval+shiftval) );
742 ++nsuccessfulshifts;
743 }
744 else
745 {
746 SCIP_Real* objcoeffs;
747
748 SCIP_CALL( SCIPallocBufferArray(scip, &objcoeffs, nshiftcands) );
749
750 SCIPdebugMsg(scip, " %d shiftcands found \n", nshiftcands);
751
752 /* sort the variables by their objective, optionally weighted with the shiftval */
753 if( heurdata->weightedobj )
754 {
755 for( int i = 0; i < nshiftcands; ++i )
756 objcoeffs[i] = SCIPvarGetObj(shiftcands[i])*shiftvals[i];
757 }
758 else
759 {
760 for( int i = 0; i < nshiftcands; ++i )
761 objcoeffs[i] = SCIPvarGetObj(shiftcands[i]);
762 }
763
764 /* sort arrays with respect to the first one */
765 SCIPsortRealPtr(objcoeffs, (void**)shiftcands, nshiftcands);
766
767 /* try to shift each variable -> Activities have to be updated */
768 for( int i = 0; i < nshiftcands; ++i )
769 {
770 var = shiftcands[i];
771 assert(var != NULL);
772 solval = SCIPgetSolVal(scip, worksol, var);
773 shiftval = calcShiftVal(scip, var, solval, activities);
774 assert(i > 0 || !SCIPisFeasZero(scip, shiftval));
775 assert(SCIPisFeasGE(scip, solval+shiftval, SCIPvarGetLbGlobal(var)) && SCIPisFeasLE(scip, solval+shiftval, SCIPvarGetUbGlobal(var)));
776
777 /* update data structures for nonzero shift value */
778 if( ! SCIPisFeasZero(scip, shiftval) )
779 {
780 SCIPdebugMsg(scip, " -> Variable <%s> is now shifted by <%1.1f> \n", SCIPvarGetName(vars[i]), shiftval);
781 SCIP_CALL( SCIPsetSolVal(scip, worksol, var, solval+shiftval) );
783 ++nsuccessfulshifts;
784 }
785 }
786
787 SCIPfreeBufferArray(scip, &objcoeffs);
788 }
789 shifted = TRUE;
790 }
791 }
792 while( heurdata->useloop && shifted );
793
794 if( nsuccessfulshifts > 0 )
795 {
796 /* if the problem is a pure IP, try to install the solution, if it is a MIP, solve LP again to set the continuous
797 * variables to the best possible value
798 */
800 {
801 SCIP_Bool success;
802
803 /* since activities are maintained iteratively, we cannot guarantee the feasibility of the shiftings and have
804 * to set the checklprows flag to TRUE
805 */
806 SCIP_CALL( SCIPtrySol(scip, worksol, FALSE, FALSE, FALSE, FALSE, TRUE, &success) );
807
808 if( success )
809 {
810 SCIPdebugMsg(scip, "found feasible shifted solution:\n");
811 SCIPdebug( SCIP_CALL( SCIPprintSol(scip, worksol, NULL, FALSE) ) );
813 }
814 }
815 else
816 {
818#ifdef NDEBUG
819 SCIP_RETCODE retstat;
820#endif
821
822 SCIPdebugMsg(scip, "shifted solution should be feasible -> solve LP to fix continuous variables to best values\n");
823
824 /* start diving to calculate the LP relaxation */
826
827 /* set the bounds of the variables: fixed for integers, global bounds for continuous */
828 for( int i = 0; i < nvars; ++i )
829 {
831 {
834 }
835 }
836 /* apply this after global bounds to not cause an error with intermediate empty domains */
837 for( int i = 0; i < nenfovars; ++i )
838 {
840 {
841 SCIP_Real solval;
842 solval = SCIPgetSolVal(scip, worksol, vars[i]);
843 SCIP_CALL( SCIPchgVarLbDive(scip, vars[i], solval) );
844 SCIP_CALL( SCIPchgVarUbDive(scip, vars[i], solval) );
845 }
846 }
847
848 /* solve LP */
849 SCIPdebugMsg(scip, " -> old LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
850
851 /**@todo in case of an MINLP, if SCIPisNLPConstructed() is TRUE, say, rather solve the NLP instead of the LP */
852 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
853 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
854 */
855#ifdef NDEBUG
856 retstat = SCIPsolveDiveLP(scip, -1, &lperror, NULL);
857 if( retstat != SCIP_OKAY )
858 {
859 SCIPwarningMessage(scip, "Error while solving LP in 1-opt heuristic; LP solve terminated with code <%d>\n",retstat);
860 }
861#else
863#endif
864
865 SCIPdebugMsg(scip, " -> new LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
866 SCIPdebugMsg(scip, " -> error=%u, status=%d\n", lperror, SCIPgetLPSolstat(scip));
867
868 /* check if this is a feasible solution */
870 {
871 SCIP_Bool success;
872
873 /* copy the current LP solution to the working solution */
874 SCIP_CALL( SCIPlinkLPSol(scip, worksol) );
875
876 /* in exact mode we have to end diving prior to trying the solution */
877 if( SCIPisExact(scip) )
878 {
879 SCIP_CALL( SCIPunlinkSol(scip, worksol) );
881 }
882
883 SCIP_CALL( SCIPtrySol(scip, worksol, FALSE, FALSE, FALSE, FALSE, FALSE, &success) );
884
885 /* check solution for feasibility */
886 if( success )
887 {
888 SCIPdebugMsg(scip, "found feasible shifted solution:\n");
889 SCIPdebug( SCIP_CALL( SCIPprintSol(scip, worksol, NULL, FALSE) ) );
891 }
892 }
893
894 /* terminate the diving */
895 if( SCIPinDive(scip) )
896 {
898 }
899 }
900 }
901
902 /* heuristic should not rerun on this incumbent because the heuristic loop finishes only after no further
903 * improvements of the incumbent solution are possible
904 */
905 if( heurdata->useloop )
907
908 SCIPfreeBufferArray(scip, &shiftvals);
909 SCIPfreeBufferArray(scip, &shiftcands);
911
912 SCIP_CALL( SCIPfreeSol(scip, &worksol) );
913
914 SCIPdebugMsg(scip, "Finished 1-opt heuristic\n");
915
916 return SCIP_OKAY;
917}
918
919/*
920 * primal heuristic specific interface methods
921 */
922
923/** creates the oneopt primal heuristic and includes it in SCIP */
925 SCIP* scip /**< SCIP data structure */
926 )
927{
929 SCIP_HEUR* heur;
930
931 /* create Oneopt primal heuristic data */
933
934 /* include primal heuristic */
938
939 assert(heur != NULL);
940
941 /* primal heuristic is safe to use in exact solving mode */
942 SCIPheurMarkExact(heur);
943
944 /* set non-NULL pointers to callback methods */
945 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyOneopt) );
946 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeOneopt) );
947 SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolOneopt) );
948 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolOneopt) );
949 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitOneopt) );
950
951 /* add oneopt primal heuristic parameters */
952 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/weightedobj",
953 "should the objective be weighted with the potential shifting value when sorting the shifting candidates?",
954 &heurdata->weightedobj, TRUE, DEFAULT_WEIGHTEDOBJ, NULL, NULL) );
955
956 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/duringroot",
957 "should the heuristic be called before and during the root node?",
958 &heurdata->duringroot, TRUE, DEFAULT_DURINGROOT, NULL, NULL) );
959
960 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/forcelpconstruction",
961 "should the construction of the LP be forced even if LP solving is deactivated?",
962 &heurdata->forcelpconstruction, TRUE, DEFAULT_FORCELPCONSTRUCTION, NULL, NULL) );
963
964 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/beforepresol",
965 "should the heuristic be called before presolving?",
966 &heurdata->beforepresol, TRUE, DEFAULT_BEFOREPRESOL, NULL, NULL) );
967
968 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/oneopt/useloop",
969 "should the heuristic continue to run as long as improvements are found?",
970 &heurdata->useloop, TRUE, DEFAULT_USELOOP, NULL, NULL) );
971
972 return SCIP_OKAY;
973}
#define NULL
Definition def.h:257
#define SCIP_Bool
Definition def.h:100
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define SCIP_CALL_ABORT(x)
Definition def.h:343
#define SCIP_LONGINT_FORMAT
Definition def.h:157
#define SCIP_CALL(x)
Definition def.h:364
SCIP_RETCODE SCIPtranslateSubSols(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_Bool *success, int *solindex)
Definition scip_copy.c:1438
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:2866
SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
Definition scip_copy.c:3250
SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
Definition scip_copy.c:3293
SCIP_RETCODE SCIPfree(SCIP **scip)
SCIP_RETCODE SCIPcreate(SCIP **scip)
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
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
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)
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 SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:183
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition heur.c:1368
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition scip_heur.c:122
SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:231
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:167
void SCIPheurSetTimingmask(SCIP_HEUR *heur, SCIP_HEURTIMING timingmask)
Definition heur.c:1507
int SCIPheurGetFreqofs(SCIP_HEUR *heur)
Definition heur.c:1573
SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:247
void SCIPheurMarkExact(SCIP_HEUR *heur)
Definition heur.c:1457
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:199
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition heur.c:1467
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition heur.c:1378
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:2986
SCIP_RETCODE SCIPcreateSolCopy(SCIP *scip, SCIP_SOL **sol, SCIP_SOL *sourcesol)
Definition scip_sol.c:882
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition scip_sol.c:2351
SCIP_RETCODE SCIPcreateOrigSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition scip_sol.c:829
SCIP_RETCODE SCIPunlinkSol(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:1504
SCIP_Bool SCIPsolIsOriginal(SCIP_SOL *sol)
Definition sol.c:4155
int SCIPsolGetIndex(SCIP_SOL *sol)
Definition sol.c:4305
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:4017
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:4114
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
Definition scip_sol.c:1569
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1763
void SCIPsolSetHeur(SCIP_SOL *sol, SCIP_HEUR *heur)
Definition sol.c:4319
SCIP_Bool SCIPsolIsExact(SCIP_SOL *sol)
Definition sol.c:4165
SCIP_RETCODE SCIPtransformProb(SCIP *scip)
Definition scip_solve.c:232
SCIP_RETCODE SCIPsolve(SCIP *scip)
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:23715
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition var.c:23418
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:23932
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition var.c:23485
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:24174
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23299
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:24152
void SCIPsortRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
#define HEUR_TIMING
return SCIP_OKAY
#define HEUR_FREQOFS
#define HEUR_DESC
#define HEUR_DISPCHAR
#define HEUR_MAXDEPTH
#define HEUR_PRIORITY
SCIPfreeSol(scip, &heurdata->sol))
#define HEUR_NAME
#define HEUR_FREQ
#define HEUR_USESSUBSCIP
#define DEFAULT_BEFOREPRESOL
SCIP_Bool lperror
SCIP_Bool cutoff
int nlprows
SCIP_ROW ** lprows
SCIP_Real obj
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIPlinkLPSol(scip, sol))
SCIP_VAR * var
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)
#define DEFAULT_FORCELPCONSTRUCTION
Definition heur_oneopt.c:76
static SCIP_RETCODE updateRowActivities(SCIP *scip, SCIP_Real *activities, SCIP_VAR *var, SCIP_Real shiftval)
#define DEFAULT_WEIGHTEDOBJ
Definition heur_oneopt.c:73
#define DEFAULT_DURINGROOT
Definition heur_oneopt.c:74
static SCIP_Real calcShiftVal(SCIP *scip, SCIP_VAR *var, SCIP_Real solval, SCIP_Real *activities)
#define DEFAULT_USELOOP
Definition heur_oneopt.c:77
Improvement heuristic that alters single variable values.
int nenfovars
static SCIP_VAR ** vars
SCIP_Real * activities
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
#define SCIP_DECL_HEURINITSOL(x)
Definition type_heur.h:132
#define SCIP_DECL_HEURCOPY(x)
Definition type_heur.h:97
struct SCIP_HeurData SCIP_HEURDATA
Definition type_heur.h:77
struct SCIP_Heur SCIP_HEUR
Definition type_heur.h:76
#define SCIP_DECL_HEURINIT(x)
Definition type_heur.h:113
#define SCIP_DECL_HEURFREE(x)
Definition type_heur.h:105
#define SCIP_DECL_HEUREXITSOL(x)
Definition type_heur.h:143
#define SCIP_DECL_HEUREXEC(x)
Definition type_heur.h:163
struct SCIP_Row SCIP_ROW
Definition type_lp.h:105
struct SCIP_Col SCIP_COL
Definition type_lp.h:99
@ SCIP_LPSOLSTAT_OPTIMAL
Definition type_lp.h:44
struct SCIP_HashMap SCIP_HASHMAP
Definition type_misc.h:106
@ SCIP_PARAMSETTING_OFF
@ 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_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
#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
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_VARSTATUS_COLUMN
Definition type_var.h:53