Scippy

SCIP

Solving Constraint Integer Programs

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-2025 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file heur_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}*/
135 SCIP_HEURDATA* heurdata;
136
137 assert(scip != NULL);
138 assert(heur != NULL);
139 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
140
141 heurdata = SCIPheurGetData(heur);
142
143 /* free primal heuristic data */
144 SCIPfreeBlockMemory(scip, &heurdata);
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}*/
153 SCIP_HEURDATA* heurdata;
154
155 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
156 heurdata = SCIPheurGetData(heur);
157 assert(heurdata != NULL);
158
159 /* initialize data */
160 heurdata->usednodes = 0;
161
162 /* create random number generator */
163 SCIP_CALL( SCIPcreateRandom(scip, &heurdata->randnumgen,
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}*/
173 SCIP_HEURDATA* heurdata;
174
175 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
176
177 /* free heuristic data */
178 heurdata = SCIPheurGetData(heur);
179 assert(heurdata != NULL);
180
181 /* free random number generator */
182 SCIPfreeRandom(scip, &heurdata->randnumgen);
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{
198 SCIP_ROW** lprows;
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;
216 SCIP_Bool propagate;
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);
240 assert(SCIPinProbing(scip));
241
242 if( heurdata == NULL )
243 {
245 heurdata = SCIPheurGetData(heur);
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 */
274 SCIP_CALL( SCIPgetLPRowsData(scip, &lprows, &nlprows) );
275 SCIP_CALL( SCIPallocBufferArray(scip, &minact, nlprows) );
276 SCIP_CALL( SCIPallocBufferArray(scip, &maxact, nlprows) );
277 SCIP_CALL( SCIPallocClearBufferArray(scip, &fulfilled, nlprows) );
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];
288 ndownlocks[v] = SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL);
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 */
433 if( !SCIPisPositive(scip, SCIPvarGetObj(var)) )
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 {
473 SCIP_CALL( SCIPfixVarProbing(scip, var, 1.0) );
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 {
488 SCIP_CALL( SCIPfixVarProbing(scip, var, 0.0) );
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}*/
657 SCIP_HEURDATA* heurdata;
658 SCIP_VAR** vars;
660 SCIP_Real lowerbound;
661 SCIP_Bool cutoff;
662 SCIP_Bool lperror;
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
673 *result = SCIP_DIDNOTRUN;
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 {
688 SCIP_CALL( SCIPconstructLP(scip, &cutoff) );
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
707 *result = SCIP_DIDNOTFIND;
708
709 heurdata = SCIPheurGetData(heur);
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
762 nvars = SCIPgetNVars(scip);
763 vars = SCIPgetVars(scip);
764 nminfixings = (int)(SCIPceil(scip, heurdata->minfixingratelp * nvars));
765
766 /* count fixed variables */
767 for( i = 0; i < nvars && nfixedvars < nminfixings; ++i )
768 {
769 if( SCIPisEQ(scip, SCIPvarGetLbLocal(vars[i]), SCIPvarGetUbLocal(vars[i])) )
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
814 SCIP_CALL( SCIPsolveProbingLP(scip, -1, &lperror, &cutoff) );
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 */
845 SCIP_CALL( SCIPtrySol(scip, sol, FALSE, FALSE, FALSE, FALSE, FALSE, &stored) );
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");
857 *result = SCIP_FOUNDSOL;
858 }
859
860 SCIP_CALL( SCIPfreeSol(scip, &sol) );
861
862 /* we found a solution, so we are done */
863 goto TERMINATE;
864 }
865
866 SCIP_CALL( SCIPfreeSol(scip, &sol) );
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;
876 SCIP_Bool valid;
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 */
904 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
905
906 /* create subproblem */
907 SCIP_CALL( SCIPcreate(&subscip) );
908
909 /* allocate temporary memory for subscip variables */
910 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
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 )
1046 *result = SCIP_FOUNDSOL;
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{
1087 SCIP_HEURDATA* heurdata;
1088 SCIP_HEUR* heur;
1089
1090 /* create primal heuristic data */
1091 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
1092
1093 /* include primal heuristic */
1096 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecLocks, heurdata) );
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}
SCIP_VAR * w
Definition: circlepacking.c:67
SCIP_Real * r
Definition: circlepacking.c:59
#define NULL
Definition: def.h:248
#define SCIP_MAXSTRLEN
Definition: def.h:269
#define SCIP_Longint
Definition: def.h:141
#define SCIP_MAXTREEDEPTH
Definition: def.h:297
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:224
#define SCIP_Real
Definition: def.h:156
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIP_CALL_ABORT(x)
Definition: def.h:334
#define SCIP_LONGINT_FORMAT
Definition: def.h:148
#define REALABS(x)
Definition: def.h:182
#define SCIP_LONGINT_MAX
Definition: def.h:142
#define SCIP_CALL(x)
Definition: def.h:355
SCIP_RETCODE SCIPtranslateSubSols(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_Bool *success, int *solindex)
Definition: scip_copy.c:1437
SCIP_RETCODE SCIPcopy(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool threadsafe, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
Definition: scip_copy.c:2865
SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
Definition: scip_copy.c:3249
SCIP_RETCODE 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)
Definition: scip_general.c:759
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip_general.c:402
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip_general.c:370
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip_general.c:562
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,...)
Definition: scip_message.c:225
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_RETCODE 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)
Definition: heur_locks.c:1083
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
Definition: scip_branch.c:304
int SCIPgetNPseudoBranchCands(SCIP *scip)
Definition: scip_branch.c:766
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 SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: scip_heur.c:167
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1368
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition: scip_heur.c:122
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip_heur.c:183
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
Definition: scip_heur.c:215
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition: heur.c:1613
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 SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
Definition: scip_heur.c:199
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1467
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)
Definition: scip_probing.c:199
char * SCIPsnprintfProbingStats(SCIP *scip, char *strbuf, int len)
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip_probing.c:581
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip_probing.c:226
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:98
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
Definition: scip_probing.c:120
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip_probing.c:166
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:825
SCIP_RETCODE SCIPfixVarProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval)
Definition: scip_probing.c:419
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip_probing.c:261
SCIP_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 SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:516
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:1252
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition: scip_sol.c:2349
int SCIPgetNSols(SCIP *scip)
Definition: scip_sol.c:2882
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition: scip_sol.c:3123
SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip_sol.c:4012
SCIP_RETCODE 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:4312
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1295
SCIP_RETCODE SCIPpresolve(SCIP *scip)
Definition: scip_solve.c:2449
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip_solve.c:2635
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)
Definition: scip_timing.c:378
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
void SCIPfreeRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen)
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
Definition: misc.c:10245
SCIP_RETCODE SCIPcreateRandom(SCIP *scip, SCIP_RANDNUMGEN **randnumgen, unsigned int initialseed, SCIP_Bool useglobalseed)
#define DEFAULT_NODESQUOT
Definition: heur_locks.c:81
static SCIP_DECL_HEUREXEC(heurExecLocks)
Definition: heur_locks.c:655
static SCIP_DECL_HEURFREE(heurFreeLocks)
Definition: heur_locks.c:133
static SCIP_DECL_HEUREXIT(heurExitLocks)
Definition: heur_locks.c:171
#define DEFAULT_NODESOFS
Definition: heur_locks.c:80
#define DEFAULT_MINFIXINGRATELP
Definition: heur_locks.c:89
#define DEFAULT_COPYCUTS
Definition: heur_locks.c:84
#define DEFAULT_MAXNODES
Definition: heur_locks.c:74
#define DEFAULT_ROUNDUPPROBABILITY
Definition: heur_locks.c:75
#define HEUR_TIMING
Definition: heur_locks.c:71
#define DEFAULT_MINNODES
Definition: heur_locks.c:79
static SCIP_DECL_HEURINIT(heurInitLocks)
Definition: heur_locks.c:151
static SCIP_DECL_HEURCOPY(heurCopyLocks)
Definition: heur_locks.c:119
#define HEUR_FREQOFS
Definition: heur_locks.c:69
#define HEUR_DESC
Definition: heur_locks.c:65
#define DEFAULT_MINFIXINGRATE
Definition: heur_locks.c:76
SCIP_RETCODE SCIPapplyLockFixings(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_Bool *cutoff, SCIP_Bool *allrowsfulfilled)
Definition: heur_locks.c:191
#define HEUR_DISPCHAR
Definition: heur_locks.c:66
#define HEUR_MAXDEPTH
Definition: heur_locks.c:70
#define HEUR_PRIORITY
Definition: heur_locks.c:67
#define DEFAULT_MINIMPROVE
Definition: heur_locks.c:77
#define HEUR_NAME
Definition: heur_locks.c:64
#define DEFAULT_UPDATELOCKS
Definition: heur_locks.c:83
#define DEFAULT_RANDSEED
Definition: heur_locks.c:88
#define DEFAULT_USEFINALSUBMIP
Definition: heur_locks.c:86
#define HEUR_FREQ
Definition: heur_locks.c:68
#define HEUR_USESSUBSCIP
Definition: heur_locks.c:72
#define DEFAULT_MAXPROPROUNDS
Definition: heur_locks.c:82
locks primal heuristic
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
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:77
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:52
@ 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
Definition: type_message.h:62
@ SCIP_PARAMSETTING_OFF
Definition: type_paramset.h:63
@ SCIP_PARAMSETTING_FAST
Definition: type_paramset.h:62
@ SCIP_DIDNOTRUN
Definition: type_result.h:42
@ SCIP_DIDNOTFIND
Definition: type_result.h:44
@ SCIP_FOUNDSOL
Definition: type_result.h:56
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_VARTYPE_BINARY
Definition: type_var.h:64
@ SCIP_VARSTATUS_COLUMN
Definition: type_var.h:53
@ SCIP_LOCKTYPE_MODEL
Definition: type_var.h:141