Scippy

SCIP

Solving Constraint Integer Programs

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-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_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#include <string.h>
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 */
189 if( SCIPvarIsRelaxationOnly(var) )
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
213 if( SCIPvarIsIntegral(var) )
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{
339 SCIP_VAR** vars = SCIPgetVars(scip);
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);
598 assert(nvars == SCIPgetNVars(scip));
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{
711 SCIP_HEURDATA* heurdata;
712
713 assert(eventhdlr != NULL);
714 assert(eventdata != NULL);
715 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
716 assert(event != NULL);
718
719 heurdata = (SCIP_HEURDATA*)eventdata;
720 assert(heurdata != NULL);
721
722 /* interrupt solution process of sub-SCIP */
723 if( SCIPgetNLPs(scip) > heurdata->lplimfac * heurdata->nodelimit )
724 {
725 SCIPdebugMsg(scip, "interrupt after %" SCIP_LONGINT_FORMAT " LPs\n",SCIPgetNLPs(scip));
727 }
728
729 return SCIP_OKAY;
730}
731
732/** setup and solve the subproblem and catch the return code */
733static
735 SCIP* scip, /**< SCIP data structure */
736 SCIP* subscip, /**< sub-SCIP data structure */
737 SCIP_HEURDATA* heurdata, /**< heuristics data */
738 SCIP_VAR** subvars, /**< subproblem's variables */
739 SCIP_VAR** vars, /**< original problem's variables */
740 SCIP_VAR** fixvars, /**< variables that should be fixed */
741 SCIP_Real* fixvals, /**< corresponding fixing values */
742 int nfixvars, /**< number of variables that should be fixed */
743 int nvars /**< number of original problem's variables */
744 )
745{
746 SCIP_HASHMAP* varmapfw = NULL; /* mapping of SCIP variables to sub-SCIP variables */
747 SCIP_Bool success;
748 int i;
749
750 assert( subscip != NULL );
751 assert( heurdata != NULL );
752 assert( vars != NULL );
753
754 /* create the variable hash map */
755 SCIP_CALL( SCIPhashmapCreate(&varmapfw, SCIPblkmem(subscip), nvars) );
756 success = FALSE;
757
758 if( heurdata->uselprows )
759 {
760 SCIP_Bool valid;
761 char probname[SCIP_MAXSTRLEN];
762
763 /* copy all plugins */
765 TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, &valid) );
766
767 /* copy parameter settings */
769
770 /* even when solving exactly, sub-SCIP heuristics should be run in floating-point mode, since the exactsol constraint
771 * handler is in place to perform a final repair step
772 */
774
775 /* get name of the original problem and add the string "_lpfacesub" */
776 (void) SCIPsnprintf(probname, SCIP_MAXSTRLEN, "%s_lpfacesub", SCIPgetProbName(scip));
777
778 /* create the subproblem */
779 SCIP_CALL( SCIPcreateProbBasic(subscip, probname) );
781
782 /* copy all variables */
783 SCIP_CALL( SCIPcopyVars(scip, subscip, varmapfw, NULL, fixvars, fixvals, nfixvars, TRUE) );
784 }
785 else
786 {
787 SCIP_CALL( SCIPcopyConsCompression(scip, subscip, varmapfw, NULL, "lpface", fixvars, fixvals, nfixvars, TRUE, FALSE, FALSE, TRUE, &success) );
788
789 if( heurdata->copycuts )
790 {
791 /* copies all active cuts from cutpool of sourcescip to linear constraints in targetscip */
792 SCIP_CALL( SCIPcopyCuts(scip, subscip, varmapfw, NULL, TRUE, NULL) );
793 }
794 }
795 assert(!SCIPisExact(subscip));
796
797 /* fill subvars array with mapping from original variables and set the objective coefficient to the desired value */
798 for( i = 0; i < nvars; i++ )
799 {
800 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmapfw, vars[i]);
801
802 if( subvars[i] != NULL )
803 {
804 SCIP_CALL( changeSubvariableObjective(scip, subscip, vars[i], subvars[i], heurdata) );
805 }
806 }
807
808 /* free hash map */
809 SCIPhashmapFree(&varmapfw);
810
811 /* disable output to console */
812 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
813
814 /* fix variables that are at their bounds and have nonzero reduced costs */
815 SCIP_CALL( setupSubproblem(scip, subscip, subvars, heurdata) );
816
817 /* set up sub-SCIP parameters */
819
820 return SCIP_OKAY;
821}
822
823/** setup and solve the subproblem and catch the return code */
824static
826 SCIP* scip, /**< SCIP data structure */
827 SCIP* subscip, /**< sub-SCIP data structure */
828 SCIP_HEUR* heur, /**< mutation heuristic */
829 SCIP_HEURDATA* heurdata, /**< heuristics data */
830 SCIP_VAR** subvars, /**< subproblem's variables */
831 SCIP_RESULT* result, /**< pointer to store the result */
832 SCIP_Real focusnodelb, /**< lower bound of the focus node */
833 SCIP_Bool* keepthisscip /**< should the subscip be kept or deleted? */
834 )
835{
836 SCIP_EVENTHDLR* eventhdlr;
837 SCIP_Bool success;
838
839 assert( scip != NULL );
840 assert( subscip != NULL );
841 assert( heur != NULL );
842 assert( heurdata != NULL );
843 assert( subvars != NULL );
844
845 /* create event handler for LP events */
846 SCIP_CALL( SCIPincludeEventhdlrBasic(subscip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecLpface, NULL) );
847 if( eventhdlr == NULL )
848 {
849 SCIPerrorMessage("event handler for " HEUR_NAME " heuristic not found.\n");
850 return SCIP_PLUGINNOTFOUND;
851 }
852
853 /* determine node, memory, and time limits for the sub-SCIP. Both node and time limit change with every call to
854 * the heuristic
855 */
856 SCIP_CALL( setSubscipLimits(scip, subscip, heur, heurdata, &success) );
857
858 /* if we did not succeed to set the limits of the subscip to let it run, we won't keep it any longer */
859 if( !success )
860 {
861 *keepthisscip = FALSE;
862
863 return SCIP_OKAY;
864 }
865
866 /* catch LP events of sub-SCIP */
867 SCIP_CALL( SCIPtransformProb(subscip) );
868 SCIP_CALL( SCIPcatchEvent(subscip, SCIP_EVENTTYPE_LPSOLVED, eventhdlr, (SCIP_EVENTDATA*) heurdata, NULL) );
869
870#ifdef WRITELPFACEPROB
871 {
872 char probfilename[] = "./lpface_prob.mps";
873 char paramfilename[] = "./lpface_prob.set";
874 SCIPinfoMessage(scip, NULL, "Writing problem and parameters to file: <%s> <%s>\n", probfilename, paramfilename);
875 SCIP_CALL( SCIPwriteOrigProblem(subscip, probfilename, NULL, FALSE) );
876 SCIP_CALL( SCIPwriteParams(subscip, paramfilename, TRUE, TRUE) );
877 }
878#endif
879
880 /* we must not be infeasible at this stage */
881 assert(SCIPgetStatus(subscip) != SCIP_STATUS_INFEASIBLE);
882
883 /* solve the subproblem */
884 SCIPdebugMsg(scip, "Solve Lpface subMIP\n");
885 SCIPdebug(
886 SCIP_CALL( subscipGetInfo(scip, subscip) );
887 )
888
889 /* Errors in solving the subproblem should not kill the overall solving process.
890 * Hence, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
891 */
892 SCIP_CALL_ABORT( SCIPsolve(subscip) );
893
894 /* print solving statistics of subproblem if we are in SCIP's debug mode */
896
897 /* save useful information regarding the subscip runs */
898 heurdata->usednodes += SCIPgetNNodes(subscip);
899 heurdata->submipnlpiters += SCIPgetNLPIterations(subscip);
900 heurdata->submippresoltime += SCIPgetPresolvingTime(subscip);
901 heurdata->submipstatus = SCIPgetStatus(subscip);
902
903 /* store the focus node lower bound as infeasible to avoid running on this face again */
904 if( heurdata->submipstatus == SCIP_STATUS_INFEASIBLE )
905 {
906 heurdata->lastlpobjinfeas = focusnodelb;
907 *keepthisscip = FALSE;
908 }
909 else if( SCIPgetNSols(subscip) > 0 )
910 {
911 int solindex;
912
913 /* check, whether a solution was found;
914 * due to numerics, it might happen that not all solutions are feasible -> try all solutions until one is accepted
915 */
916 SCIP_CALL( SCIPtranslateSubSols(scip, subscip, heur, subvars, &success, &solindex) );
917 SCIPdebugMsg(scip, "Transfer was %s successful\n", success ? "" : "not");
918
919 /* we found an optimal solution and are done. Thus, we free the subscip immediately */
920 if( success )
921 {
922 *keepthisscip = FALSE;
923 *result = SCIP_FOUNDSOL;
924 }
925
926 /* if solution could not be added to problem => run is counted as a failure */
927 if( ! success || solindex != SCIPsolGetIndex(SCIPgetBestSol(scip)) )
928 updateFailureStatistic(scip, heurdata);
929 }
930 else
931 {
932 /* if no new solution was found, run was a failure */
933 updateFailureStatistic(scip, heurdata);
934 }
935
936 return SCIP_OKAY;
937}
938
939/*
940 * Callback methods of primal heuristic
941 */
942
943/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
944static
945SCIP_DECL_HEURCOPY(heurCopyLpface)
946{ /*lint --e{715}*/
947 assert(scip != NULL);
948 assert(heur != NULL);
949 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
950
951 /* call inclusion method of primal heuristic */
953
954 return SCIP_OKAY;
955}
956
957/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
958static
959SCIP_DECL_HEURFREE(heurFreeLpface)
960{ /*lint --e{715}*/
961 SCIP_HEURDATA* heurdata;
962
963 assert(heur != NULL);
964 assert(scip != NULL);
965
966 /* get heuristic data */
967 heurdata = SCIPheurGetData(heur);
968 assert(heurdata != NULL);
969
970 /* free heuristic data */
971 SCIPfreeBlockMemory(scip, &heurdata);
972 SCIPheurSetData(heur, NULL);
973
974 return SCIP_OKAY;
975}
976
977/** initialization method of primal heuristic (called after problem was transformed) */
978static
979SCIP_DECL_HEURINIT(heurInitLpface)
980{ /*lint --e{715}*/
981 SCIP_HEURDATA* heurdata;
982
983 assert(heur != NULL);
984 assert(scip != NULL);
985
986 /* get heuristic's data */
987 heurdata = SCIPheurGetData(heur);
988 assert(heurdata != NULL);
989
990 /* initialize data */
991 heurdata->usednodes = 0;
992 heurdata->nfailures = 0;
993 heurdata->nextnodenumber = 0;
994
995 heurdata->submipstatus = SCIP_STATUS_UNKNOWN;
996 heurdata->submipnlpiters = -1;
997 heurdata->submippresoltime = 0.0;
998 heurdata->nvarsfixed = -1;
999
1000 return SCIP_OKAY;
1001}
1002
1003/** solving process initialization method of primal heuristic (called when branch and bound process is about to begin) */
1004static
1005SCIP_DECL_HEURINITSOL(heurInitsolLpface)
1006{ /*lint --e{715}*/
1007 SCIP_HEURDATA* heurdata;
1008
1009 assert(heur != NULL);
1010 assert(scip != NULL);
1011
1012 /* get heuristic's data */
1013 heurdata = SCIPheurGetData(heur);
1014 assert(heurdata != NULL);
1015
1016 /* reset the last infeasible objective because it lives in transformed space and must be invalidated at every restart */
1017 heurdata->lastlpobjinfeas = -SCIPinfinity(scip);
1018
1019 assert(heurdata->subscipdata == NULL);
1020
1021 /* variable order might have changed since the last run, reinitialize sub-SCIP data */
1022 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata->subscipdata) );
1023 subscipdataReset(heurdata->subscipdata);
1024
1025 return SCIP_OKAY;
1026}
1027
1028/** solving process deinitialization method of primal heuristic (called before branch and bound process is exiting) */
1029static
1030SCIP_DECL_HEUREXITSOL(heurExitsolLpface)
1031{ /*lint --e{715}*/
1032 SCIP_HEURDATA* heurdata;
1033
1034 assert(heur != NULL);
1035 assert(scip != NULL);
1036
1037 /* get heuristic's data */
1038 heurdata = SCIPheurGetData(heur);
1039 assert(heurdata != NULL);
1040
1041 /* variable order might change after restart, free the heuristic subscipdata */
1042 assert(heurdata->keepsubscip || heurdata->subscipdata->subscip == NULL);
1043 if( heurdata->subscipdata->subscip != NULL )
1044 {
1045 /* free kept data structures first */
1046 SCIP_CALL( subscipdataFreeSubscip(scip, heurdata->subscipdata) );
1047 }
1048
1049 /* free the sub-SCIP data structure */
1050 SCIPfreeBlockMemory(scip, &heurdata->subscipdata);
1051
1052 return SCIP_OKAY;
1053}
1054
1055#ifdef SCIP_STATISTIC
1056/** deinitialization method of primal heuristic (called before transformed problem is freed) */
1057static
1059{ /*lint --e{715}*/
1060 SCIP_HEURDATA* heurdata;
1061
1062 assert(heur != NULL);
1063 assert(scip != NULL);
1064
1065 /* get heuristic's data */
1066 heurdata = SCIPheurGetData(heur);
1067 assert(heurdata != NULL);
1068
1070 "LP Face heuristic stats: Status: %d Nodes: %d LP iters: %d Fixed: %d Presolving time: %.2f\n",
1071 heurdata->submipstatus, heurdata->usednodes, heurdata->submipnlpiters, heurdata->nvarsfixed, heurdata->submippresoltime);
1072
1073 return SCIP_OKAY;
1074}
1075#else
1076#define heurExitLpface NULL
1077#endif
1078
1079/** execution method of primal heuristic */
1080static
1081SCIP_DECL_HEUREXEC(heurExecLpface)
1082{ /*lint --e{715}*/
1083 SCIP* subscip; /* the subproblem created by lpface */
1084 SCIP_HEURDATA* heurdata; /* primal heuristic data */
1085 SCIP_VAR** vars; /* original problem's variables */
1086 SCIP_VAR** subvars; /* subproblem's variables */
1087 SCIP_RETCODE retcode;
1088 SCIP_Bool keepthisscip;
1089 SCIP_Real focusnodelb;
1090 SCIP_Real rootlb;
1091 SCIP_Longint nodelimit; /* node limit for the subproblem */
1092 int nvars; /* number of original problem's variables */
1093 int nbinvars;
1094 int nintvars;
1095
1096 assert(scip != NULL);
1097 assert(heur != NULL);
1098 assert(result != NULL);
1099
1100 *result = SCIP_DELAYED;
1101
1102 /* we skip infeasible nodes */
1103 if( nodeinfeasible )
1104 return SCIP_OKAY;
1105
1106 /* do not run heuristic on nodes that were not solved to optimality */
1108 return SCIP_OKAY;
1109
1110 /* LP face requires that the LP defines a valid lower bound for the current node */
1112 return SCIP_OKAY;
1113
1114 assert(SCIPgetCurrentNode(scip) != NULL);
1116 assert(!SCIPisInfinity(scip, focusnodelb));
1117
1118 /* do not run if the current focus node already has a lower bound higher than the LP value at the node,
1119 * for example, due to strong branching
1120 */
1121 if( SCIPisGT(scip, focusnodelb, SCIPgetLPObjval(scip)) )
1122 return SCIP_OKAY;
1123
1124 /* from the checked conditions, the LP objective should be the lower bound for the current node */
1125 assert(SCIPisEQ(scip, focusnodelb, SCIPgetLPObjval(scip)));
1126
1127 /* only run at lower bound defining nodes */
1128 if( SCIPisGT(scip, focusnodelb, SCIPgetLowerbound(scip)) )
1129 return SCIP_OKAY;
1130
1131 /* get heuristic's data */
1132 heurdata = SCIPheurGetData(heur);
1133 assert(heurdata != NULL);
1134
1135 /* delay heuristic if the active search tree path is not deep enough */
1136 if( SCIPgetDepth(scip) < heurdata->minpathlen - 1 )
1137 return SCIP_OKAY;
1138
1139 /* the node number to run the heuristic again was not yet reached */
1140 if( SCIPgetNNodes(scip) < heurdata->nextnodenumber )
1141 return SCIP_OKAY;
1142
1143 /* only run if lower bound has increased since last LP objective where the sub-MIP was solved to infeasibility */
1144 if( SCIPisEQ(scip, heurdata->lastlpobjinfeas, focusnodelb) )
1145 return SCIP_OKAY;
1146
1147 /* make the reasoning stronger if the objective value must be integral */
1149 && (! SCIPisIntegral(scip, focusnodelb) || SCIPisLT(scip, focusnodelb, heurdata->lastlpobjinfeas + 1.0)) )
1150 return SCIP_OKAY;
1151
1152 rootlb = SCIPgetLowerboundRoot(scip);
1153 assert(SCIPisLE(scip, rootlb, focusnodelb));
1154
1155 /* if the lower bound hasn't changed since the root node, we want to run anyway, otherwise we base our decision on the
1156 * total path length of the active search tree along which the lower bound did not change anymore.
1157 */
1158 if( SCIPisLT(scip, rootlb, focusnodelb) )
1159 {
1160 SCIP_NODE* parent;
1161 int nonimprovingpathlen = 0; /* the length of the current path (in edges) along which the lower bound stayed the same */
1162
1164
1165 /* count the path length along which the dual bound has not changed */
1166 while( SCIPisEQ(scip, SCIPnodeGetLowerbound(parent), focusnodelb) && nonimprovingpathlen < heurdata->minpathlen )
1167 {
1168 ++nonimprovingpathlen;
1169
1170 /* we cannot hit the root node because the root lower bound is strictly smaller */
1171 assert(SCIPnodeGetParent(parent) != NULL);
1172 parent = SCIPnodeGetParent(parent);
1173 }
1174
1175 /* we return if the nonimproving path is too short measured by the heuristic frequency */
1176 if( nonimprovingpathlen < heurdata->minpathlen )
1177 {
1178 /* we do not delay the heuristic if the path has length zero, otherwise it may be called at children so that
1179 * the path length is sufficient
1180 */
1181 if( nonimprovingpathlen == 0 )
1182 *result = SCIP_DIDNOTRUN;
1183
1184 return SCIP_OKAY;
1185 }
1186 }
1187
1188 *result = SCIP_DIDNOTRUN;
1189
1190 /* calculate the maximal number of branching nodes until heuristic is aborted */
1191 nodelimit = calcNodeLimit(scip, heur, heurdata);
1192
1193 /* check whether we have enough nodes left to call subproblem solving */
1194 if( nodelimit < heurdata->minnodes )
1195 return SCIP_OKAY;
1196
1197 if( SCIPisStopped(scip) )
1198 return SCIP_OKAY;
1199
1200 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, &nbinvars, &nintvars, NULL, NULL) );
1201 assert(nvars > 0);
1202
1203 /* check whether discrete variables are present */
1204 if( nbinvars == 0 && nintvars == 0 )
1205 return SCIP_OKAY;
1206
1207 *result = SCIP_DIDNOTFIND;
1208
1209 keepthisscip = heurdata->keepsubscip;
1210
1211 /* check if variable number increased since last call to the sub-SCIP */
1212 if( heurdata->subscipdata->subscip != NULL && heurdata->subscipdata->nsubvars != nvars )
1213 {
1214 SCIPdebugMsg(scip, "Free subscip of LP face heuristic because variable number %d changed since last call (was %d)\n",
1215 nvars, heurdata->subscipdata->nsubvars);
1216
1217 SCIP_CALL( subscipdataFreeSubscip(scip, heurdata->subscipdata) );
1218 }
1219 else if( heurdata->subscipdata->subscip != NULL && SCIPisGT(scip, focusnodelb, heurdata->subscipdata->objbound) )
1220 {
1221 SCIPdebugMsg(scip, "Free subscip of LP face heuristic because of different dual bound: %16.9g > %16.9g\n",
1222 SCIPretransformObj(scip, focusnodelb), SCIPretransformObj(scip, heurdata->subscipdata->objbound));
1223
1224 SCIP_CALL( subscipdataFreeSubscip(scip, heurdata->subscipdata) );
1225 }
1226
1227 /* retrieve the sub-SCIP from the heuristic data structure */
1228 if( heurdata->subscipdata->subscip != NULL )
1229 {
1230 subscip = heurdata->subscipdata->subscip;
1231 subvars = heurdata->subscipdata->subvars;
1232 nvars = heurdata->subscipdata->nsubvars;
1233
1234 SCIPdebug(
1235 SCIPdebugMsg(scip, "Loaded sub-SCIP from previous run:\n");
1236 SCIP_CALL( subscipGetInfo(scip, subscip) );
1237 )
1238 }
1239 else
1240 {
1241 SCIP_VAR** fixvars;
1242 SCIP_Real* fixvals;
1243 int nfixvars;
1244 SCIP_Bool success;
1245
1246 assert(heurdata->subscipdata->subscip == NULL);
1247
1248 /* allocate memory to hold sub-SCIP variables */
1249 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
1250
1251 SCIP_CALL( SCIPallocBufferArray(scip, &fixvars, nvars) );
1252 SCIP_CALL( SCIPallocBufferArray(scip, &fixvals, nvars) );
1253
1254 SCIP_CALL( determineVariableFixings(scip, heurdata, fixvars, fixvals, &nfixvars, &success) );
1255
1256 if( ! success )
1257 {
1258 SCIPfreeBufferArray(scip, &fixvals);
1259 SCIPfreeBufferArray(scip, &fixvars);
1260 SCIPfreeBufferArray(scip, &subvars);
1261
1262 *result = SCIP_DIDNOTRUN;
1263 return SCIP_OKAY;
1264 }
1265
1266 SCIPdebugMsg(scip, "Creating new sub-Problem for LP face heuristic\n");
1267
1268 /* initialize the subproblem */
1269 SCIP_CALL( SCIPcreate(&subscip) );
1270
1271 SCIP_CALL( setupSubscipLpface(scip, subscip, heurdata, subvars, vars, fixvars, fixvals, nfixvars, nvars) );
1272
1273 SCIPfreeBufferArray(scip, &fixvals);
1274 SCIPfreeBufferArray(scip, &fixvars);
1275 }
1276
1277 retcode = solveSubscipLpface(scip, subscip, heur, heurdata, subvars, result, focusnodelb, &keepthisscip);
1278
1279 SCIP_CALL( retcode );
1280
1281 /* free subproblem or store it for the next run of the heuristic */
1282 if( ! keepthisscip )
1283 {
1284 /* we only allocated buffer memory if no previous subscip was reinstalled */
1285 if( heurdata->subscipdata->subscip == NULL )
1286 {
1287 SCIPfreeBufferArray(scip, &subvars);
1288 SCIP_CALL( SCIPfree(&subscip) );
1289 }
1290 else
1291 SCIP_CALL( subscipdataFreeSubscip(scip, heurdata->subscipdata) );
1292
1293 subscipdataReset(heurdata->subscipdata);
1294 }
1295 else
1296 {
1297 /* if the subscip has not yet been stored, we copy the subscip into the heuristic data to keep it for the next run */
1298 if( heurdata->subscipdata->subscip == NULL )
1299 {
1300 SCIP_CALL( subscipdataCopySubscip(scip, heurdata->subscipdata, subscip, subvars, nvars) );
1301 SCIPfreeBufferArray(scip, &subvars);
1302 }
1303 else
1304 {
1305 assert(heurdata->subscipdata->subscip == subscip);
1306 assert(heurdata->subscipdata->subvars == subvars);
1307 assert(heurdata->subscipdata->nsubvars == nvars);
1308 }
1309 }
1310
1311 return SCIP_OKAY;
1312}
1313
1314/*
1315 * primal heuristic specific interface methods
1316 */
1317
1318/** creates the lpface primal heuristic and includes it in SCIP */
1320 SCIP* scip /**< SCIP data structure */
1321 )
1322{
1323 SCIP_HEURDATA* heurdata;
1324 SCIP_HEUR* heur;
1325
1326 /* create Lpface primal heuristic data */
1327 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
1328
1329 heurdata->subscipdata = NULL;
1330
1331 /* include primal heuristic */
1334 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecLpface, heurdata) );
1335
1336 assert(heur != NULL);
1337
1338 /* primal heuristic is safe to use in exact solving mode */
1339 SCIPheurMarkExact(heur);
1340
1341 /* set non-NULL pointers to callback methods */
1342 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyLpface) );
1343 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeLpface) );
1344 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitLpface) );
1345 SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolLpface) );
1346 SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolLpface) );
1348
1349 /* add lpface primal heuristic parameters */
1350 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
1351 "number of nodes added to the contingent of the total nodes",
1352 &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1353
1354 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
1355 "maximum number of nodes to regard in the subproblem",
1356 &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1357
1358 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
1359 "minimum number of nodes required to start the subproblem",
1360 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1361
1362 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
1363 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
1364 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
1365
1366 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minfixingrate",
1367 "required percentage of fixed integer variables in sub-MIP to run",
1368 &heurdata->minfixingrate, FALSE, DEFAULT_MINFIXINGRATE, 0.0, 1.0, NULL, NULL) );
1369
1370 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/lplimfac",
1371 "factor by which the limit on the number of LP depends on the node limit",
1372 &heurdata->lplimfac, TRUE, DEFAULT_LPLIMFAC, 1.0, SCIP_REAL_MAX, NULL, NULL) );
1373
1374 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/uselprows",
1375 "should subproblem be created out of the rows in the LP rows?",
1376 &heurdata->uselprows, TRUE, DEFAULT_USELPROWS, NULL, NULL) );
1377
1378 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/dualbasisequations",
1379 "should dually nonbasic rows be turned into equations?",
1380 &heurdata->dualbasisequations, TRUE, DEFAULT_DUALBASISEQUATIONS, NULL, NULL) );
1381
1382 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/keepsubscip",
1383 "should the heuristic continue solving the same sub-SCIP?",
1384 &heurdata->keepsubscip, TRUE, DEFAULT_KEEPSUBSCIP, NULL, NULL) );
1385
1386 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
1387 "if uselprows == FALSE, should all active cuts from cutpool be copied to constraints in subproblem?",
1388 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
1389
1390 SCIP_CALL( SCIPaddCharParam(scip, "heuristics/" HEUR_NAME "/subscipobjective",
1391 "objective function in the sub-SCIP: (z)ero, (r)oot-LP-difference, (i)nference, LP (f)ractionality, (o)riginal",
1392 &heurdata->subscipobjective, TRUE, 'z', "forzi", NULL, NULL) );
1393
1394 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/minpathlen",
1395 "the minimum active search tree path length along which lower bound hasn't changed before heuristic becomes active",
1396 &heurdata->minpathlen, TRUE, DEFAULT_MINPATHLEN, 0, 65531, NULL, NULL) );
1397
1398 return SCIP_OKAY;
1399}
Constraint handler for linear constraints in their most general form, .
#define NULL
Definition: def.h:248
#define SCIP_MAXSTRLEN
Definition: def.h:269
#define SCIP_Longint
Definition: def.h:141
#define SCIP_REAL_MAX
Definition: def.h:158
#define SCIP_INVALID
Definition: def.h:178
#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 MAX(x, y)
Definition: def.h:220
#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 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:2609
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 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:1167
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:2961
int SCIPgetSubscipDepth(SCIP *scip)
Definition: scip_copy.c:2588
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 SCIPcopyParamSettings(SCIP *sourcescip, SCIP *targetscip)
Definition: scip_copy.c:2547
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 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,...)
Definition: scip_message.c:208
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:225
#define SCIPdebugMsg
Definition: scip_message.h:78
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)
Definition: heur_lpface.c:1319
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
Definition: scip_branch.c:304
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 SCIPsetHeurExitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXITSOL((*heurexitsol)))
Definition: scip_heur.c:247
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: scip_heur.c:167
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1368
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition: scip_heur.c:122
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip_heur.c:183
SCIP_RETCODE SCIPsetHeurExit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEUREXIT((*heurexit)))
Definition: scip_heur.c:215
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition: heur.c:1593
SCIP_RETCODE SCIPsetHeurInitsol(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINITSOL((*heurinitsol)))
Definition: scip_heur.c:231
void SCIPheurMarkExact(SCIP_HEUR *heur)
Definition: heur.c:1457
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURINIT((*heurinit)))
Definition: scip_heur.c:199
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1467
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1378
SCIP_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:8503
SCIP_NODE * SCIPnodeGetParent(SCIP_NODE *node)
Definition: tree.c:8782
SCIP_NODESEL * SCIPfindNodesel(SCIP *scip, const char *name)
Definition: scip_nodesel.c:242
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:2981
int SCIPgetNSols(SCIP *scip)
Definition: scip_sol.c:2882
int SCIPsolGetIndex(SCIP_SOL *sol)
Definition: sol.c:4290
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1765
SCIP_Real SCIPretransformObj(SCIP *scip, SCIP_Real obj)
Definition: scip_sol.c:2132
SCIP_RETCODE SCIPtransformProb(SCIP *scip)
Definition: scip_solve.c:232
SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
Definition: scip_solve.c:3548
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip_solve.c:2635
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)
Definition: scip_timing.c:378
SCIP_Real SCIPgetPresolvingTime(SCIP *scip)
Definition: scip_timing.c:442
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:23683
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:23386
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:23900
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:24142
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:23662
SCIP_Real SCIPvarGetRootSol(SCIP_VAR *var)
Definition: var.c:19115
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:23490
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
Definition: var.c:24664
SCIP_Bool SCIPvarIsRelaxationOnly(SCIP_VAR *var)
Definition: var.c:23600
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:24120
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
static SCIP_RETCODE setSubscipLimits(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata, SCIP_Bool *success)
Definition: heur_lpface.c:427
static SCIP_RETCODE createRows(SCIP *scip, SCIP *subscip, SCIP_VAR **subvars, SCIP_Bool dualbasisequations)
Definition: heur_lpface.c:237
#define DEFAULT_NODESQUOT
Definition: heur_lpface.c:81
static SCIP_RETCODE subscipdataCopySubscip(SCIP *scip, SUBSCIPDATA *subscipdata, SCIP *subscip, SCIP_VAR **subvars, int nvars)
Definition: heur_lpface.c:586
static SCIP_RETCODE setSubscipParameters(SCIP *subscip)
Definition: heur_lpface.c:489
static SCIP_DECL_HEUREXEC(heurExecLpface)
Definition: heur_lpface.c:1081
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)
Definition: heur_lpface.c:734
static SCIP_RETCODE subscipdataFreeSubscip(SCIP *scip, SUBSCIPDATA *subscipdata)
Definition: heur_lpface.c:557
#define DEFAULT_NODESOFS
Definition: heur_lpface.c:80
static SCIP_RETCODE changeSubvariableObjective(SCIP *scip, SCIP *subscip, SCIP_VAR *var, SCIP_VAR *subvar, SCIP_HEURDATA *heurdata)
Definition: heur_lpface.c:644
#define DEFAULT_COPYCUTS
Definition: heur_lpface.c:85
#define DEFAULT_MAXNODES
Definition: heur_lpface.c:77
#define HEUR_TIMING
Definition: heur_lpface.c:74
#define DEFAULT_MINNODES
Definition: heur_lpface.c:78
#define HEUR_FREQOFS
Definition: heur_lpface.c:72
#define HEUR_DESC
Definition: heur_lpface.c:68
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)
Definition: heur_lpface.c:825
static SCIP_Longint calcNodeLimit(SCIP *scip, SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur_lpface.c:395
#define DEFAULT_KEEPSUBSCIP
Definition: heur_lpface.c:88
#define heurExitLpface
Definition: heur_lpface.c:1076
#define DEFAULT_LPLIMFAC
Definition: heur_lpface.c:82
static SCIP_DECL_HEURINITSOL(heurInitsolLpface)
Definition: heur_lpface.c:1005
#define DEFAULT_DUALBASISEQUATIONS
Definition: heur_lpface.c:87
#define DEFAULT_MINFIXINGRATE
Definition: heur_lpface.c:79
#define HEUR_DISPCHAR
Definition: heur_lpface.c:69
#define HEUR_MAXDEPTH
Definition: heur_lpface.c:73
#define HEUR_PRIORITY
Definition: heur_lpface.c:70
#define HEUR_NAME
Definition: heur_lpface.c:67
static SCIP_RETCODE determineVariableFixings(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_VAR **fixvars, SCIP_Real *fixvals, int *nfixvars, SCIP_Bool *success)
Definition: heur_lpface.c:147
#define DEFAULT_USELPROWS
Definition: heur_lpface.c:83
#define DEFAULT_MINPATHLEN
Definition: heur_lpface.c:89
static SCIP_DECL_HEURCOPY(heurCopyLpface)
Definition: heur_lpface.c:945
#define EVENTHDLR_DESC
Definition: heur_lpface.c:93
static void updateFailureStatistic(SCIP *scip, SCIP_HEURDATA *heurdata)
Definition: heur_lpface.c:381
#define HEUR_FREQ
Definition: heur_lpface.c:71
#define HEUR_USESSUBSCIP
Definition: heur_lpface.c:75
static SCIP_DECL_HEURFREE(heurFreeLpface)
Definition: heur_lpface.c:959
static SCIP_DECL_EVENTEXEC(eventExecLpface)
Definition: heur_lpface.c:709
#define EVENTHDLR_NAME
Definition: heur_lpface.c:92
static SCIP_DECL_HEURINIT(heurInitLpface)
Definition: heur_lpface.c:979
static void subscipdataReset(SUBSCIPDATA *subscipdata)
Definition: heur_lpface.c:545
static SCIP_RETCODE setupSubproblem(SCIP *scip, SCIP *subscip, SCIP_VAR **subvars, SCIP_HEURDATA *heurdata)
Definition: heur_lpface.c:332
static SCIP_DECL_HEUREXITSOL(heurExitsolLpface)
Definition: heur_lpface.c:1030
LNS heuristic that tries to compute integral solution on optimal LP face.
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
Definition: heur_lpface.c:102
SCIP_VAR ** subvars
Definition: heur_lpface.c:103
SCIP_Real objbound
Definition: heur_lpface.c:105
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:179
#define SCIP_EVENTTYPE_LPSOLVED
Definition: type_event.h:102
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:77
#define SCIP_DECL_HEUREXIT(x)
Definition: type_heur.h:121
@ SCIP_BRANCHDIR_DOWNWARDS
Definition: type_history.h:43
@ SCIP_BRANCHDIR_UPWARDS
Definition: type_history.h:44
@ SCIP_LPSOLSTAT_OPTIMAL
Definition: type_lp.h:44
@ SCIP_VERBLEVEL_HIGH
Definition: type_message.h:61
@ SCIP_PARAMSETTING_FAST
Definition: type_paramset.h:62
@ 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
Definition: type_retcode.h:54
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ 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
@ SCIP_VARSTATUS_COLUMN
Definition: type_var.h:53