SCIP Doxygen Documentation
Loading...
Searching...
No Matches
heur_lpface.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_lpface.c
26 * @ingroup DEFPLUGINS_HEUR
27 * @brief lpface primal heuristic that searches the optimal LP face inside a sub-MIP
28 * @author Gregor Hendel
29 */
30
31/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32
34#include "scip/cons_linear.h"
35#include "scip/scipdefplugins.h"
36#include "scip/heur_lpface.h"
37#include "scip/pub_event.h"
38#include "scip/pub_heur.h"
39#include "scip/pub_lp.h"
40#include "scip/pub_message.h"
41#include "scip/pub_misc.h"
42#include "scip/pub_sol.h"
43#include "scip/pub_tree.h"
44#include "scip/pub_var.h"
45#include "scip/scip_branch.h"
46#include "scip/scip_cons.h"
47#include "scip/scip_copy.h"
48#include "scip/scip_event.h"
49#include "scip/scip_exact.h"
50#include "scip/scip_general.h"
51#include "scip/scip_heur.h"
52#include "scip/scip_lp.h"
53#include "scip/scip_mem.h"
54#include "scip/scip_message.h"
55#include "scip/scip_nodesel.h"
56#include "scip/scip_numerics.h"
57#include "scip/scip_param.h"
58#include "scip/scip_prob.h"
59#include "scip/scip_sol.h"
60#include "scip/scip_solve.h"
62#include "scip/scip_timing.h"
63#include "scip/scip_tree.h"
64#include "scip/scip_var.h"
65
66
67#define HEUR_NAME "lpface"
68#define HEUR_DESC "LNS heuristic that searches the optimal LP face inside a sub-MIP"
69#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_LNS
70#define HEUR_PRIORITY -1104010
71#define HEUR_FREQ 15
72#define HEUR_FREQOFS 0
73#define HEUR_MAXDEPTH -1
74#define HEUR_TIMING SCIP_HEURTIMING_AFTERLPNODE
75#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
76
77#define DEFAULT_MAXNODES 5000LL /**< maximum number of nodes to regard in the subproblem */
78#define DEFAULT_MINNODES 50LL /**< minimum number of nodes to regard in the subproblem */
79#define DEFAULT_MINFIXINGRATE 0.1 /**< required percentage of fixed integer variables in sub-MIP to run */
80#define DEFAULT_NODESOFS 200LL /**< 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_LPLIMFAC 2.0 /**< factor by which the limit on the number of LP depends on the node limit */
83#define DEFAULT_USELPROWS TRUE /**< should subproblem be created out of the rows in the LP rows,
84 * otherwise, the copy constructors of the constraints handlers are used */
85#define DEFAULT_COPYCUTS TRUE /**< if uselprows == FALSE, should all active cuts from cutpool be copied
86 * to constraints in subproblem? */
87#define DEFAULT_DUALBASISEQUATIONS FALSE /**< should the dually nonbasic rows be turned into equations? */
88#define DEFAULT_KEEPSUBSCIP FALSE /**< should the heuristic continue solving the same sub-SCIP? */
89#define DEFAULT_MINPATHLEN 5 /**< the minimum active search tree path length along which the lower bound
90 * hasn't changed before heuristic becomes active */
91/* event handler properties */
92#define EVENTHDLR_NAME "Lpface"
93#define EVENTHDLR_DESC "LP event handler for " HEUR_NAME " heuristic"
94
95/*
96 * Data structures
97 */
98
99/** data structure to keep sub-SCIP across runs */
101{
102 SCIP* subscip; /**< pointer to store sub-SCIP data structure */
103 SCIP_VAR** subvars; /**< array of variables of the sub-problem */
104 int nsubvars; /**< number of sub-problem variables */
105 SCIP_Real objbound; /**< lower bound on objective for when sub SCIP was created */
106};
108
109/** primal heuristic data */
110struct SCIP_HeurData
111{
112 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
113 SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
114 SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
115 SCIP_Longint usednodes; /**< nodes already used by lpface in earlier calls */
116 SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
117
118 unsigned int nfailures; /**< number of failures since last successful call */
119 SCIP_Longint nextnodenumber; /**< number of nodes at which lpface should be called the next time */
120 SCIP_Real lastlpobjinfeas; /**< last LP objective where the sub-MIP was run to proven infeasibility */
121 SCIP_Real minfixingrate; /**< required percentage of fixed integer variables in sub-MIP to run */
122 SCIP_Real nodelimit; /**< the nodelimit employed in the current sub-SCIP, for the event handler*/
123 SCIP_Real lplimfac; /**< factor by which the limit on the number of LP depends on the node limit */
124 SCIP_Bool uselprows; /**< should subproblem be created out of the rows in the LP rows? */
125 SCIP_Bool copycuts; /**< if uselprows == FALSE, should all active cuts from cutpool be copied
126 * to constraints in subproblem? */
127 SCIP_Bool dualbasisequations; /**< should the dually nonbasic rows be turned into equations? */
128 SCIP_Bool keepsubscip; /**< should the heuristic continue solving the same sub-SCIP? */
129 char subscipobjective; /**< objective function in the sub-SCIP: (z)ero, (r)oot-LP-difference,
130 * (i)nference, LP (f)ractionality, (o)riginal */
131
132 SCIP_STATUS submipstatus; /**< return status of the sub-MIP */
133 SCIP_Longint submipnlpiters; /**< number of LP iterations of the sub-MIP */
134 SCIP_Real submippresoltime; /**< time required to presolve the sub-MIP */
135 int nvarsfixed; /**< the number of fixed variables by the heuristic */
136 int minpathlen; /**< the minimum active search tree path length along which the lower bound
137 * hasn't changed before heuristic becomes active */
138 SUBSCIPDATA* subscipdata; /**< sub-SCIP data structure */
139};
140
141/*
142 * Local methods
143 */
144
145/** determine variable fixings for sub-SCIP based on reduced costs */
146static
148 SCIP* scip, /**< SCIP data structure */
149 SCIP_HEURDATA* heurdata, /**< primal heuristic data */
150 SCIP_VAR** fixvars, /**< buffer to store variables that should be fixed */
151 SCIP_Real* fixvals, /**< buffer to store corresponding fixing values */
152 int* nfixvars, /**< pointer to store number of variables that should be fixed */
153 SCIP_Bool* success /**< pointer to store whether enough integer variables were fixed */
154 )
155{
156 SCIP_VAR** vars; /* original scip variables */
157 SCIP_Real fixingrate; /* percentage of variables that are fixed */
158 int nvars;
159 int nbinvars;
160 int nintvars;
161 int i;
162 int fixingcounter;
163
164 /* get required data of the main scip problem */
165 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, &nintvars, NULL, NULL) );
166
167 fixingcounter = 0;
168
169 assert(nvars >= nbinvars + nintvars);
170
171 *nfixvars = 0;
172 /* loop over problem variables and fix all with nonzero reduced costs to their solution value */
173 for( i = 0; i < nvars; i++ )
174 {
175 SCIP_Real solval;
176 SCIP_COL* col;
177 SCIP_Real redcost;
178 SCIP_Real lbglobal;
179 SCIP_Real ubglobal;
180 SCIP_VAR* var;
181
182 var = vars[i];
183
184 /* skip non-column variables */
186 continue;
187
188 /* skip relaxation only variables */
190 continue;
191
192 solval = SCIPgetSolVal(scip, NULL, var);
193 col = SCIPvarGetCol(vars[i]);
194 assert(col != NULL);
195 redcost = SCIPgetColRedcost(scip, col);
196 lbglobal = SCIPvarGetLbGlobal(var);
197 ubglobal = SCIPvarGetUbGlobal(var);
198
199 /* fix the variable to its solution value if variable is nonbasic (i.e., at one of its bounds)
200 * with nonzero reduced costs
201 */
202 if( ! SCIPisDualfeasZero(scip, redcost) )
203 {
204 /* fix variable based on reduced cost information, respecting global bounds */
205 if( (redcost > 0 && SCIPisFeasEQ(scip, solval, lbglobal)) ||
206 (redcost < 0 && SCIPisFeasEQ(scip, solval, ubglobal)) )
207 {
208 assert(! SCIPisInfinity(scip, REALABS(solval)));
209
210 fixvars[*nfixvars] = var;
211 fixvals[*nfixvars] = solval;
212
214 ++fixingcounter;
215
216 ++(*nfixvars);
217 }
218 }
219 }
220
221 fixingrate = (SCIP_Real)fixingcounter / (SCIP_Real)(MAX(nbinvars + nintvars, 1));
222 heurdata->nvarsfixed = fixingcounter;
223
224 /* if all variables were fixed or amount of fixed variables is insufficient, skip residual part of
225 * subproblem creation and abort immediately
226 */
227 *success = (fixingcounter < nvars && fixingrate >= heurdata->minfixingrate);
228
229 SCIPdebugMsg(scip, " LP face heuristic fixed %senough variables (%d out of %d)\n",
230 *success ? "": "not ", fixingcounter, nvars);
231
232 return SCIP_OKAY;
233}
234
235/** creates the rows of the subproblem */
236static
238 SCIP* scip, /**< original SCIP data structure */
239 SCIP* subscip, /**< SCIP data structure for the subproblem */
240 SCIP_VAR** subvars, /**< the variables of the subproblem */
241 SCIP_Bool dualbasisequations /**< should the dually nonbasic rows be turned into equations? */
242 )
243{
244 SCIP_ROW** rows; /* original scip rows */
245
246 int nrows;
247 int i;
248
249 /* get the rows and their number */
250 SCIP_CALL( SCIPgetLPRowsData(scip, &rows, &nrows) );
251
252 /* copy all global rows to linear constraints, unless they contain relaxation-only variables */
253 for( i = 0; i < nrows; i++ )
254 {
255 SCIP_VAR** consvars; /* new constraint's variables */
256 SCIP_COL** cols; /* original row's columns */
257 SCIP_CONS* cons; /* new constraint */
258
259 SCIP_Real* vals; /* variables' coefficient values of the row */
260 SCIP_Real constant; /* constant added to the row */
261 SCIP_Real lhs; /* left hand side of the row */
262 SCIP_Real rhs; /* left right side of the row */
263 SCIP_Real dualsol;
264 SCIP_Real rowsolactivity;
265 int j;
266 int nnonz;
267
268 /* ignore rows that are only locally valid */
269 if( SCIProwIsLocal(rows[i]) )
270 continue;
271
272 /* get the row's data */
273 constant = SCIProwGetConstant(rows[i]);
274 vals = SCIProwGetVals(rows[i]);
275 nnonz = SCIProwGetNNonz(rows[i]);
276 cols = SCIProwGetCols(rows[i]);
277
278 /* only subtract constant if left hand side is not infinite */
279 lhs = SCIProwGetLhs(rows[i]);
280 if( ! SCIPisInfinity(scip, -lhs) )
281 lhs -= constant;
282
283 /* only subtract constant if right hand side is not infinite */
284 rhs = SCIProwGetRhs(rows[i]);
285 if( ! SCIPisInfinity(scip, rhs) )
286 rhs -= constant;
287
288 assert(lhs <= rhs);
289
290 /* allocate memory array to be filled with the corresponding subproblem variables */
291 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nnonz) );
292 for( j = 0; j < nnonz; j++ )
293 {
294 consvars[j] = subvars[SCIPvarGetProbindex(SCIPcolGetVar(cols[j]))];
295 if( consvars[j] == NULL )
296 break;
297 }
298 /* skip row if not all variables are in sub-SCIP, i.e., relaxation-only variables */
299 if( j < nnonz )
300 {
301 SCIPfreeBufferArray(scip, &consvars);
302 continue;
303 }
304
305 dualsol = SCIProwGetDualsol(rows[i]);
306 rowsolactivity = SCIPgetRowActivity(scip, rows[i]);
307
308 /* transform into equation if the row is sharp and has a nonzero dual solution */
309 if( dualbasisequations && ! SCIPisDualfeasZero(scip, dualsol) )
310 {
311 if( dualsol > 0.0 && SCIPisFeasEQ(scip, rowsolactivity, lhs) )
312 rhs = lhs;
313 else if( dualsol < 0.0 && SCIPisFeasEQ(scip, rowsolactivity, rhs) )
314 lhs = rhs;
315 }
316
317 /* create a new linear constraint and add it to the subproblem */
318 SCIP_CALL( SCIPcreateConsLinear(subscip, &cons, SCIProwGetName(rows[i]), nnonz, consvars, vals, lhs, rhs,
320 SCIP_CALL( SCIPaddCons(subscip, cons) );
321 SCIP_CALL( SCIPreleaseCons(subscip, &cons) );
322
323 /* free temporary memory */
324 SCIPfreeBufferArray(scip, &consvars);
325 }
326
327 return SCIP_OKAY;
328}
329
330/** create the LP face subproblem constraints */
331static
333 SCIP* scip, /**< original SCIP data structure */
334 SCIP* subscip, /**< SCIP data structure for the subproblem */
335 SCIP_VAR** subvars, /**< the variables of the subproblem */
336 SCIP_HEURDATA* heurdata /**< primal heuristic data */
337 )
338{
340 int nvars = SCIPgetNVars(scip);
341 SCIP_Real lowerbound;
342 SCIP_CONS* origobjcons;
343 int i;
344#ifndef NDEBUG
345 int nobjvars = 0;
346#endif
347
348 /* we copy the rows of the LP, if enough variables could be fixed and we work on the MIP relaxation of the problem */
349 if( heurdata->uselprows )
350 {
351 SCIP_CALL( createRows(scip, subscip, subvars, heurdata->dualbasisequations) );
352 }
353
354 /* add an equation that the objective function must be equal to the lower bound */
355 lowerbound = SCIPgetLowerbound(scip);
356
357 SCIP_CALL( SCIPcreateConsLinear(subscip, &origobjcons, "objbound_of_origscip", 0, NULL, NULL, lowerbound, lowerbound,
359
360 for( i = 0; i < nvars; ++i)
361 {
362 if( ! SCIPisZero(subscip, SCIPvarGetObj(vars[i])) )
363 {
364 assert(subvars[i] != NULL); /* a relaxation-only variable cannot have an objective coefficient */
365 SCIP_CALL( SCIPaddCoefLinear(subscip, origobjcons, subvars[i], SCIPvarGetObj(vars[i])) );
366#ifndef NDEBUG
367 nobjvars++;
368#endif
369 }
370 }
371 assert(nobjvars == SCIPgetNObjVars(scip));
372
373 SCIP_CALL( SCIPaddCons(subscip, origobjcons) );
374 SCIP_CALL( SCIPreleaseCons(subscip, &origobjcons) );
375
376 return SCIP_OKAY;
377}
378
379/** updates heurdata after an unsuccessful run of lpface */
380static
382 SCIP* scip, /**< original SCIP data structure */
383 SCIP_HEURDATA* heurdata /**< primal heuristic data */
384 )
385{
386 /* increase number of failures, calculate next node at which lpface should be called and update actual solutions */
387 heurdata->nfailures++;
388 heurdata->nextnodenumber = (heurdata->nfailures <= 25
389 ? SCIPgetNNodes(scip) + 100*(2LL << heurdata->nfailures) /*lint !e703*/
391}
392
393/** calculate a node limit based on node limiting parameters of the heuristic */
394static
396 SCIP* scip, /**< (original) SCIP data structure */
397 SCIP_HEUR* heur, /**< LP face heuristic */
398 SCIP_HEURDATA* heurdata /**< primal heuristic data */
399 )
400{
401 SCIP_Longint nodelimit;
402
403 /* calculate the maximal number of branching nodes until heuristic is aborted */
404 nodelimit = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
405
406 /* count the setup costs for the sub-MIP as 100 nodes */
407 nodelimit -= 100 * SCIPheurGetNCalls(heur);
408
409 /* add the offset */
410 nodelimit += heurdata->nodesofs;
411
412 /* subtract previously used nodes */
413 nodelimit -= heurdata->usednodes;
414
415 /* do not use more than the maximum number of allowed nodes in one run */
416 nodelimit = MIN(nodelimit, heurdata->maxnodes);
417
418 /* if the subscip has been kept from a previous run, add the number of already processed nodes */
419 if( heurdata->subscipdata->subscip != NULL )
420 nodelimit += SCIPgetNNodes(heurdata->subscipdata->subscip);
421
422 return nodelimit;
423}
424
425/** sets node, time, and memory limit according to the parameter settings of the heuristic */
426static
428 SCIP* scip, /**< original SCIP data structure */
429 SCIP* subscip, /**< data structure of the sub-problem */
430 SCIP_HEUR* heur, /**< LP face heuristic */
431 SCIP_HEURDATA* heurdata, /**< heuristic data structure */
432 SCIP_Bool* success /**< did we successfully set all parameters up? */
433 )
434{
435 SCIP_Real timelimit;
436 SCIP_Real memorylimit;
437 SCIP_Longint nodelimit;
438 SCIP_Bool avoidmemout;
439
440 *success = TRUE;
441
442 /* check whether there is enough time and memory left */
443 SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &timelimit) );
444 SCIP_CALL( SCIPgetRealParam(scip, "limits/memory", &memorylimit) );
445 SCIP_CALL( SCIPgetBoolParam(scip, "misc/avoidmemout", &avoidmemout) );
446
447 if( ! SCIPisInfinity(scip, timelimit) )
448 timelimit -= SCIPgetSolvingTime(scip);
449
450 /* substract the memory already used by the main SCIP and the estimated memory usage of external software */
451 if( ! SCIPisInfinity(scip, memorylimit) )
452 {
453 memorylimit -= SCIPgetMemUsed(scip)/1048576.0;
454 memorylimit -= SCIPgetMemExternEstim(scip)/1048576.0;
455 }
456
457 /* abort if no time is left or not enough memory (we don't abort in this case if misc_avoidmemout == FALSE)
458 * to create a copy of SCIP, including external memory usage */
459 if( timelimit <= 0.0 || (avoidmemout && memorylimit <= 2.0 * SCIPgetMemExternEstim(scip) / 1048576.0) )
460 {
461 *success = FALSE;
462 return SCIP_OKAY;
463 }
464
465 /* calculate node limit for the subproblem */
466 nodelimit = calcNodeLimit(scip, heur, heurdata);
467
468 /* we should have aborted the sub-SCIP procedure earlier if no additional nodes are allowed
469 * with the current parameter settings
470 */
471 assert(nodelimit > SCIPgetNNodes(subscip));
472
473 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", nodelimit) );
474 heurdata->nodelimit = nodelimit;
475
476 /* set also the other two limits */
477 SCIP_CALL( SCIPsetRealParam(subscip, "limits/time", timelimit) );
478 SCIP_CALL( SCIPsetRealParam(subscip, "limits/memory", memorylimit) );
479
480 /* disable bound limits */
481 SCIP_CALL( SCIPsetRealParam(subscip, "limits/primal", SCIP_INVALID) );
482 SCIP_CALL( SCIPsetRealParam(subscip, "limits/dual", SCIP_INVALID) );
483
484 return SCIP_OKAY;
485}
486
487/** sets all one-time parameter settings like search strategy, but no limits */
488static
490 SCIP* subscip /**< data structure of the sub-problem */
491 )
492{
493 /* do not abort subproblem on CTRL-C */
494 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
495
496 /* for debugging lpface, enable MIP output */
497#ifdef SCIP_DEBUG
498 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
499 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 1) );
500#endif
501
502 /* disable statistic timing inside sub SCIP */
503 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
504
505 /* forbid recursive call of heuristics and separators solving subMIPs */
506 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
507
508 /* disable expensive cutting plane separation */
510
511 /* disable expensive presolving */
513
514 /* use restart depth first node selection */
515 if( SCIPfindNodesel(subscip, "restartdfs") != NULL && ! SCIPisParamFixed(subscip, "nodeselection/restartdfs/stdpriority") )
516 {
517 SCIP_CALL( SCIPsetIntParam(subscip, "nodeselection/restartdfs/stdpriority", INT_MAX/4) );
518 }
519
520 /* use inference branching */
521 if( SCIPfindBranchrule(subscip, "inference") != NULL && ! SCIPisParamFixed(subscip, "branching/inference/priority") )
522 {
523 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
524 }
525
526 /* enable conflict analysis, disable analysis of boundexceeding LPs, and restrict conflict pool */
527 if( !SCIPisParamFixed(subscip, "conflict/enable") )
528 {
529 SCIP_CALL( SCIPsetBoolParam(subscip, "conflict/enable", TRUE) );
530 }
531 if( !SCIPisParamFixed(subscip, "conflict/useboundlp") )
532 {
533 SCIP_CALL( SCIPsetCharParam(subscip, "conflict/useboundlp", 'o') );
534 }
535 if( !SCIPisParamFixed(subscip, "conflict/maxstoresize") )
536 {
537 SCIP_CALL( SCIPsetIntParam(subscip, "conflict/maxstoresize", 100) );
538 }
539
540 return SCIP_OKAY;
541}
542
543/** reset the sub-SCIP data to its default values */
544static
546 SUBSCIPDATA* subscipdata /**< data structure of the sub-problem */
547 )
548{
549 subscipdata->subscip = NULL;
550 subscipdata->subvars = NULL;
551 subscipdata->nsubvars = 0;
552 subscipdata->objbound = SCIP_INVALID;
553}
554
555/** free the stored sub-SCIP information */
556static
558 SCIP* scip, /**< original SCIP data structure */
559 SUBSCIPDATA* subscipdata /**< data structure of the sub-problem */
560 )
561{
562 assert(subscipdata != NULL);
563
564 /* free the subscipdata's scip */
565 if( subscipdata->subscip != NULL )
566 {
567 SCIP_CALL( SCIPfree(&subscipdata->subscip) );
568 }
569
570 subscipdata->subscip = NULL;
571
572 /* free the subscip variables */
573 if( subscipdata->subvars != NULL )
574 {
575 assert(subscipdata->nsubvars > 0);
576 SCIPfreeBlockMemoryArray(scip, &subscipdata->subvars, subscipdata->nsubvars);
577 }
578
579 subscipdataReset(subscipdata);
580
581 return SCIP_OKAY;
582}
583
584/** store the sub-SCIP to the data structure */
585static
587 SCIP* scip, /**< original SCIP data structure */
588 SUBSCIPDATA* subscipdata, /**< data structure of the sub-problem */
589 SCIP* subscip, /**< sub scip data structure to keep */
590 SCIP_VAR** subvars, /**< sub scip variable array in the order of the main SCIP variables */
591 int nvars /**< number of sub SCIP variables */
592 )
593{
594 assert(scip != NULL);
595 assert(subscipdata != NULL);
596 assert(subscip != NULL);
597 assert(subvars != NULL);
599
600 assert(subscipdata->subscip == NULL);
601 assert(subscipdata->subvars == NULL);
602
603 subscipdata->subscip = subscip;
604 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &subscipdata->subvars, subvars, nvars) );
605 subscipdata->nsubvars = nvars;
606
608
609 return SCIP_OKAY;
610}
611
612#ifdef SCIP_DEBUG
613/** print debug message listing solving time, nodes, and status of sub-SCIP */
614static
615SCIP_RETCODE subscipGetInfo(
616 SCIP* scip, /**< SCIP data structure */
617 SCIP* subscip /**< sub SCIP data */
618 )
619{
620 SCIP_Real timelimit;
621 SCIP_Real memorylimit;
622 SCIP_Longint nodelimit;
623 SCIP_Real time;
624 SCIP_Longint nodes;
625 SCIP_STATUS status;
626
627 SCIP_CALL( SCIPgetRealParam(subscip, "limits/time", &timelimit) );
628 SCIP_CALL( SCIPgetRealParam(subscip, "limits/memory", &memorylimit) );
629 SCIP_CALL( SCIPgetLongintParam(subscip, "limits/nodes", &nodelimit) );
630
631 time = SCIPgetSolvingTime(subscip);
632 nodes = SCIPgetNNodes(subscip);
633 status = SCIPgetStatus(subscip);
634
635 SCIPdebugMsg(scip, "SCIP info: Time: %.1f (Limit: %.1f) Nodes: %"SCIP_LONGINT_FORMAT" (Limit: %"SCIP_LONGINT_FORMAT") Status: %d\n",
636 time, timelimit, nodes, nodelimit, status);
637
638 return SCIP_OKAY;
639}
640#endif
641
642/** create the objective function based on the user selection */
643static
645 SCIP* scip, /**< SCIP data structure */
646 SCIP* subscip, /**< sub-SCIP data structure */
647 SCIP_VAR* var, /**< SCIP variable */
648 SCIP_VAR* subvar, /**< sub-SCIP variable whose objective coefficient is changed */
649 SCIP_HEURDATA* heurdata /**< heuristic data structure to control how the objective is changed */
650 )
651{
652 SCIP_Real objcoeff;
653 SCIP_Real upfrac;
654 SCIP_Real downfrac;
655 SCIP_Real lpsolval;
656 SCIP_Real rootlpsolval;
657
658 /* create the objective value based on the choice of the sub-SCIP objective */
659 switch( heurdata->subscipobjective )
660 {
661 /* use zero as objective function */
662 case 'z':
663 objcoeff = 0.0;
664 break;
665
666 /* use current LP fractionality as objective */
667 case 'f':
668 lpsolval = SCIPvarGetLPSol(var);
669 downfrac = SCIPfrac(scip, lpsolval);
670 upfrac = 1.0 - downfrac;
671
672 objcoeff = downfrac - upfrac;
673 break;
674
675 /* use root LP solution difference */
676 case 'r':
677 lpsolval = SCIPvarGetLPSol(var);
678 rootlpsolval = SCIPvarGetRootSol(var);
679 objcoeff = rootlpsolval - lpsolval;
680 break;
681
682 /* use average inferences */
683 case 'i':
686 break;
687
688 /* use original objective function */
689 case 'o':
690 objcoeff = SCIPvarGetObj(var);
691 break;
692 default:
693 objcoeff = 0.0;
694 break;
695 }
696
697 SCIP_CALL( SCIPchgVarObj(subscip, subvar, objcoeff) );
698
699 return SCIP_OKAY;
700}
701
702/* ---------------- Callback methods of event handler ---------------- */
703
704/** execution callback of the event handler for Lpface sub-SCIP
705 *
706 * we interrupt the solution process if we hit the LP iteration limit per node
707 */
708static
709SCIP_DECL_EVENTEXEC(eventExecLpface)
710{
712
713 assert(eventhdlr != NULL);
714 assert(eventdata != NULL);
715 assert(event != NULL);
717
719
720 heurdata = (SCIP_HEURDATA*)eventdata;
721 assert(heurdata != NULL);
722
723 /* interrupt solution process of sub-SCIP */
724 if( SCIPgetNLPs(scip) > heurdata->lplimfac * heurdata->nodelimit )
725 {
726 SCIPdebugMsg(scip, "interrupt after %" SCIP_LONGINT_FORMAT " LPs\n",SCIPgetNLPs(scip));
728 }
729
730 return SCIP_OKAY;
731}
732
733/** setup and solve the subproblem and catch the return code */
734static
736 SCIP* scip, /**< SCIP data structure */
737 SCIP* subscip, /**< sub-SCIP data structure */
738 SCIP_HEURDATA* heurdata, /**< heuristics data */
739 SCIP_VAR** subvars, /**< subproblem's variables */
740 SCIP_VAR** vars, /**< original problem's variables */
741 SCIP_VAR** fixvars, /**< variables that should be fixed */
742 SCIP_Real* fixvals, /**< corresponding fixing values */
743 int nfixvars, /**< number of variables that should be fixed */
744 int nvars /**< number of original problem's variables */
745 )
746{
747 SCIP_HASHMAP* varmapfw = NULL; /* mapping of SCIP variables to sub-SCIP variables */
748 SCIP_Bool success;
749 int i;
750
751 assert( subscip != NULL );
752 assert( heurdata != NULL );
753 assert( vars != NULL );
754
755 /* create the variable hash map */
756 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
757 success = FALSE;
758
759 if( heurdata->uselprows )
760 {
762 char probname[SCIP_MAXSTRLEN];
763
764 /* copy all plugins */
766 TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, &valid) );
767
768 /* copy parameter settings */
770
771 /* even when solving exactly, sub-SCIP heuristics should be run in floating-point mode, since the exactsol constraint
772 * handler is in place to perform a final repair step
773 */
775
776 /* get name of the original problem and add the string "_lpfacesub" */
777 (void) SCIPsnprintf(probname, SCIP_MAXSTRLEN, "%s_lpfacesub", SCIPgetProbName(scip));
778
779 /* create the subproblem */
780 SCIP_CALL( SCIPcreateProbBasic(subscip, probname) );
782
783 /* copy all variables */
784 SCIP_CALL( SCIPcopyVars(scip, subscip, varmapfw, NULL, fixvars, fixvals, nfixvars, TRUE) );
785 }
786 else
787 {
788 SCIP_CALL( SCIPcopyConsCompression(scip, subscip, varmapfw, NULL, "lpface", fixvars, fixvals, nfixvars, TRUE, FALSE, FALSE, TRUE, &success) );
789
790 if( heurdata->copycuts )
791 {
792 /* copies all active cuts from cutpool of sourcescip to linear constraints in targetscip */
793 SCIP_CALL( SCIPcopyCuts(scip, subscip, varmapfw, NULL, TRUE, NULL) );
794 }
795 }
796 assert(!SCIPisExact(subscip));
797
798 /* fill subvars array with mapping from original variables and set the objective coefficient to the desired value */
799 for( i = 0; i < nvars; i++ )
800 {
801 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
802
803 if( subvars[i] != NULL )
804 {
805 SCIP_CALL( changeSubvariableObjective(scip, subscip, vars[i], subvars[i], heurdata) );
806 }
807 }
808
809 /* free hash map */
810 SCIPhashmapFree(&varmapfw);
811
812 /* disable output to console */
813 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
814
815 /* fix variables that are at their bounds and have nonzero reduced costs */
816 SCIP_CALL( setupSubproblem(scip, subscip, subvars, heurdata) );
817
818 /* set up sub-SCIP parameters */
820
821 return SCIP_OKAY;
822}
823
824/** setup and solve the subproblem and catch the return code */
825static
827 SCIP* scip, /**< SCIP data structure */
828 SCIP* subscip, /**< sub-SCIP data structure */
829 SCIP_HEUR* heur, /**< mutation heuristic */
830 SCIP_HEURDATA* heurdata, /**< heuristics data */
831 SCIP_VAR** subvars, /**< subproblem's variables */
832 SCIP_RESULT* result, /**< pointer to store the result */
833 SCIP_Real focusnodelb, /**< lower bound of the focus node */
834 SCIP_Bool* keepthisscip /**< should the subscip be kept or deleted? */
835 )
836{
837 SCIP_EVENTHDLR* eventhdlr;
838 SCIP_Bool success;
839
840 assert( scip != NULL );
841 assert( subscip != NULL );
842 assert( heur != NULL );
843 assert( heurdata != NULL );
844 assert( subvars != NULL );
845
846 /* create event handler for LP events */
847 SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecLpface, NULL) );
848 if( eventhdlr == NULL )
849 {
850 SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
851 return SCIP_PLUGINNOTFOUND;
852 }
853
854 /* determine node, memory, and time limits for the sub-SCIP. Both node and time limit change with every call to
855 * the heuristic
856 */
857 SCIP_CALL( setSubscipLimits(scip, subscip, heur, heurdata, &success) );
858
859 /* if we did not succeed to set the limits of the subscip to let it run, we won't keep it any longer */
860 if( !success )
861 {
862 *keepthisscip = FALSE;
863
864 return SCIP_OKAY;
865 }
866
867 /* catch LP events of sub-SCIP */
868 SCIP_CALL( SCIPtransformProb(subscip) );
870
871#ifdef WRITELPFACEPROB
872 {
873 char probfilename[] = "./lpface_prob.mps";
874 char paramfilename[] = "./lpface_prob.set";
875 SCIPinfoMessage(scip, NULL, "Writing problem and parameters to file: <%s> <%s>\n", probfilename, paramfilename);
876 SCIP_CALL( SCIPwriteOrigProblem(subscip, probfilename, NULL, FALSE) );
877 SCIP_CALL( SCIPwriteParams(subscip, paramfilename, TRUE, TRUE) );
878 }
879#endif
880
881 /* we must not be infeasible at this stage */
883
884 /* solve the subproblem */
885 SCIPdebugMsg(scip, "Solve Lpface subMIP\n");
886 SCIPdebug(
887 SCIP_CALL( subscipGetInfo(scip, subscip) );
888 )
889
890 /* Errors in solving the subproblem should not kill the overall solving process.
891 * Hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
892 */
893 SCIP_CALL_ABORT( SCIPsolve(subscip) );
894
895 /* print solving statistics of subproblem if we are in SCIP's debug mode */
897
898 /* save useful information regarding the subscip runs */
899 heurdata->usednodes += SCIPgetNNodes(subscip);
900 heurdata->submipnlpiters += SCIPgetNLPIterations(subscip);
901 heurdata->submippresoltime += SCIPgetPresolvingTime(subscip);
902 heurdata->submipstatus = SCIPgetStatus(subscip);
903
904 /* store the focus node lower bound as infeasible to avoid running on this face again */
905 if( heurdata->submipstatus == SCIP_STATUS_INFEASIBLE )
906 {
907 heurdata->lastlpobjinfeas = focusnodelb;
908 *keepthisscip = FALSE;
909 }
910 else if( SCIPgetNSols(subscip) > 0 )
911 {
912 int solindex;
913
914 /* check, whether a solution was found;
915 * due to numerics, it might happen that not all solutions are feasible -> try all solutions until one is accepted
916 */
917 SCIP_CALL( SCIPtranslateSubSols(scip, subscip, heur, subvars, &success, &solindex) );
918 SCIPdebugMsg(scip, "Transfer was %s successful\n", success ? "" : "not");
919
920 /* we found an optimal solution and are done. Thus, we free the subscip immediately */
921 if( success )
922 {
923 *keepthisscip = FALSE;
925 }
926
927 /* if solution could not be added to problem => run is counted as a failure */
928 if( ! success || solindex != SCIPsolGetIndex(SCIPgetBestSol(scip)) )
930 }
931 else
932 {
933 /* if no new solution was found, run was a failure */
935 }
936
937 return SCIP_OKAY;
938}
939
940/*
941 * Callback methods of primal heuristic
942 */
943
944/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
945static
946SCIP_DECL_HEURCOPY(heurCopyLpface)
947{ /*lint --e{715}*/
948 assert(scip != NULL);
949 assert(heur != NULL);
950
952
953 /* call inclusion method of primal heuristic */
955
956 return SCIP_OKAY;
957}
958
959/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
960static
961SCIP_DECL_HEURFREE(heurFreeLpface)
962{ /*lint --e{715}*/
964
965 assert(heur != NULL);
966 assert(scip != NULL);
967
968 /* get heuristic data */
970 assert(heurdata != NULL);
971
972 /* free heuristic data */
974 SCIPheurSetData(heur, NULL);
975
976 return SCIP_OKAY;
977}
978
979/** initialization method of primal heuristic (called after problem was transformed) */
980static
981SCIP_DECL_HEURINIT(heurInitLpface)
982{ /*lint --e{715}*/
984
985 assert(heur != NULL);
986 assert(scip != NULL);
987
988 /* get heuristic's data */
990 assert(heurdata != NULL);
991
992 /* initialize data */
993 heurdata->usednodes = 0;
994 heurdata->nfailures = 0;
995 heurdata->nextnodenumber = 0;
996
997 heurdata->submipstatus = SCIP_STATUS_UNKNOWN;
998 heurdata->submipnlpiters = -1;
999 heurdata->submippresoltime = 0.0;
1000 heurdata->nvarsfixed = -1;
1001
1002 return SCIP_OKAY;
1003}
1004
1005/** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
1006static
1007SCIP_DECL_HEURINITSOL(heurInitsolLpface)
1008{ /*lint --e{715}*/
1010
1011 assert(heur != NULL);
1012 assert(scip != NULL);
1013
1014 /* get heuristic's data */
1015 heurdata = SCIPheurGetData(heur);
1016 assert(heurdata != NULL);
1017
1018 /* reset the last infeasible objective because it lives in transformed space and must be invalidated at every restart */
1019 heurdata->lastlpobjinfeas = -SCIPinfinity(scip);
1020
1021 assert(heurdata->subscipdata == NULL);
1022
1023 /* variable order might have changed since the last run, reinitialize sub-SCIP data */
1024 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata->subscipdata) );
1025 subscipdataReset(heurdata->subscipdata);
1026
1027 return SCIP_OKAY;
1028}
1029
1030/** solving process deinitialization method of primal heuristic (called before branch and bound process is exiting) */
1031static
1032SCIP_DECL_HEUREXITSOL(heurExitsolLpface)
1033{ /*lint --e{715}*/
1035
1036 assert(heur != NULL);
1037 assert(scip != NULL);
1038
1039 /* get heuristic's data */
1040 heurdata = SCIPheurGetData(heur);
1041 assert(heurdata != NULL);
1042
1043 /* variable order might change after restart, free the heuristic subscipdata */
1044 assert(heurdata->keepsubscip || heurdata->subscipdata->subscip == NULL);
1045 if( heurdata->subscipdata->subscip != NULL )
1046 {
1047 /* free kept data structures first */
1049 }
1050
1051 /* free the sub-SCIP data structure */
1052 SCIPfreeBlockMemory(scip, &heurdata->subscipdata);
1053
1054 return SCIP_OKAY;
1055}
1056
1057#ifdef SCIP_STATISTIC
1058/** deinitialization method of primal heuristic (called before transformed problem is freed) */
1059static
1061{ /*lint --e{715}*/
1063
1064 assert(heur != NULL);
1065 assert(scip != NULL);
1066
1067 /* get heuristic's data */
1068 heurdata = SCIPheurGetData(heur);
1069 assert(heurdata != NULL);
1070
1072 "LP Face heuristic stats: Status: %d Nodes: %d LP iters: %d Fixed: %d Presolving time: %.2f\n",
1073 heurdata->submipstatus, heurdata->usednodes, heurdata->submipnlpiters, heurdata->nvarsfixed, heurdata->submippresoltime);
1074
1075 return SCIP_OKAY;
1076}
1077#else
1078#define heurExitLpface NULL
1079#endif
1080
1081/** execution method of primal heuristic */
1082static
1083SCIP_DECL_HEUREXEC(heurExecLpface)
1084{ /*lint --e{715}*/
1085 SCIP* subscip; /* the subproblem created by lpface */
1086 SCIP_HEURDATA* heurdata; /* primal heuristic data */
1087 SCIP_VAR** vars; /* original problem's variables */
1088 SCIP_VAR** subvars; /* subproblem's variables */
1089 SCIP_RETCODE retcode;
1090 SCIP_Bool keepthisscip;
1091 SCIP_Real focusnodelb;
1092 SCIP_Real rootlb;
1093 SCIP_Longint nodelimit; /* node limit for the subproblem */
1094 int nvars; /* number of original problem's variables */
1095 int nbinvars;
1096 int nintvars;
1097
1098 assert(scip != NULL);
1099 assert(heur != NULL);
1100 assert(result != NULL);
1101
1103
1104 /* we skip infeasible nodes */
1105 if( nodeinfeasible )
1106 return SCIP_OKAY;
1107
1108 /* do not run heuristic on nodes that were not solved to optimality */
1110 return SCIP_OKAY;
1111
1112 /* LP face requires that the LP defines a valid lower bound for the current node */
1114 return SCIP_OKAY;
1115
1118 assert(!SCIPisInfinity(scip, focusnodelb));
1119
1120 /* do not run if the current focus node already has a lower bound higher than the LP value at the node,
1121 * for example, due to strong branching
1122 */
1123 if( SCIPisGT(scip, focusnodelb, SCIPgetLPObjval(scip)) )
1124 return SCIP_OKAY;
1125
1126 /* from the checked conditions, the LP objective should be the lower bound for the current node */
1127 assert(SCIPisEQ(scip, focusnodelb, SCIPgetLPObjval(scip)));
1128
1129 /* only run at lower bound defining nodes */
1130 if( SCIPisGT(scip, focusnodelb, SCIPgetLowerbound(scip)) )
1131 return SCIP_OKAY;
1132
1133 /* get heuristic's data */
1134 heurdata = SCIPheurGetData(heur);
1135 assert(heurdata != NULL);
1136
1137 /* delay heuristic if the active search tree path is not deep enough */
1138 if( SCIPgetDepth(scip) < heurdata->minpathlen - 1 )
1139 return SCIP_OKAY;
1140
1141 /* the node number to run the heuristic again was not yet reached */
1142 if( SCIPgetNNodes(scip) < heurdata->nextnodenumber )
1143 return SCIP_OKAY;
1144
1145 /* only run if lower bound has increased since last LP objective where the sub-MIP was solved to infeasibility */
1146 if( SCIPisEQ(scip, heurdata->lastlpobjinfeas, focusnodelb) )
1147 return SCIP_OKAY;
1148
1149 /* make the reasoning stronger if the objective value must be integral */
1151 && (! SCIPisIntegral(scip, focusnodelb) || SCIPisLT(scip, focusnodelb, heurdata->lastlpobjinfeas + 1.0)) )
1152 return SCIP_OKAY;
1153
1154 rootlb = SCIPgetLowerboundRoot(scip);
1155 assert(SCIPisLE(scip, rootlb, focusnodelb));
1156
1157 /* if the lower bound hasn't changed since the root node, we want to run anyway, otherwise we base our decision on the
1158 * total path length of the active search tree along which the lower bound did not change anymore.
1159 */
1160 if( SCIPisLT(scip, rootlb, focusnodelb) )
1161 {
1162 SCIP_NODE* parent;
1163 int nonimprovingpathlen = 0; /* the length of the current path (in edges) along which the lower bound stayed the same */
1164
1166
1167 /* count the path length along which the dual bound has not changed */
1168 while( SCIPisEQ(scip, SCIPnodeGetLowerbound(parent), focusnodelb) && nonimprovingpathlen < heurdata->minpathlen )
1169 {
1170 ++nonimprovingpathlen;
1171
1172 /* we cannot hit the root node because the root lower bound is strictly smaller */
1173 assert(SCIPnodeGetParent(parent) != NULL);
1174 parent = SCIPnodeGetParent(parent);
1175 }
1176
1177 /* we return if the nonimproving path is too short measured by the heuristic frequency */
1178 if( nonimprovingpathlen < heurdata->minpathlen )
1179 {
1180 /* we do not delay the heuristic if the path has length zero, otherwise it may be called at children so that
1181 * the path length is sufficient
1182 */
1183 if( nonimprovingpathlen == 0 )
1185
1186 return SCIP_OKAY;
1187 }
1188 }
1189
1191
1192 /* calculate the maximal number of branching nodes until heuristic is aborted */
1193 nodelimit = calcNodeLimit(scip, heur, heurdata);
1194
1195 /* check whether we have enough nodes left to call subproblem solving */
1196 if( nodelimit < heurdata->minnodes )
1197 return SCIP_OKAY;
1198
1199 if( SCIPisStopped(scip) )
1200 return SCIP_OKAY;
1201
1202 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, &nintvars, NULL, NULL) );
1203 assert(nvars > 0);
1204
1205 /* check whether discrete variables are present */
1206 if( nbinvars == 0 && nintvars == 0 )
1207 return SCIP_OKAY;
1208
1210
1211 keepthisscip = heurdata->keepsubscip;
1212
1213 /* check if variable number increased since last call to the sub-SCIP */
1214 if( heurdata->subscipdata->subscip != NULL && heurdata->subscipdata->nsubvars != nvars )
1215 {
1216 SCIPdebugMsg(scip, "Free subscip of LP face heuristic because variable number %d changed since last call (was %d)\n",
1217 nvars, heurdata->subscipdata->nsubvars);
1218
1220 }
1221 else if( heurdata->subscipdata->subscip != NULL && SCIPisGT(scip, focusnodelb, heurdata->subscipdata->objbound) )
1222 {
1223 SCIPdebugMsg(scip, "Free subscip of LP face heuristic because of different dual bound: %16.9g > %16.9g\n",
1224 SCIPretransformObj(scip, focusnodelb), SCIPretransformObj(scip, heurdata->subscipdata->objbound));
1225
1227 }
1228
1229 /* retrieve the sub-SCIP from the heuristic data structure */
1230 if( heurdata->subscipdata->subscip != NULL )
1231 {
1232 subscip = heurdata->subscipdata->subscip;
1233 subvars = heurdata->subscipdata->subvars;
1234 nvars = heurdata->subscipdata->nsubvars;
1235
1236 SCIPdebug(
1237 SCIPdebugMsg(scip, "Loaded sub-SCIP from previous run:\n");
1238 SCIP_CALL( subscipGetInfo(scip, subscip) );
1239 )
1240 }
1241 else
1242 {
1243 SCIP_VAR** fixvars;
1244 SCIP_Real* fixvals;
1245 int nfixvars;
1246 SCIP_Bool success;
1247
1248 assert(heurdata->subscipdata->subscip == NULL);
1249
1250 /* allocate memory to hold sub-SCIP variables */
1252
1255
1256 SCIP_CALL( determineVariableFixings(scip, heurdata, fixvars, fixvals, &nfixvars, &success) );
1257
1258 if( ! success )
1259 {
1260 SCIPfreeBufferArray(scip, &fixvals);
1261 SCIPfreeBufferArray(scip, &fixvars);
1262 SCIPfreeBufferArray(scip, &subvars);
1263
1265 return SCIP_OKAY;
1266 }
1267
1268 SCIPdebugMsg(scip, "Creating new sub-Problem for LP face heuristic\n");
1269
1270 /* initialize the subproblem */
1271 SCIP_CALL( SCIPcreate(&subscip) );
1272
1273 SCIP_CALL( setupSubscipLpface(scip, subscip, heurdata, subvars, vars, fixvars, fixvals, nfixvars, nvars) );
1274
1275 SCIPfreeBufferArray(scip, &fixvals);
1276 SCIPfreeBufferArray(scip, &fixvars);
1277 }
1278
1279 retcode = solveSubscipLpface(scip, subscip, heur, heurdata, subvars, result, focusnodelb, &keepthisscip);
1280
1281 SCIP_CALL( retcode );
1282
1283 /* free subproblem or store it for the next run of the heuristic */
1284 if( ! keepthisscip )
1285 {
1286 /* we only allocated buffer memory if no previous subscip was reinstalled */
1287 if( heurdata->subscipdata->subscip == NULL )
1288 {
1289 SCIPfreeBufferArray(scip, &subvars);
1290 SCIP_CALL( SCIPfree(&subscip) );
1291 }
1292 else
1294
1295 subscipdataReset(heurdata->subscipdata);
1296 }
1297 else
1298 {
1299 /* if the subscip has not yet been stored, we copy the subscip into the heuristic data to keep it for the next run */
1300 if( heurdata->subscipdata->subscip == NULL )
1301 {
1302 SCIP_CALL( subscipdataCopySubscip(scip, heurdata->subscipdata, subscip, subvars, nvars) );
1303 SCIPfreeBufferArray(scip, &subvars);
1304 }
1305 else
1306 {
1307 assert(heurdata->subscipdata->subscip == subscip);
1308 assert(heurdata->subscipdata->subvars == subvars);
1309 assert(heurdata->subscipdata->nsubvars == nvars);
1310 }
1311 }
1312
1313 return SCIP_OKAY;
1314}
1315
1316/*
1317 * primal heuristic specific interface methods
1318 */
1319
1320/** creates the lpface primal heuristic and includes it in SCIP */
1322 SCIP* scip /**< SCIP data structure */
1323 )
1324{
1326 SCIP_HEUR* heur;
1327
1328 /* create Lpface primal heuristic data */
1330
1331 heurdata->subscipdata = NULL;
1332
1333 /* include primal heuristic */
1336 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecLpface, heurdata) );
1337
1338 assert(heur != NULL);
1339
1340 /* primal heuristic is safe to use in exact solving mode */
1341 SCIPheurMarkExact(heur);
1342
1343 /* set non-NULL pointers to callback methods */
1344 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyLpface) );
1345 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeLpface) );
1346 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitLpface) );
1347 SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolLpface) );
1348 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolLpface) );
1350
1351 /* add lpface primal heuristic parameters */
1352 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
1353 "number of nodes added to the contingent of the total nodes",
1354 &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1355
1356 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
1357 "maximum number of nodes to regard in the subproblem",
1358 &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1359
1360 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
1361 "minimum number of nodes required to start the subproblem",
1362 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1363
1364 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
1365 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
1366 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
1367
1368 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minfixingrate",
1369 "required percentage of fixed integer variables in sub-MIP to run",
1370 &heurdata->minfixingrate, FALSE, DEFAULT_MINFIXINGRATE, 0.0, 1.0, NULL, NULL) );
1371
1372 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lplimfac",
1373 "factor by which the limit on the number of LP depends on the node limit",
1374 &heurdata->lplimfac, TRUE, DEFAULT_LPLIMFAC, 1.0, SCIP_REAL_MAX, NULL, NULL) );
1375
1376 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/uselprows",
1377 "should subproblem be created out of the rows in the LP rows?",
1378 &heurdata->uselprows, TRUE, DEFAULT_USELPROWS, NULL, NULL) );
1379
1380 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/dualbasisequations",
1381 "should dually nonbasic rows be turned into equations?",
1382 &heurdata->dualbasisequations, TRUE, DEFAULT_DUALBASISEQUATIONS, NULL, NULL) );
1383
1384 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/keepsubscip",
1385 "should the heuristic continue solving the same sub-SCIP?",
1386 &heurdata->keepsubscip, TRUE, DEFAULT_KEEPSUBSCIP, NULL, NULL) );
1387
1388 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
1389 "if uselprows == FALSE, should all active cuts from cutpool be copied to constraints in subproblem?",
1390 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
1391
1392 SCIP_CALL( SCIPaddCharParam(scip, "heuristics/" HEUR_NAME "/subscipobjective",
1393 "objective function in the sub-SCIP: (z)ero, (r)oot-LP-difference, (i)nference, LP (f)ractionality, (o)riginal",
1394 &heurdata->subscipobjective, TRUE, 'z', "forzi", NULL, NULL) );
1395
1396 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/minpathlen",
1397 "the minimum active search tree path length along which lower bound hasn't changed before heuristic becomes active",
1398 &heurdata->minpathlen, TRUE, DEFAULT_MINPATHLEN, 0, 65531, NULL, NULL) );
1399
1400 return SCIP_OKAY;
1401}
#define EVENTHDLR_NAME
#define EVENTHDLR_DESC
#define DEFAULT_MAXNODES
Constraint handler for linear constraints in their most general form, .
#define NULL
Definition def.h:257
#define SCIP_MAXSTRLEN
Definition def.h:278
#define SCIP_Longint
Definition def.h:150
#define SCIP_REAL_MAX
Definition def.h:167
#define SCIP_INVALID
Definition def.h:187
#define SCIP_Bool
Definition def.h:100
#define MIN(x, y)
Definition def.h:233
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define MAX(x, y)
Definition def.h:229
#define SCIP_CALL_ABORT(x)
Definition def.h:343
#define SCIP_LONGINT_FORMAT
Definition def.h:157
#define REALABS(x)
Definition def.h:191
#define SCIP_LONGINT_MAX
Definition def.h:151
#define SCIP_CALL(x)
Definition def.h:364
#define DEFAULT_MINNODES
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPcopyPlugins(SCIP *sourcescip, SCIP *targetscip, SCIP_Bool copyreaders, SCIP_Bool copypricers, SCIP_Bool copyconshdlrs, SCIP_Bool copyconflicthdlrs, SCIP_Bool copypresolvers, SCIP_Bool copyrelaxators, SCIP_Bool copyseparators, SCIP_Bool copycutselectors, SCIP_Bool copypropagators, SCIP_Bool copyheuristics, SCIP_Bool copyeventhdlrs, SCIP_Bool copynodeselectors, SCIP_Bool copybranchrules, SCIP_Bool copyiisfinders, SCIP_Bool copydisplays, SCIP_Bool copydialogs, SCIP_Bool copytables, SCIP_Bool copyexprhdlrs, SCIP_Bool copynlpis, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
Definition scip_copy.c:276
void SCIPsetSubscipDepth(SCIP *scip, int newdepth)
Definition scip_copy.c:2610
SCIP_RETCODE SCIPtranslateSubSols(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_Bool *success, int *solindex)
Definition scip_copy.c:1438
SCIP_RETCODE SCIPcopyVars(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool global)
Definition scip_copy.c:1168
SCIP_RETCODE SCIPcopyConsCompression(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool threadsafe, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
Definition scip_copy.c:2962
int SCIPgetSubscipDepth(SCIP *scip)
Definition scip_copy.c:2589
SCIP_RETCODE SCIPcopyCuts(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
Definition scip_copy.c:2114
SCIP_RETCODE SCIPcopyParamSettings(SCIP *sourcescip, SCIP *targetscip)
Definition scip_copy.c:2548
SCIP_Bool SCIPisStopped(SCIP *scip)
SCIP_RETCODE SCIPfree(SCIP **scip)
SCIP_RETCODE SCIPcreate(SCIP **scip)
SCIP_STATUS SCIPgetStatus(SCIP *scip)
int SCIPgetNObjVars(SCIP *scip)
Definition scip_prob.c:2616
const char * SCIPgetProbName(SCIP *scip)
Definition scip_prob.c:1242
SCIP_RETCODE SCIPwriteOrigProblem(SCIP *scip, const char *filename, const char *extension, SCIP_Bool genericnames)
Definition scip_prob.c:742
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
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:3274
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition scip_prob.c:2201
SCIP_RETCODE SCIPcreateProbBasic(SCIP *scip, const char *name)
Definition scip_prob.c:182
SCIP_Bool SCIPisObjIntegral(SCIP *scip)
Definition scip_prob.c:1801
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
SCIP_Real SCIPgetNodeLowerbound(SCIP *scip, SCIP_NODE *node)
Definition scip_prob.c:4215
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
#define SCIPdebugMsg
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 SCIPaddCharParam(SCIP *scip, const char *name, const char *desc, char *valueptr, SCIP_Bool isadvanced, char defaultvalue, const char *allowedvalues, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:167
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 SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
Definition scip_param.c:307
SCIP_RETCODE SCIPwriteParams(SCIP *scip, const char *filename, SCIP_Bool comments, SCIP_Bool onlychanged)
Definition scip_param.c:813
SCIP_RETCODE SCIPsetPresolving(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition scip_param.c:956
SCIP_RETCODE SCIPsetCharParam(SCIP *scip, const char *name, char value)
Definition scip_param.c:661
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 SCIPgetLongintParam(SCIP *scip, const char *name, SCIP_Longint *value)
Definition scip_param.c:288
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition scip_param.c:429
SCIP_RETCODE SCIPsetRealParam(SCIP *scip, const char *name, SCIP_Real value)
Definition scip_param.c:603
SCIP_RETCODE SCIPsetSeparating(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition scip_param.c:985
SCIP_RETCODE SCIPincludeHeurLpface(SCIP *scip)
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
SCIP_Real SCIPgetColRedcost(SCIP *scip, SCIP_COL *col)
Definition scip_lp.c:1163
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
Definition lp.c:17425
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1173
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition scip_event.c:111
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition event.c:396
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition event.c:1194
SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition scip_event.c:293
SCIP_Bool SCIPisExact(SCIP *scip)
Definition scip_exact.c:193
SCIP_RETCODE SCIPenableExactSolving(SCIP *scip, SCIP_Bool enable)
Definition scip_exact.c:151
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:183
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition heur.c:1368
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition scip_heur.c:122
SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:231
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:167
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition heur.c:1593
SCIP_RETCODE SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:247
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
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition heur.c:1378
SCIP_Bool SCIPisLPRelax(SCIP *scip)
Definition scip_lp.c:231
SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
Definition scip_lp.c:576
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
Definition scip_lp.c:174
SCIP_Bool SCIPallColsInLP(SCIP *scip)
Definition scip_lp.c:655
SCIP_Real SCIPgetLPObjval(SCIP *scip)
Definition scip_lp.c:253
SCIP_Longint SCIPgetMemExternEstim(SCIP *scip)
Definition scip_mem.c:126
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:110
SCIP_Longint SCIPgetMemUsed(SCIP *scip)
Definition scip_mem.c:100
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition scip_mem.c:57
#define SCIPallocBufferArray(scip, ptr, num)
Definition scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition scip_mem.h:136
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition scip_mem.h:105
SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
Definition tree.c:8533
SCIP_NODE * SCIPnodeGetParent(SCIP_NODE *node)
Definition tree.c:8812
SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
Definition lp.c:17686
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_Bool SCIProwIsLocal(SCIP_ROW *row)
Definition lp.c:17795
const char * SCIProwGetName(SCIP_ROW *row)
Definition lp.c:17745
SCIP_Real SCIPgetRowActivity(SCIP *scip, SCIP_ROW *row)
Definition scip_lp.c:2068
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
Definition lp.c:17652
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition lp.c:17706
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
Definition lp.c:17642
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition scip_sol.c:2986
int SCIPgetNSols(SCIP *scip)
Definition scip_sol.c:2887
int SCIPsolGetIndex(SCIP_SOL *sol)
Definition sol.c:4305
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1763
SCIP_Real SCIPretransformObj(SCIP *scip, SCIP_Real obj)
Definition scip_sol.c:2134
SCIP_RETCODE SCIPtransformProb(SCIP *scip)
Definition scip_solve.c:232
SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
SCIP_RETCODE SCIPsolve(SCIP *scip)
SCIP_Real SCIPgetLowerboundRoot(SCIP *scip)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
SCIP_Real SCIPgetLowerbound(SCIP *scip)
SCIP_Longint SCIPgetNLPs(SCIP *scip)
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
SCIP_Real SCIPgetPresolvingTime(SCIP *scip)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfrac(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisDualfeasZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
int SCIPgetDepth(SCIP *scip)
Definition scip_tree.c:672
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition scip_tree.c:91
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
Definition var.c:23715
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition var.c:23418
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:23932
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:24174
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition var.c:23694
SCIP_Real SCIPvarGetRootSol(SCIP_VAR *var)
Definition var.c:19144
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition var.c:23522
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition var.c:24696
SCIP_Bool SCIPvarIsRelaxationOnly(SCIP_VAR *var)
Definition var.c:23632
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:24152
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition scip_var.c:5372
SCIP_Real SCIPgetVarAvgInferences(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition scip_var.c:11891
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10827
#define HEUR_TIMING
return SCIP_OKAY
#define HEUR_FREQOFS
#define HEUR_DESC
#define HEUR_DISPCHAR
#define HEUR_MAXDEPTH
#define HEUR_PRIORITY
#define HEUR_NAME
#define HEUR_FREQ
#define HEUR_USESSUBSCIP
#define DEFAULT_NODESQUOT
Definition heur_alns.c:90
#define DEFAULT_COPYCUTS
Definition heur_alns.c:147
#define DEFAULT_NODESOFS
Definition heur_clique.c:94
#define DEFAULT_LPLIMFAC
#define DEFAULT_MINFIXINGRATE
#define DEFAULT_USELPROWS
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
heurdata usednodes
Definition heur_locks.c:163
static SCIP_RETCODE setSubscipLimits(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_Bool *success)
static SCIP_RETCODE createRows(SCIP *scip, SCIP *subscip, SCIP_VAR **subvars, SCIP_Bool dualbasisequations)
static SCIP_RETCODE subscipdataCopySubscip(SCIP *scip, SUBSCIPDATA *subscipdata, SCIP *subscip, SCIP_VAR **subvars, int nvars)
static SCIP_RETCODE setSubscipParameters(SCIP *subscip)
static SCIP_RETCODE setupSubscipLpface(SCIP *scip, SCIP *subscip, SCIP_HEURDATA *heurdata, SCIP_VAR **subvars, SCIP_VAR **vars, SCIP_VAR **fixvars, SCIP_Real *fixvals, int nfixvars, int nvars)
struct SubscipData SUBSCIPDATA
static SCIP_RETCODE subscipdataFreeSubscip(SCIP *scip, SUBSCIPDATA *subscipdata)
static SCIP_RETCODE changeSubvariableObjective(SCIP *scip, SCIP *subscip, SCIP_VAR *var, SCIP_VAR *subvar, SCIP_HEURDATA *heurdata)
static SCIP_RETCODE solveSubscipLpface(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_VAR **subvars, SCIP_RESULT *result, SCIP_Real focusnodelb, SCIP_Bool *keepthisscip)
static SCIP_Longint calcNodeLimit(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
#define DEFAULT_KEEPSUBSCIP
Definition heur_lpface.c:88
#define heurExitLpface
#define DEFAULT_DUALBASISEQUATIONS
Definition heur_lpface.c:87
static SCIP_RETCODE determineVariableFixings(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR **fixvars, SCIP_Real *fixvals, int *nfixvars, SCIP_Bool *success)
#define DEFAULT_MINPATHLEN
Definition heur_lpface.c:89
static void updateFailureStatistic(SCIP *scip, SCIP_HEURDATA *heurdata)
static void subscipdataReset(SUBSCIPDATA *subscipdata)
static SCIP_RETCODE setupSubproblem(SCIP *scip, SCIP *subscip, SCIP_VAR **subvars, SCIP_HEURDATA *heurdata)
LNS heuristic that tries to compute integral solution on optimal LP face.
SCIP_VAR * var
static SCIP_VAR ** vars
memory allocation routines
public methods for managing events
public methods for primal heuristics
public methods for LP management
public methods for message output
#define SCIPerrorMessage
Definition pub_message.h:64
#define SCIPdebug(x)
Definition pub_message.h:93
public data structures and miscellaneous methods
public methods for primal CIP solutions
public methods for branch and bound tree
public methods for problem variables
public methods for branching rule plugins and branching
public methods for constraint handler plugins and constraints
public methods for problem copies
public methods for event handler plugins and event handlers
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 node selector plugins
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for solutions
public solving methods
public methods for querying solving statistics
public methods for timing
public methods for the branch-and-bound tree
public methods for SCIP variables
default SCIP plugins
SCIP * subscip
SCIP_VAR ** subvars
SCIP_Real objbound
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
struct SCIP_Eventhdlr SCIP_EVENTHDLR
Definition type_event.h:159
struct SCIP_EventData SCIP_EVENTDATA
Definition type_event.h:179
#define SCIP_DECL_EVENTEXEC(x)
Definition type_event.h:259
#define SCIP_EVENTTYPE_LPSOLVED
Definition type_event.h:102
#define SCIP_DECL_HEURINITSOL(x)
Definition type_heur.h:132
#define SCIP_DECL_HEURCOPY(x)
Definition type_heur.h:97
struct SCIP_HeurData SCIP_HEURDATA
Definition type_heur.h:77
struct SCIP_Heur SCIP_HEUR
Definition type_heur.h:76
#define SCIP_DECL_HEURINIT(x)
Definition type_heur.h:113
#define SCIP_DECL_HEUREXIT(x)
Definition type_heur.h:121
#define SCIP_DECL_HEURFREE(x)
Definition type_heur.h:105
#define SCIP_DECL_HEUREXITSOL(x)
Definition type_heur.h:143
#define SCIP_DECL_HEUREXEC(x)
Definition type_heur.h:163
@ SCIP_BRANCHDIR_DOWNWARDS
@ SCIP_BRANCHDIR_UPWARDS
struct SCIP_Row SCIP_ROW
Definition type_lp.h:105
struct SCIP_Col SCIP_COL
Definition type_lp.h:99
@ SCIP_LPSOLSTAT_OPTIMAL
Definition type_lp.h:44
@ SCIP_VERBLEVEL_HIGH
struct SCIP_HashMap SCIP_HASHMAP
Definition type_misc.h:106
@ SCIP_PARAMSETTING_FAST
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_DELAYED
Definition type_result.h:43
@ SCIP_DIDNOTFIND
Definition type_result.h:44
@ SCIP_FOUNDSOL
Definition type_result.h:56
enum SCIP_Result SCIP_RESULT
Definition type_result.h:61
@ SCIP_PLUGINNOTFOUND
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
@ SCIP_STATUS_UNKNOWN
Definition type_stat.h:42
@ SCIP_STATUS_INFEASIBLE
Definition type_stat.h:44
enum SCIP_Status SCIP_STATUS
Definition type_stat.h:64
struct SCIP_Node SCIP_NODE
Definition type_tree.h:63
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_VARSTATUS_COLUMN
Definition type_var.h:53