SCIP Doxygen Documentation
Loading...
Searching...
No Matches
heur_locks.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_locks.c
26 * @ingroup DEFPLUGINS_HEUR
27 * @brief rounding locks primal heuristic
28 * @author Michael Winkler
29 * @author Gerald Gamrath
30 */
31
32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33
35#include "scip/heur_locks.h"
36#include "scip/pub_cons.h"
37#include "scip/pub_heur.h"
38#include "scip/pub_lp.h"
39#include "scip/pub_message.h"
40#include "scip/pub_misc.h"
41#include "scip/pub_var.h"
42#include "scip/scip_branch.h"
44#include "scip/scip_cons.h"
45#include "scip/scip_copy.h"
46#include "scip/scip_exact.h"
47#include "scip/scip_general.h"
48#include "scip/scip_heur.h"
49#include "scip/scip_lp.h"
50#include "scip/scip_mem.h"
51#include "scip/scip_message.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"
57#include "scip/scip_sol.h"
58#include "scip/scip_solve.h"
60#include "scip/scip_timing.h"
61#include "scip/scip_tree.h"
62#include <string.h>
63
64#define HEUR_NAME "locks"
65#define HEUR_DESC "heuristic that fixes variables based on their rounding locks"
66#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_PROP
67#define HEUR_PRIORITY 3000
68#define HEUR_FREQ 0
69#define HEUR_FREQOFS 0
70#define HEUR_MAXDEPTH -1
71#define HEUR_TIMING SCIP_HEURTIMING_BEFORENODE
72#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
73
74#define DEFAULT_MAXNODES 5000LL /**< maximum number of nodes to regard in the subproblem */
75#define DEFAULT_ROUNDUPPROBABILITY 0.67 /**< probability for rounding a variable up in case of ties */
76#define DEFAULT_MINFIXINGRATE 0.65 /**< minimum percentage of variables that have to be fixed */
77#define DEFAULT_MINIMPROVE 0.01 /**< factor by which locks heuristic should at least improve the
78 * incumbent */
79#define DEFAULT_MINNODES 500LL /**< minimum number of nodes to regard in the subproblem */
80#define DEFAULT_NODESOFS 500LL /**< number of nodes added to the contingent of the total nodes */
81#define DEFAULT_NODESQUOT 0.1 /**< subproblem nodes in relation to nodes of the original problem */
82#define DEFAULT_MAXPROPROUNDS 2 /**< maximum number of propagation rounds during probing */
83#define DEFAULT_UPDATELOCKS TRUE /**< should the locks be updated based on LP rows? */
84#define DEFAULT_COPYCUTS TRUE /**< should all active cuts from the cutpool of the
85 * original scip be copied to constraints of the subscip? */
86#define DEFAULT_USEFINALSUBMIP TRUE /**< should a final sub-MIP be solved to construct a feasible
87 * solution if the LP was not roundable? */
88#define DEFAULT_RANDSEED 73 /**< initial random seed */
89#define DEFAULT_MINFIXINGRATELP 0.0 /**< minimum fixing rate over all variables (including continuous)
90 * to solve LP */
91
92/** primal heuristic data */
93struct SCIP_HeurData
94{
95 SCIP_RANDNUMGEN* randnumgen; /**< random number generation */
96 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
97 SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
98 SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
99 SCIP_Longint usednodes; /**< nodes already used by locks heuristic in earlier calls */
100 SCIP_Real roundupprobability; /**< probability for rounding a variable up in case of ties */
101 SCIP_Real minfixingrate; /**< minimum percentage of variables that have to be fixed */
102 SCIP_Real minfixingratelp; /**< minimum fixing rate over all variables (including continuous) to solve LP */
103 SCIP_Real minimprove; /**< factor by which locks heuristic should at least improve the incumbent */
104 SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
105 int maxproprounds; /**< maximum number of propagation rounds during probing */
106 SCIP_Bool updatelocks; /**< should the locks be updated based on LP rows? */
107 SCIP_Bool copycuts; /**< should all active cuts from cutpool be copied to constraints in
108 * the subproblem? */
109 SCIP_Bool usefinalsubmip; /**< should a final sub-MIP be solved to construct a feasible solution if
110 * the LP was not roundable? */
111};
112
113/*
114 * Local methods
115 */
116
117/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
118static
119SCIP_DECL_HEURCOPY(heurCopyLocks)
120{ /*lint --e{715}*/
121 assert(scip != NULL);
122 assert(heur != NULL);
123 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
124
125 /* call inclusion method of primal heuristic */
127
128 return SCIP_OKAY;
129}
130
131/** free method for primal heuristic plugins (called when SCIP is exiting) */
132static
133SCIP_DECL_HEURFREE(heurFreeLocks)
134{ /*lint --e{715}*/
136
137 assert(scip != NULL);
138 assert(heur != NULL);
139 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
140
142
143 /* free primal heuristic data */
145
146 return SCIP_OKAY;
147}
148
149/** initialization method of primal heuristic (called after problem was transformed) */
150static
151SCIP_DECL_HEURINIT(heurInitLocks) /*lint --e{715}*/
152{ /*lint --e{715}*/
154
155 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
158
159 /* initialize data */
160 heurdata->usednodes = 0;
161
162 /* create random number generator */
165
166 return SCIP_OKAY;
167}
168
169/** deinitialization method of primal heuristic (called before transformed problem is freed) */
170static
171SCIP_DECL_HEUREXIT(heurExitLocks) /*lint --e{715}*/
172{ /*lint --e{715}*/
174
175 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
176
177 /* free heuristic data */
179 assert(heurdata != NULL);
180
181 /* free random number generator */
183
184 return SCIP_OKAY;
185}
186
187/** apply fix-and-propagate scheme based on variable locks
188 *
189 * @note probing mode of SCIP needs to be enabled before
190 */
192 SCIP* scip, /**< SCIP data structure */
193 SCIP_HEURDATA* heurdata, /**< primal heuristic data */
194 SCIP_Bool* cutoff, /**< pointer to store if a cutoff was detected */
195 SCIP_Bool* allrowsfulfilled /**< pointer to store if all rows became redundant */
196 )
197{
199 SCIP_VAR** vars;
200 SCIP_VAR** sortvars;
201 SCIP_Real* minact;
202 SCIP_Real* maxact;
203 SCIP_Bool* fulfilled;
204 SCIP_VAR* var;
205 SCIP_ROW* row;
206 SCIP_COL* col;
207 SCIP_ROW** colrows;
208 SCIP_Real* colvals;
209 int ncolrows;
210 int* ndownlocks;
211 int* nuplocks;
212 int* varpos = NULL;
213 SCIP_Real lastfixval;
214 SCIP_Real randnumber;
215 SCIP_Real roundupprobability;
217 SCIP_Bool propagated;
218 SCIP_Bool haslhs;
219 SCIP_Bool hasrhs;
220 SCIP_Bool updatelocks;
221 int lastfixlocks;
222 int maxproprounds;
223 int nglbfulfilledrows;
224 int rowpos;
225 int nbinvars;
226 int nvars;
227 int nlprows;
228 int nfulfilledrows;
229 int bestpos;
230 int lastbestscore;
231 int bestscore;
232 int score;
233 int v;
234 int r;
235 int i;
236
237 assert(scip != NULL);
238 assert(cutoff != NULL);
239 assert(allrowsfulfilled != NULL);
241
242 if( heurdata == NULL )
243 {
246 }
247 assert(heurdata != NULL);
248
249 *cutoff = FALSE;
250 *allrowsfulfilled = FALSE;
251
252 propagate = (heurdata->maxproprounds != 0);
253
254 if( heurdata->maxproprounds == -2 )
255 maxproprounds = 0;
256 else
257 maxproprounds = heurdata->maxproprounds;
258
259 roundupprobability = heurdata->roundupprobability;
260
261 updatelocks = heurdata->updatelocks && (SCIPgetNCheckConss(scip) == SCIPgetNLPRows(scip));
262
263 SCIPdebugMsg(scip, "%d constraints: %d logicor, updatelocks=%u\n", SCIPgetNConss(scip), SCIPconshdlrGetNCheckConss(SCIPfindConshdlr(scip, "logicor")), updatelocks);
264
265 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, NULL, NULL, NULL) );
266 assert(vars != NULL);
267
268 /* allocate memory */
269 SCIP_CALL( SCIPduplicateBufferArray(scip, &sortvars, vars, nbinvars) );
270 SCIP_CALL( SCIPallocBufferArray(scip, &nuplocks, nbinvars) );
271 SCIP_CALL( SCIPallocBufferArray(scip, &ndownlocks, nbinvars) );
272
273 /* get LP data */
278
279 /* @todo add objective value as second sorting criteria */
280
281 nglbfulfilledrows = 0;
282
283 /* get locks of variables */
284 for( v = 0; v < nbinvars; ++v )
285 {
286 var = sortvars[v];
289 }
290
291 /* get activities of rows */
292 for( r = 0; r < nlprows; ++r )
293 {
294 row = lprows[r];
295 assert(SCIProwGetLPPos(row) == r);
296
297 /* no trivial rows */
299
300 minact[r] = SCIPgetRowMinActivity(scip, row);
301 maxact[r] = SCIPgetRowMaxActivity(scip, row);
302 }
303
304 propagated = TRUE;
305 lastbestscore = INT_MAX;
306
307 /* fix variables */
308 for( v = 0; v < nbinvars; v++ )
309 {
310 if( SCIPisStopped(scip) )
311 break;
312
313 assert(!(*cutoff));
314
315 nfulfilledrows = 0;
316
317 while( v < nbinvars && (SCIPvarGetLbLocal(sortvars[v]) > 0.5 || SCIPvarGetUbLocal(sortvars[v]) < 0.5) )
318 {
319 ++v;
320 }
321 if( v == nbinvars )
322 break;
323
324 bestpos = v;
325 bestscore = nuplocks[v] + ndownlocks[v];
326
327 /* get best variable */
328 if( bestscore < lastbestscore )
329 {
330 for( i = v + 1; i < nbinvars; ++i )
331 {
332 var = sortvars[i];
333
334 /* variable is already fixed; move it to the front and increment v to ignore it */
335 if( SCIPvarGetLbLocal(var) > 0.5 || SCIPvarGetUbLocal(var) < 0.5 )
336 {
337 int locks;
338
339 sortvars[i] = sortvars[v];
340 sortvars[v] = var;
341
342 locks = nuplocks[i];
343 nuplocks[i] = nuplocks[v];
344 nuplocks[v] = locks;
345
346 locks = ndownlocks[i];
347 ndownlocks[i] = ndownlocks[v];
348 ndownlocks[v] = locks;
349
350 if( varpos != NULL )
351 {
352 varpos[SCIPvarGetProbindex(sortvars[i])] = i;
353 varpos[SCIPvarGetProbindex(sortvars[v])] = v;
354 }
355
356 if( bestpos == v )
357 bestpos = i;
358
359 ++v;
360
361 continue;
362 }
363
364 score = nuplocks[i] + ndownlocks[i];
365 assert(score <= lastbestscore);
366
367 if( score > bestscore )
368 {
369 bestscore = score;
370 bestpos = i;
371
372 if( bestscore == lastbestscore )
373 break;
374 }
375 }
376 if( v == nbinvars )
377 break;
378 }
379 lastbestscore = bestscore;
380
381 /* move best variable to the front (at position v) */
382 if( bestpos != v )
383 {
384 int locks;
385
386 var = sortvars[bestpos];
387 sortvars[bestpos] = sortvars[v];
388 sortvars[v] = var;
389
390 locks = nuplocks[bestpos];
391 nuplocks[bestpos] = nuplocks[v];
392 nuplocks[v] = locks;
393
394 locks = ndownlocks[bestpos];
395 ndownlocks[bestpos] = ndownlocks[v];
396 ndownlocks[v] = locks;
397
398 if( varpos != NULL )
399 {
400 varpos[SCIPvarGetProbindex(sortvars[bestpos])] = bestpos;
401 varpos[SCIPvarGetProbindex(sortvars[v])] = v;
402 }
403 }
404
405 var = sortvars[v];
406
407 /* all remaining variables are fixed, we can break the fix-and-propagate loop */
408 if( SCIPvarGetLbLocal(var) > 0.5 || SCIPvarGetUbLocal(var) < 0.5 )
409 {
410 assert(v == nbinvars);
411
412 break;
413 }
414
415 /* stop if we reached the depth limit */
417 break;
418
419 if( propagated )
420 {
422 propagated = FALSE;
423 }
424
425 /* set variables to the bound with fewer locks, if tie choose an average value */
426 if( ndownlocks[v] > nuplocks[v] )
427 lastfixval = 1.0;
428 else if( ndownlocks[v] < nuplocks[v] )
429 lastfixval = 0.0;
430 else
431 {
432 /* prefer one-fixing if objective value is not positive */
434 lastfixval = 1.0;
435 else
436 {
437 randnumber = SCIPrandomGetReal(heurdata->randnumgen, 0.0, 1.0);
438
439 /* if a tie occurs, we randomly round the variable based on the parameter 'roundupprobability' */
440 if( randnumber < roundupprobability )
441 lastfixval = 1.0;
442 else
443 lastfixval = 0.0;
444 }
445 }
446
447 lastfixlocks = lastfixval > 0.5 ? nuplocks[v] : ndownlocks[v];
448
449 SCIP_CALL( SCIPfixVarProbing(scip, var, lastfixval) );
450
451 SCIPdebugMsg(scip, "iteration %d: fixing variable <%s> to %d with locks (%d, %d)\n", v, SCIPvarGetName(var), lastfixval > 0.5 ? 1 : 0, ndownlocks[v], nuplocks[v]);
452
453 if( propagate && lastfixlocks > 0 )
454 {
455 /* apply propagation */
456 SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, NULL) );
457 propagated = TRUE;
458
459 if( *cutoff )
460 {
461 SCIPdebugMsg(scip, "last fixing led to infeasibility trying other bound\n");
462
463 /* fix cutoff variable in other direction */
465 *cutoff = FALSE;
466
467 if( lastfixval < 0.5 )
468 {
469 lastfixval = 1.0;
470
471 if( SCIPvarGetUbLocal(var) > 0.5 )
472 {
474 }
475 /* because of the limited number of propagation rounds, it may happen that conflict analysis finds a
476 * valid global fixing for the last fixed variable that conflicts with applying the reverse fixing
477 * after backtracking; in that case, we ran into a deadend and stop
478 */
479 else
480 *cutoff = TRUE;
481 }
482 else
483 {
484 lastfixval = 0.0;
485
486 if( SCIPvarGetLbLocal(var) < 0.5 )
487 {
489 }
490 /* because of the limited number of propagation rounds, it may happen that conflict analysis finds a
491 * valid global fixing for the last fixed variable that conflicts with applying the reverse fixing
492 * after backtracking; in that case, we ran into a deadend and stop
493 */
494 else
495 *cutoff = TRUE;
496 }
497
498 if( !(*cutoff) )
499 {
500 SCIP_CALL( SCIPpropagateProbing(scip, maxproprounds, cutoff, NULL) );
501 }
502 if( *cutoff )
503 {
504 SCIPdebugMsg(scip, "probing was infeasible\n");
505
506 break;
507 }
508 }
509 /* @todo collect propagated bounds and use them to update row activities as well */
510 }
511
512 if( updatelocks )
513 {
515 continue;
516
517 col = SCIPvarGetCol(var);
518 assert(col != NULL);
519
520 colrows = SCIPcolGetRows(col);
521 colvals = SCIPcolGetVals(col);
522 ncolrows = SCIPcolGetNNonz(col);
523
524 /* update activities */
525 for( r = 0; r < ncolrows; ++r )
526 {
527 row = colrows[r];
528 rowpos = SCIProwGetLPPos(row);
529
530 /* the row is not in the LP */
531 if( rowpos == -1 )
532 continue;
533
534 assert(lprows[rowpos] == row);
535
536 /* we disregard cuts */
537 if( SCIProwGetRank(row) > 0 )
538 continue;
539
540 /* the row is already fulfilled */
541 if( fulfilled[rowpos] )
542 continue;
543
544 haslhs = !SCIPisInfinity(scip, -SCIProwGetLhs(row));
545 hasrhs = !SCIPisInfinity(scip, SCIProwGetRhs(row));
546
547 /* no trivial rows */
548 assert(hasrhs || haslhs);
549
550 if( ((colvals[r] > 0) == (lastfixval < 0.5)) )
551 {
552 maxact[rowpos] -= REALABS(colvals[r]);
553 }
554 if( ((colvals[r] > 0) == (lastfixval > 0.5)) )
555 {
556 minact[rowpos] += REALABS(colvals[r]);
557 }
558
559 /* check if the row cannot be violated anymore */
560 if( (!haslhs || SCIPisFeasGE(scip, minact[rowpos], SCIProwGetLhs(row)))
561 && (!hasrhs || SCIPisFeasLE(scip, maxact[rowpos], SCIProwGetRhs(row))) )
562 {
563 SCIP_COL** cols;
564 SCIP_VAR* colvar;
565 SCIP_Real* vals;
566 int ncols;
567 int pos;
568 int w;
569
570 SCIPdebugMsg(scip, "Row <%s> has activity [%g, %g], lhs=%g, rhs=%g\n", SCIProwGetName(row), minact[rowpos], maxact[rowpos], SCIProwGetLhs(row), SCIProwGetRhs(row));
572
573 if( varpos == NULL )
574 {
575 SCIP_CALL( SCIPallocBufferArray(scip, &varpos, nbinvars) );
576
577 for( pos = 0; pos < nbinvars; ++pos )
578 varpos[SCIPvarGetProbindex(sortvars[pos])] = pos;
579 }
580
581 ++nfulfilledrows;
582 fulfilled[rowpos] = TRUE;
583 cols = SCIProwGetCols(row);
584 vals = SCIProwGetVals(row);
585 ncols = SCIProwGetNNonz(row);
586
587 /* we assume that all rows are locking the variables */
588 for( w = ncols - 1; w >= 0; --w )
589 {
590 colvar = SCIPcolGetVar(cols[w]);
591 if( SCIPvarGetType(colvar) == SCIP_VARTYPE_BINARY && !SCIPvarIsImpliedIntegral(colvar) && colvar != var )
592 {
593 assert(sortvars[varpos[SCIPvarGetProbindex(colvar)]] == colvar);
594 pos = varpos[SCIPvarGetProbindex(colvar)];
595
596 if( haslhs )
597 {
598 if( vals[w] > 0.0 )
599 --(ndownlocks[pos]);
600 else
601 --(nuplocks[pos]);
602 }
603 if( hasrhs )
604 {
605 if( vals[w] > 0.0 )
606 --(nuplocks[pos]);
607 else
608 --(ndownlocks[pos]);
609 }
610 }
611 }
612
613 continue;
614 }
615 else if( SCIPisFeasLT(scip, maxact[rowpos], SCIProwGetLhs(row)) || SCIPisFeasGT(scip, minact[rowpos], SCIProwGetRhs(row)) )
616 {
617 *cutoff = TRUE;
618 break;
619 }
620 }
621
622 if( *cutoff )
623 {
624 SCIPdebugMsg(scip, "found infeasible row, stopping heur\n");
625 break;
626 }
627
628 nglbfulfilledrows += nfulfilledrows;
629 SCIPdebugMsg(scip, "last fixing led to %d fulfilled rows, now %d of %d rows are fulfilled\n", nfulfilledrows, nglbfulfilledrows, nlprows);
630
631 if( nglbfulfilledrows == nlprows )
632 {
633 *allrowsfulfilled = TRUE;
634 break;
635 }
636 }
637 } /*lint --e{850}*/
638
640 SCIPfreeBufferArray(scip, &fulfilled);
641 SCIPfreeBufferArray(scip, &maxact);
642 SCIPfreeBufferArray(scip, &minact);
643 SCIPfreeBufferArray(scip, &ndownlocks);
644 SCIPfreeBufferArray(scip, &nuplocks);
645 SCIPfreeBufferArray(scip, &sortvars);
646
647 return SCIP_OKAY;
648}
649
650
651
652
653/** execution method of primal heuristic */
654static
655SCIP_DECL_HEUREXEC(heurExecLocks)
656{ /*lint --e{715}*/
658 SCIP_VAR** vars;
660 SCIP_Real lowerbound;
663 SCIP_Bool allrowsfulfilled = FALSE;
664#ifdef NOCONFLICT
665 SCIP_Bool enabledconflicts;
666#endif
667 int oldnpscands;
668 int npscands;
669
670 int nvars;
671 int i;
672
674
675 /* only run once */
676 if( SCIPgetNRuns(scip) > 1 )
677 return SCIP_OKAY;
678
679 if( SCIPgetNBinVars(scip) == 0 )
680 return SCIP_OKAY;
681
682 /* only run if we are allowed to solve an LP at the current node in the tree */
684 return SCIP_OKAY;
685
687 {
689
690 /* manually cut off the node if the LP construction detected infeasibility (heuristics cannot return such a
691 * result); the cutoff result is safe to use in exact solving mode, but we don't have enough information to
692 * give a certificate for the cutoff
693 */
694 if( cutoff && !SCIPisCertified(scip) )
695 {
697 return SCIP_OKAY;
698 }
699
701
702 /* we need an LP */
703 if( SCIPgetNLPRows(scip) == 0 )
704 return SCIP_OKAY;
705 }
706
708
710 assert(heurdata != NULL);
711
712#ifdef NOCONFLICT
713 /* disable conflict analysis */
714 SCIP_CALL( SCIPgetBoolParam(scip, "conflict/enable", &enabledconflicts) );
715
716 if( !SCIPisParamFixed(scip, "conflict/enable") )
717 {
718 SCIP_CALL( SCIPsetBoolParam(scip, "conflict/enable", FALSE) );
719 }
720#endif
721
722 lowerbound = SCIPgetLowerbound(scip);
723 oldnpscands = SCIPgetNPseudoBranchCands(scip);
724
725 /* start probing mode */
727
728#ifdef COLLECTSTATISTICS
730#endif
731
732 cutoff = FALSE;
733 lperror = FALSE;
734
735 SCIP_CALL( SCIPapplyLockFixings(scip, heurdata, &cutoff, &allrowsfulfilled) );
736
737 if( cutoff || SCIPisStopped(scip) )
738 goto TERMINATE;
739
740 /* check that we had enough fixings */
742
743 SCIPdebugMsg(scip, "npscands=%d, oldnpscands=%d, allrowsfulfilled=%u heurdata->minfixingrate=%g\n",
744 npscands, oldnpscands, allrowsfulfilled, heurdata->minfixingrate);
745
746 if( !allrowsfulfilled && npscands > oldnpscands * (1 - heurdata->minfixingrate) )
747 {
748 SCIPdebugMsg(scip, "--> too few fixings\n");
749
750 goto TERMINATE;
751 }
752 else
753 {
754 char strbuf[SCIP_MAXSTRLEN];
755 int ncols;
756
757 if( SCIPgetNContVars(scip) > 0 )
758 {
759 int nminfixings;
760 int nfixedvars = 0;
761
764 nminfixings = (int)(SCIPceil(scip, heurdata->minfixingratelp * nvars));
765
766 /* count fixed variables */
767 for( i = 0; i < nvars && nfixedvars < nminfixings; ++i )
768 {
770 ++nfixedvars;
771 }
772
773 SCIPdebugMsg(scip, "Fixed %d of %d (%.1f %%) variables after probing -> %s\n",
774 nfixedvars, nvars, (100.0 * nfixedvars / (SCIP_Real)nvars),
775 nfixedvars >= nminfixings ? "continue and solve LP for remaining variables" : "terminate without LP");
776
777 if( nfixedvars < nminfixings )
778 goto TERMINATE;
779 }
780
781 /* print message if relatively large LP is solved from scratch, since this could lead to a longer period during
782 * which the user sees no output; more detailed probing stats only in debug mode */
783 ncols = SCIPgetNLPCols(scip);
784 if( !SCIPisLPSolBasic(scip) && ncols > 1000 )
785 {
786 int nunfixedcols = SCIPgetNUnfixedLPCols(scip);
787
788 if( nunfixedcols > 0.5 * ncols )
789 {
791 "Heuristic " HEUR_NAME " solving LP from scratch with %.1f %% unfixed columns (%d of %d) ...\n",
792 100.0 * (nunfixedcols / (SCIP_Real)ncols), nunfixedcols, ncols);
793 }
794 }
795 SCIPdebugMsg(scip, "Heuristic " HEUR_NAME " probing LP: %s\n",
797
798 /* solve LP;
799 * errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
800 * hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
801 */
802 SCIPdebugMsg(scip, "starting solving locks-lp at time %g\n", SCIPgetSolvingTime(scip));
803#ifdef NDEBUG
804 {
805 SCIP_Bool retstat;
806 retstat = SCIPsolveProbingLP(scip, -1, &lperror, &cutoff);
807 if( retstat != SCIP_OKAY )
808 {
809 SCIPwarningMessage(scip, "Error while solving LP in LOCKS heuristic; LP solve terminated with code <%d>\n",
810 retstat);
811 }
812 }
813#else
815#endif
816 SCIPdebugMsg(scip, "ending solving locks-lp at time %g\n", SCIPgetSolvingTime(scip));
817
818 lpstatus = SCIPgetLPSolstat(scip);
819
820 SCIPdebugMsg(scip, " -> new LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
821 SCIPdebugMsg(scip, " -> error=%u, status=%d\n", lperror, SCIPgetLPSolstat(scip));
822
823 /* check if this is a feasible solution */
824 if( !lperror && lpstatus == SCIP_LPSOLSTAT_OPTIMAL )
825 {
826 SCIP_SOL* sol;
827 SCIP_Bool success;
828
829 lowerbound = SCIPgetLPObjval(scip);
830
831 /* create a copy of the current LP solution */
832 SCIP_CALL( SCIPcreateSol(scip, &sol, heur) );
834
835 SCIP_CALL( SCIProundSol(scip, sol, &success) );
836
837 if( success )
838 {
839 SCIP_Bool stored;
840
841 /* check solution for feasibility, and add it to solution store if possible.
842 * Neither integrality nor feasibility of LP rows have to be checked, because they
843 * are guaranteed by the heuristic at this stage.
844 */
846
847 if( stored )
848 {
849#ifdef SCIP_MORE_DEBUG
850 SCIP_Bool feasible;
851 SCIP_CALL( SCIPcheckSol(scip, sol, TRUE, TRUE, TRUE, TRUE, TRUE, &feasible) );
852 assert(feasible);
853#endif
854
855 SCIPdebugMsg(scip, "found feasible solution:\n");
858 }
859
861
862 /* we found a solution, so we are done */
863 goto TERMINATE;
864 }
865
867 }
868 }
869
870 if( heurdata->usefinalsubmip && !cutoff && !lperror && lpstatus != SCIP_LPSOLSTAT_INFEASIBLE && lpstatus != SCIP_LPSOLSTAT_OBJLIMIT )
871 {
872 SCIP* subscip;
873 SCIP_VAR** subvars;
874 SCIP_HASHMAP* varmap;
875 SCIP_Longint nstallnodes;
877
878 /* calculate the maximal number of branching nodes until heuristic is aborted */
879 nstallnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
880
881 /* reward locks heuristic if it succeeded often */
882 nstallnodes = (SCIP_Longint)(nstallnodes * 3.0 * (SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur) + 1.0));
883 nstallnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-MIP as 100 nodes */
884 nstallnodes += heurdata->nodesofs;
885
886 /* determine the node limit for the current process */
887 nstallnodes -= heurdata->usednodes;
888 nstallnodes = MIN(nstallnodes, heurdata->maxnodes);
889
890 /* check whether we have enough nodes left to call subproblem solving */
891 if( nstallnodes < heurdata->minnodes )
892 {
893 SCIPdebugMsg(scip, "skipping " HEUR_NAME ": nstallnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->minnodes);
894 goto TERMINATE;
895 }
896
897 /* check whether there is enough time and memory left */
899
900 if( !valid )
901 goto TERMINATE;
902
903 /* get all variables */
905
906 /* create subproblem */
907 SCIP_CALL( SCIPcreate(&subscip) );
908
909 /* allocate temporary memory for subscip variables */
911
912 /* create the variable mapping hash map */
913 SCIP_CALL( SCIPhashmapCreate(&varmap, SCIPblkmem(subscip), nvars) );
914
915 SCIP_CALL( SCIPcopy(scip, subscip, varmap, NULL, "_locks", FALSE, FALSE, FALSE, TRUE, &valid) );
916
917 if( heurdata->copycuts )
918 {
919 /* copies all active cuts from cutpool of sourcescip to linear constraints in targetscip */
920 SCIP_CALL( SCIPcopyCuts(scip, subscip, varmap, NULL, FALSE, NULL) );
921 }
922
923 for( i = 0; i < nvars; i++ )
924 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmap, vars[i]);
925
926 /* free hash map */
927 SCIPhashmapFree(&varmap);
928
929 /* do not abort subproblem on CTRL-C */
930 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
931
932#ifdef SCIP_DEBUG
933 /* for debugging, enable full output */
934 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
935 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 100000000) );
936#else
937 /* disable statistic timing inside sub SCIP and output to console */
938 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
939 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
940#endif
941
942 /* set limits for the subproblem */
943 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
944 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/stallnodes", nstallnodes) );
945 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", heurdata->maxnodes) );
946
947 /* forbid call of heuristics and separators solving sub-CIPs */
948 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
949
950 /* disable cutting plane separation */
952
953 /* disable expensive presolving */
955
956 /* use inference branching */
957 if( SCIPfindBranchrule(subscip, "inference") != NULL && !SCIPisParamFixed(subscip, "branching/inference/priority") )
958 {
959 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
960 }
961
962 /* speed up sub-SCIP by not checking dual LP feasibility */
963 SCIP_CALL( SCIPsetBoolParam(subscip, "lp/checkdualfeas", FALSE) );
964
965 /* if there is already a solution, add an objective cutoff */
966 if( SCIPgetNSols(scip) > 0 )
967 {
968 SCIP_Real upperbound;
969 SCIP_Real minimprove;
970 SCIP_Real cutoffbound;
971
972 minimprove = heurdata->minimprove;
974
975 upperbound = SCIPgetUpperbound(scip) - SCIPsumepsilon(scip);
976
977 if( !SCIPisInfinity(scip, -1.0 * lowerbound) )
978 {
979 cutoffbound = (1-minimprove) * SCIPgetUpperbound(scip) + minimprove * lowerbound;
980 }
981 else
982 {
983 if( SCIPgetUpperbound ( scip ) >= 0 )
984 cutoffbound = (1 - minimprove) * SCIPgetUpperbound(scip);
985 else
986 cutoffbound = (1 + minimprove) * SCIPgetUpperbound(scip);
987 }
988 cutoffbound = MIN(upperbound, cutoffbound);
989 SCIP_CALL( SCIPsetObjlimit(subscip, cutoffbound) );
990 SCIPdebugMsg(scip, "setting objlimit for subscip to %g\n", cutoffbound);
991 }
992
993 SCIPdebugMsg(scip, "starting solving locks-submip at time %g\n", SCIPgetSolvingTime(scip));
994
995 /* solve the subproblem */
996 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
997 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
998 */
999#ifdef NDEBUG
1000 {
1001 SCIP_RETCODE retstat;
1002 retstat = SCIPpresolve(subscip);
1003 if( retstat != SCIP_OKAY )
1004 {
1005 SCIPwarningMessage(scip, "Error while presolving subMIP in locks heuristic; sub-SCIP terminated with code <%d>\n", retstat);
1006
1007 goto FREESCIPANDTERMINATE;
1008 }
1009 }
1010#else
1011 SCIP_CALL_ABORT( SCIPpresolve(subscip) );
1012#endif
1013
1014 SCIPdebugMsg(scip, "locks heuristic presolved subproblem at time %g : %d vars, %d cons; fixing value = %g\n", SCIPgetSolvingTime(scip), SCIPgetNVars(subscip), SCIPgetNConss(subscip), ((nvars - SCIPgetNVars(subscip)) / (SCIP_Real)nvars));
1015
1016 /* after presolving, we should have at least reached a certain fixing rate over ALL variables (including continuous)
1017 * to ensure that not only the MIP but also the LP relaxation is easy enough
1018 */
1019 if( ((nvars - SCIPgetNVars(subscip)) / (SCIP_Real)nvars) >= heurdata->minfixingrate )
1020 {
1021 SCIP_Bool success;
1022
1023 SCIPdebugMsg(scip, "solving subproblem: nstallnodes=%" SCIP_LONGINT_FORMAT ", maxnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->maxnodes);
1024
1025#ifdef NDEBUG
1026 {
1027 SCIP_RETCODE retstat;
1028 retstat = SCIPsolve(subscip);
1029 if( retstat != SCIP_OKAY )
1030 {
1031 SCIPwarningMessage(scip, "Error while solving subMIP in locks heuristic; sub-SCIP terminated with code <%d>\n",retstat);
1032
1033 goto FREESCIPANDTERMINATE;
1034 }
1035 }
1036#else
1037 SCIP_CALL_ABORT( SCIPsolve(subscip) );
1038#endif
1039 SCIPdebugMsg(scip, "ending solving locks-submip at time %g, status = %d\n", SCIPgetSolvingTime(scip), SCIPgetStatus(subscip));
1040
1041 /* check, whether a solution was found; due to numerics, it might happen that not all solutions are feasible ->
1042 * try all solutions until one was accepted
1043 */
1044 SCIP_CALL( SCIPtranslateSubSols(scip, subscip, heur, subvars, &success, NULL) );
1045 if( success )
1047 }
1048
1049#ifdef SCIP_DEBUG
1050 SCIP_CALL( SCIPprintStatistics(subscip, NULL) );
1051#endif
1052
1053 heurdata->usednodes += SCIPgetNNodes(subscip);
1054#ifdef NDEBUG
1055 FREESCIPANDTERMINATE:
1056#endif
1057 /* free subproblem */
1058 SCIPfreeBufferArray(scip, &subvars);
1059 SCIP_CALL( SCIPfree(&subscip) );
1060 }
1061
1062 TERMINATE:
1063 /* exit probing mode */
1065
1066#ifdef NOCONFLICT
1067 /* reset the conflict analysis */
1068 if( !SCIPisParamFixed(scip, "conflict/enable") )
1069 {
1070 SCIP_CALL( SCIPsetBoolParam(scip, "conflict/enable", enabledconflicts) );
1071 }
1072#endif
1073
1074 return SCIP_OKAY;
1075}
1076
1077
1078/*
1079 * primal heuristic specific interface methods
1080 */
1081
1082/** creates the locks primal heuristic and includes it in SCIP */
1084 SCIP* scip /**< SCIP data structure */
1085 )
1086{
1088 SCIP_HEUR* heur;
1089
1090 /* create primal heuristic data */
1092
1093 /* include primal heuristic */
1097
1098 assert(heur != NULL);
1099
1100 /* primal heuristic is safe to use in exact solving mode */
1101 SCIPheurMarkExact(heur);
1102
1103 /* set non-NULL pointers to callback methods */
1104 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyLocks) );
1105 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeLocks) );
1106 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitLocks) );
1107 SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitLocks) );
1108
1109 /* add locks primal heuristic parameters */
1110 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxproprounds",
1111 "maximum number of propagation rounds to be performed in each propagation call (-1: no limit, -2: parameter settings)",
1112 &heurdata->maxproprounds, TRUE, DEFAULT_MAXPROPROUNDS, -2, INT_MAX, NULL, NULL) );
1113
1114 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minfixingrate",
1115 "minimum percentage of integer variables that have to be fixable",
1116 &heurdata->minfixingrate, FALSE, DEFAULT_MINFIXINGRATE, 0.0, 1.0, NULL, NULL) );
1117
1118 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/roundupprobability",
1119 "probability for rounding a variable up in case of ties",
1120 &heurdata->roundupprobability, FALSE, DEFAULT_ROUNDUPPROBABILITY, 0.0, 1.0, NULL, NULL) );
1121
1122 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/usefinalsubmip",
1123 "should a final sub-MIP be solved to costruct a feasible solution if the LP was not roundable?",
1124 &heurdata->usefinalsubmip, TRUE, DEFAULT_USEFINALSUBMIP, NULL, NULL) );
1125
1126 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
1127 "maximum number of nodes to regard in the subproblem",
1128 &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1129
1130 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
1131 "number of nodes added to the contingent of the total nodes",
1132 &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1133
1134 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
1135 "minimum number of nodes required to start the subproblem",
1136 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1137
1138 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
1139 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
1140 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
1141
1142 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
1143 "factor by which " HEUR_NAME " heuristic should at least improve the incumbent",
1144 &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
1145
1146 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
1147 "should all active cuts from cutpool be copied to constraints in subproblem?",
1148 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
1149
1150 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/updatelocks",
1151 "should the locks be updated based on LP rows?",
1152 &heurdata->updatelocks, TRUE, DEFAULT_UPDATELOCKS, NULL, NULL) );
1153
1154 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minfixingratelp",
1155 "minimum fixing rate over all variables (including continuous) to solve LP",
1156 &heurdata->minfixingratelp, TRUE, DEFAULT_MINFIXINGRATELP, 0.0, 1.0, NULL, NULL) );
1157
1158 return SCIP_OKAY;
1159}
#define DEFAULT_MAXPROPROUNDS
SCIP_VAR * w
#define DEFAULT_MAXNODES
#define DEFAULT_MINIMPROVE
#define DEFAULT_RANDSEED
#define NULL
Definition def.h:255
#define SCIP_MAXSTRLEN
Definition def.h:276
#define SCIP_Longint
Definition def.h:148
#define SCIP_MAXTREEDEPTH
Definition def.h:304
#define SCIP_Bool
Definition def.h:98
#define MIN(x, y)
Definition def.h:231
#define SCIP_Real
Definition def.h:163
#define TRUE
Definition def.h:100
#define FALSE
Definition def.h:101
#define SCIP_CALL_ABORT(x)
Definition def.h:341
#define SCIP_LONGINT_FORMAT
Definition def.h:155
#define REALABS(x)
Definition def.h:189
#define SCIP_LONGINT_MAX
Definition def.h:149
#define SCIP_CALL(x)
Definition def.h:362
#define DEFAULT_MINNODES
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 SCIPcopyCuts(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
Definition scip_copy.c:2113
SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
Definition scip_copy.c:3292
SCIP_Bool SCIPisStopped(SCIP *scip)
SCIP_RETCODE SCIPfree(SCIP **scip)
SCIP_RETCODE SCIPcreate(SCIP **scip)
SCIP_STATUS SCIPgetStatus(SCIP *scip)
int SCIPgetNContVars(SCIP *scip)
Definition scip_prob.c:2569
int SCIPgetNCheckConss(SCIP *scip)
Definition scip_prob.c:3762
SCIP_RETCODE SCIPsetObjlimit(SCIP *scip, SCIP_Real objlimit)
Definition scip_prob.c:1661
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition scip_prob.c:2115
int SCIPgetNVars(SCIP *scip)
Definition scip_prob.c:2246
int SCIPgetNConss(SCIP *scip)
Definition scip_prob.c:3620
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition scip_prob.c:2201
int SCIPgetNBinVars(SCIP *scip)
Definition scip_prob.c:2293
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition misc.c:3095
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,...)
#define SCIPdebugMsg
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition scip_param.c:250
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 SCIPincludeHeurLocks(SCIP *scip)
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
int SCIPgetNPseudoBranchCands(SCIP *scip)
SCIP_Bool SCIPisCertified(SCIP *scip)
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition lp.c:17425
int SCIPcolGetNNonz(SCIP_COL *col)
Definition lp.c:17520
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
Definition lp.c:17555
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
Definition lp.c:17545
int SCIPconshdlrGetNCheckConss(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4798
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition scip_cons.c:940
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_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition heur.c:1613
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:167
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition heur.c:1593
SCIP_HEUR * SCIPfindHeur(SCIP *scip, const char *name)
Definition scip_heur.c:263
void SCIPheurMarkExact(SCIP_HEUR *heur)
Definition heur.c:1457
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:215
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:199
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition heur.c:1467
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_Bool SCIPisLPConstructed(SCIP *scip)
Definition scip_lp.c:105
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
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition scip_lp.c:253
int SCIPgetNUnfixedLPCols(SCIP *scip)
Definition scip_lp.c:554
int SCIPgetNLPCols(SCIP *scip)
Definition scip_lp.c:533
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
Definition scip_lp.c:673
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 SCIPduplicateBufferArray(scip, ptr, source, num)
Definition scip_mem.h:132
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition scip_mem.h:137
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
int SCIPgetProbingDepth(SCIP *scip)
char * SCIPsnprintfProbingStats(SCIP *scip, char *strbuf, int len)
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
SCIP_Bool SCIPinProbing(SCIP *scip)
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
SCIP_RETCODE SCIPfixVarProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval)
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition lp.c:17686
SCIP_Real SCIPgetRowMinActivity(SCIP *scip, SCIP_ROW *row)
Definition scip_lp.c:1903
int SCIProwGetNNonz(SCIP_ROW *row)
Definition lp.c:17607
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
Definition lp.c:17632
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
Definition lp.c:17696
SCIP_Real SCIPgetRowMaxActivity(SCIP *scip, SCIP_ROW *row)
Definition scip_lp.c:1920
int SCIProwGetLPPos(SCIP_ROW *row)
Definition lp.c:17895
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
int SCIProwGetRank(SCIP_ROW *row)
Definition lp.c:17775
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition lp.c:17642
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition scip_sol.c:2353
int SCIPgetNSols(SCIP *scip)
Definition scip_sol.c:2889
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition scip_sol.c:3130
SCIP_RETCODE 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:4019
SCIP_RETCODE SCIPcheckSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *feasible)
Definition scip_sol.c:4319
SCIP_RETCODE SCIPpresolve(SCIP *scip)
SCIP_RETCODE SCIPsolve(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 SCIPgetNLPIterations(SCIP *scip)
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisPositive(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_Real SCIPceil(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPsumepsilon(SCIP *scip)
int SCIPgetDepth(SCIP *scip)
Definition scip_tree.c:672
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
int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition var.c:4386
SCIP_Bool SCIPvarIsImpliedIntegral(SCIP_VAR *var)
Definition var.c:23498
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
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition var.c:23662
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23267
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:24234
int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition var.c:4328
void SCIPenableVarHistory(SCIP *scip)
Definition scip_var.c:11083
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
Definition misc.c:10245
#define HEUR_TIMING
return SCIP_OKAY
#define HEUR_FREQOFS
#define HEUR_DESC
#define HEUR_DISPCHAR
#define HEUR_MAXDEPTH
#define HEUR_PRIORITY
SCIPfreeSol(scip, &heurdata->sol))
#define HEUR_NAME
#define HEUR_FREQ
#define HEUR_USESSUBSCIP
SCIPcreateSol(scip, &heurdata->sol, heur))
#define DEFAULT_NODESQUOT
Definition heur_alns.c:90
#define DEFAULT_COPYCUTS
Definition heur_alns.c:147
#define DEFAULT_NODESOFS
Definition heur_clique.c:95
#define DEFAULT_MINFIXINGRATE
SCIP_Bool lperror
SCIPendProbing(scip))
SCIP_Bool cutoff
int nlprows
SCIP_ROW ** lprows
static SCIP_SOL * sol
int r
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIPlinkLPSol(scip, sol))
SCIPcreateRandom(scip, &heurdata->randnumgen, DEFAULT_RANDSEED, TRUE))
#define DEFAULT_MINFIXINGRATELP
Definition heur_locks.c:89
heurdata usednodes
Definition heur_locks.c:160
#define DEFAULT_ROUNDUPPROBABILITY
Definition heur_locks.c:75
SCIP_RETCODE SCIPapplyLockFixings(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_Bool *cutoff, SCIP_Bool *allrowsfulfilled)
Definition heur_locks.c:191
#define DEFAULT_UPDATELOCKS
Definition heur_locks.c:83
SCIPfreeRandom(scip, &heurdata->randnumgen)
#define DEFAULT_USEFINALSUBMIP
Definition heur_locks.c:86
locks primal heuristic
SCIP_VAR * var
static SCIP_Bool propagate
static SCIP_VAR ** vars
memory allocation routines
public methods for managing constraints
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
public methods for problem variables
public methods for branching rule plugins and branching
public methods for certified solving
public methods for constraint handler plugins and constraints
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 the probing mode
public methods for random numbers
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
#define SCIP_DECL_HEURCOPY(x)
Definition type_heur.h:97
struct SCIP_HeurData SCIP_HEURDATA
Definition type_heur.h:77
struct SCIP_Heur SCIP_HEUR
Definition type_heur.h:76
#define SCIP_DECL_HEURINIT(x)
Definition type_heur.h:113
#define SCIP_DECL_HEUREXIT(x)
Definition type_heur.h:121
#define SCIP_DECL_HEURFREE(x)
Definition type_heur.h:105
#define SCIP_DECL_HEUREXEC(x)
Definition type_heur.h:163
struct SCIP_Row SCIP_ROW
Definition type_lp.h:105
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition type_lp.h:52
struct SCIP_Col SCIP_COL
Definition type_lp.h:99
@ SCIP_LPSOLSTAT_ERROR
Definition type_lp.h:50
@ SCIP_LPSOLSTAT_OPTIMAL
Definition type_lp.h:44
@ SCIP_LPSOLSTAT_INFEASIBLE
Definition type_lp.h:45
@ SCIP_LPSOLSTAT_OBJLIMIT
Definition type_lp.h:47
@ SCIP_VERBLEVEL_FULL
struct SCIP_HashMap SCIP_HASHMAP
Definition type_misc.h:106
struct SCIP_RandNumGen SCIP_RANDNUMGEN
Definition type_misc.h:127
@ SCIP_PARAMSETTING_OFF
@ SCIP_PARAMSETTING_FAST
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_DIDNOTFIND
Definition type_result.h:44
@ SCIP_FOUNDSOL
Definition type_result.h:56
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_VARTYPE_BINARY
Definition type_var.h:64
@ SCIP_VARSTATUS_COLUMN
Definition type_var.h:53
@ SCIP_LOCKTYPE_MODEL
Definition type_var.h:141