SCIP Doxygen Documentation
Loading...
Searching...
No Matches
heur_clique.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_clique.c
26 * @ingroup DEFPLUGINS_HEUR
27 * @brief LNS heuristic using a clique partition to restrict the search neighborhood
28 * @brief clique primal heuristic
29 * @author Stefan Heinz
30 * @author Michael Winkler
31 * @author Gerald Gamrath
32 *
33 * @todo allow smaller fixing rate for probing LP?
34 * @todo allow smaller fixing rate after presolve if total number of variables is small (<= 1000)?
35 *
36 * More details about the heuristic can be found in@n
37 * Structure-Based Primal Heuristics for Mixed Integer Programming@n
38 * Gerald Gamrath, Timo Berthold, Stefan Heinz, and Michael Winkler@n
39 * Optimization in the Real World, Volume 13 of the series Mathematics for Industry, pp 37-53@n
40 * Preliminary version available as <a href="https://opus4.kobv.de/opus4-zib/frontdoor/index/index/docId/5551">ZIB-Report 15-26</a>.
41 */
42
43/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44
46#include "scip/cons_logicor.h"
47#include "scip/heur_clique.h"
48#include "scip/heur_locks.h"
49#include "scip/pub_heur.h"
50#include "scip/pub_implics.h"
51#include "scip/pub_message.h"
52#include "scip/pub_misc.h"
53#include "scip/pub_misc_sort.h"
54#include "scip/pub_var.h"
55#include "scip/scip_branch.h"
57#include "scip/scip_cons.h"
58#include "scip/scip_copy.h"
59#include "scip/scip_exact.h"
60#include "scip/scip_general.h"
61#include "scip/scip_heur.h"
62#include "scip/scip_lp.h"
63#include "scip/scip_mem.h"
64#include "scip/scip_message.h"
65#include "scip/scip_numerics.h"
66#include "scip/scip_param.h"
67#include "scip/scip_prob.h"
68#include "scip/scip_probing.h"
69#include "scip/scip_sol.h"
70#include "scip/scip_solve.h"
72#include "scip/scip_timing.h"
73#include "scip/scip_tree.h"
74#include "scip/scip_var.h"
75#include <string.h>
76
77
78#define HEUR_NAME "clique"
79#define HEUR_DESC "LNS heuristic using a clique partition to restrict the search neighborhood"
80#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_PROP
81#define HEUR_PRIORITY 5000
82#define HEUR_FREQ 0
83#define HEUR_FREQOFS 0
84#define HEUR_MAXDEPTH -1
85#define HEUR_TIMING SCIP_HEURTIMING_BEFORENODE
86#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
87
88#define DEFAULT_MAXNODES 5000LL /**< maximum number of nodes to regard in the subproblem */
89#define DEFAULT_MININTFIXINGRATE 0.65 /**< minimum percentage of integer variables that have to be fixed */
90#define DEFAULT_MINMIPFIXINGRATE 0.65 /**< minimum percentage of variables that have to be fixed within sub-SCIP
91 * (integer and continuous) */
92#define DEFAULT_MINIMPROVE 0.01 /**< factor by which clique heuristic should at least improve the
93 * incumbent */
94#define DEFAULT_MINNODES 500LL /**< minimum number of nodes to regard in the subproblem */
95#define DEFAULT_NODESOFS 500LL /**< number of nodes added to the contingent of the total nodes */
96#define DEFAULT_NODESQUOT 0.1 /**< subproblem nodes in relation to nodes of the original problem */
97#define DEFAULT_MAXPROPROUNDS 2 /**< maximum number of propagation rounds during probing */
98#define DEFAULT_MAXBACKTRACKS 10 /**< maximum number of backtracks during the fixing process */
99#define DEFAULT_COPYCUTS TRUE /**< should all active cuts from the cutpool of the
100 * original scip be copied to constraints of the subscip */
101#define DEFAULT_USELOCKFIXINGS FALSE /**< should more variables be fixed based on variable locks if
102 * the fixing rate was not reached? */
103
104
105/*
106 * Data structures
107 */
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 clique heuristic in earlier calls */
116 SCIP_Real minintfixingrate; /**< minimum percentage of integer variables that have to be fixed */
117 SCIP_Real minmipfixingrate; /**< minimum percentage of variables that have to be fixed within sub-SCIP
118 * (integer and continuous) */
119 SCIP_Real minimprove; /**< factor by which clique heuristic should at least improve the incumbent */
120 SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
121 int maxproprounds; /**< maximum number of propagation rounds during probing */
122 int maxbacktracks; /**< maximum number of backtracks during the fixing process */
123 SCIP_Bool copycuts; /**< should all active cuts from cutpool be copied to constraints in
124 * subproblem?
125 */
126 SCIP_Bool uselockfixings; /**< should more variables be fixed based on variable locks if
127 * the fixing rate was not reached?
128 */
129};
130
131/*
132 * Local methods
133 */
134
135/** comparison method for sorting cliques by their size */
136static
137SCIP_DECL_SORTINDCOMP(compCliquesSize)
138{
139 int* cliquesizes = (int*)dataptr;
140
141 return cliquesizes[ind2] - cliquesizes[ind1];
142}
143
144static
146 SCIP_CLIQUE* clique
147 )
148{
149 SCIP_VAR** cliquevars;
150 SCIP_VAR* var;
151 int ncliquevars;
152 int nunfixed = 0;
153 int v;
154
155 ncliquevars = SCIPcliqueGetNVars(clique);
156 cliquevars = SCIPcliqueGetVars(clique);
157
158 for( v = 0; v < ncliquevars; ++v )
159 {
160 var = cliquevars[v];
161
162 /* is variable unfixed? */
164 ++nunfixed;
165 }
166
167 return nunfixed;
168}
169
170/** apply clique fixing using probing */
171static
173 SCIP* scip, /**< original SCIP data structure */
174 SCIP_HEURDATA* heurdata, /**< structure containing heurdata */
175 SCIP_Bool enabledconflicts, /**< was conflict analysis enabled before the heuristic call? */
176 SCIP_VAR** onefixvars, /**< array to store all variables which are fixed to one in the cliques */
177 SCIP_Shortbool* onefixvals, /**< array to store the values of all variables fixed to one in the cliques */
178 int* nonefixvars, /**< pointer to store the number of variables fixed to one */
179 SCIP_Bool* cutoff /**< pointer to store whether the propagation stopped with infeasibility */
180 )
181{
182 SCIP_CLIQUE** cliques;
183 SCIP_CLIQUE* clique;
184 SCIP_VAR** cliquevars;
185 SCIP_VAR* var;
186 SCIP_Bool* cliquevals;
187 SCIP_Bool* propagated;
188 int* cliquesizes;
189 int* permutation;
190 SCIP_Real bestobj;
192 SCIP_Bool alreadyone;
193 SCIP_Bool newnode;
194 int probingdepthofonefix;
195 int ncliquevars;
196 int ncliques;
197 int bestpos;
198 int firstclique;
199 int bestclique;
200 int cliquesize;
201 int bestcliquesize;
202 int nbacktracks = 0;
203 int v = 0;
204 int c;
205 int i;
206
207 assert(scip != NULL);
208 assert(heurdata != NULL);
209 assert(onefixvars != NULL);
210 assert(nonefixvars != NULL);
211 assert(cutoff != NULL);
212
213 cliques = SCIPgetCliques(scip);
214 ncliques = SCIPgetNCliques(scip);
215
216 /* allocate memory */
217 SCIP_CALL( SCIPallocBufferArray(scip, &cliquesizes, ncliques) );
218 SCIP_CALL( SCIPallocBufferArray(scip, &permutation, ncliques) );
219 SCIP_CALL( SCIPallocClearBufferArray(scip, &propagated, ncliques) );
220
221 for( c = ncliques - 1; c >= 0; --c )
222 {
223 cliquesizes[c] = SCIPcliqueGetNVars(cliques[c]);
224 }
225
226 SCIPsort(permutation, compCliquesSize, (void*)cliquesizes, ncliques);
227
228#ifndef NDEBUG
229 for( c = ncliques - 1; c >= 1; --c )
230 {
231 assert(cliquesizes[permutation[c]] <= cliquesizes[permutation[c-1]]);
232 }
233#endif
234
235 *cutoff = FALSE;
236 probingdepthofonefix = 0;
237 firstclique = 0;
238
240
241 /* @todo maybe try to fix more than one variable to one in each probing node, to gain faster results */
242 for( c = 0; c < ncliques; ++c )
243 {
244 bestpos = -1;
245 bestobj = SCIPinfinity(scip);
246 alreadyone = FALSE;
247 newnode = FALSE;
248
249 bestclique = firstclique;
250
251 if( bestclique >= ncliques )
252 break;
253
254 bestcliquesize = getCliqueUnfixedVars(cliques[permutation[bestclique]]);
255 assert(!propagated[permutation[bestclique]]);
256
257 for( i = firstclique + 1; i < ncliques; ++i)
258 {
259 if( cliquesizes[permutation[i]] < bestcliquesize )
260 break;
261
262 if( propagated[permutation[i]] )
263 continue;
264
265 cliquesize = getCliqueUnfixedVars(cliques[permutation[i]]);
266
267 if( cliquesize > bestcliquesize )
268 {
269 bestclique = i;
270 bestcliquesize = cliquesize;
271 }
272 else if( cliquesize == 0 )
273 {
274 propagated[permutation[i]] = TRUE;
275 }
276 }
277 clique = cliques[permutation[bestclique]];
278 propagated[permutation[bestclique]] = TRUE;
279
280 while( firstclique < ncliques && propagated[permutation[firstclique]] )
281 ++firstclique;
282
283 ncliquevars = SCIPcliqueGetNVars(clique);
284 cliquevars = SCIPcliqueGetVars(clique);
285 cliquevals = SCIPcliqueGetValues(clique);
286
287 for( v = 0; v < ncliquevars; ++v )
288 {
289 var = cliquevars[v];
290
291 /* variable is already fixed */
293 {
294 SCIPdebugMsg(scip, "<%s> is already fixed to %g\n", SCIPvarGetName(var), SCIPvarGetUbLocal(var));
295
296 /* clique variable is fixed to 1 */
297 if( cliquevals[v] == (SCIPvarGetLbLocal(var) > 0.5) )
298 {
299 assert(!alreadyone);
300 alreadyone = TRUE;
301 break;
302 }
303 continue;
304 }
305
306 obj = cliquevals[v] ? SCIPvarGetObj(var) : -SCIPvarGetObj(var);
307
308 /* @todo use a tiebreaker (locks?) */
309 if( obj < bestobj )
310 {
311 /* variable is not the best one in the clique anymore, fix it to 0 */
312 if( bestpos >= 0 )
313 {
314 assert(bestpos < ncliquevars);
315 if( cliquevals[bestpos] )
316 {
317 SCIP_CALL( SCIPfixVarProbing(scip, cliquevars[bestpos], 0.0) );
318 }
319 else
320 {
321 SCIP_CALL( SCIPfixVarProbing(scip, cliquevars[bestpos], 1.0) );
322 }
323 SCIPdebugMsg(scip, "fixed <%s> to %g\n", SCIPvarGetName(cliquevars[bestpos]), SCIPvarGetUbLocal(cliquevars[bestpos]));
324 newnode = TRUE;
325 }
326
327 bestobj = obj;
328 bestpos = v;
329 }
330 /* variable is not the best one in the clique, fix it to 0 */
331 else
332 {
333 assert(bestpos >= 0);
334
335 if( cliquevals[v] )
336 {
338 }
339 else
340 {
342 }
343 SCIPdebugMsg(scip, "fixed <%s> to %g\n", SCIPvarGetName(var), SCIPvarGetUbLocal(var));
344 newnode = TRUE;
345 }
346 }
347 /* we found a variable in the clique which is already fixed to 1 */
348 if( alreadyone )
349 {
350 /* fix (so far) best candidate to 0 */
351 if( bestpos >= 0 )
352 {
353 assert(bestpos < ncliquevars);
354 if( cliquevals[bestpos] )
355 {
356 SCIP_CALL( SCIPfixVarProbing(scip, cliquevars[bestpos], 0.0) );
357 }
358 else
359 {
360 SCIP_CALL( SCIPfixVarProbing(scip, cliquevars[bestpos], 1.0) );
361 }
362 SCIPdebugMsg(scip, "fixed <%s> to %g\n", SCIPvarGetName(cliquevars[bestpos]), SCIPvarGetUbLocal(cliquevars[bestpos]));
363 newnode = TRUE;
364 }
365
366 /* fix all variables not yet processed to 0 */
367 for( ; v < ncliquevars; ++v )
368 {
369 var = cliquevars[v];
370
372 continue;
373
374 if( cliquevals[v] )
375 {
377 }
378 else
379 {
381 }
382 SCIPdebugMsg(scip, "fixed <%s> to %g\n", SCIPvarGetName(var), SCIPvarGetUbLocal(var));
383 newnode = TRUE;
384 }
385 }
386 /* fix the best variable to 1 */
387 else if( bestpos >= 0 )
388 {
389 assert(bestpos < ncliquevars);
390 onefixvars[*nonefixvars] = cliquevars[bestpos];
391 probingdepthofonefix = SCIPgetProbingDepth(scip);
392
393 /* @todo should we even fix the best candidate to 1? */
394 if( cliquevals[bestpos] )
395 {
396 SCIP_CALL( SCIPfixVarProbing(scip, cliquevars[bestpos], 1.0) );
397 onefixvals[*nonefixvars] = 1;
398 }
399 else
400 {
401 SCIP_CALL( SCIPfixVarProbing(scip, cliquevars[bestpos], 0.0) );
402 onefixvals[*nonefixvars] = 0;
403 }
404 SCIPdebugMsg(scip, "fixed <%s> to %g*\n", SCIPvarGetName(cliquevars[bestpos]), SCIPvarGetUbLocal(cliquevars[bestpos]));
405 ++(*nonefixvars);
406 newnode = TRUE;
407 }
408
409 if( newnode )
410 {
411 /* propagate fixings */
413
414 SCIPdebugMsg(scip, "propagate fixings of clique %d: cutoff=%u\n", c, *cutoff);
415
416 if( SCIPisStopped(scip) )
417 break;
418
419 /* stop if we reached the depth limit */
421 break;
422
423 /* probing detected infeasibility: backtrack */
424 if( *cutoff )
425 {
426 if( *nonefixvars > 0 )
427 {
428 if( probingdepthofonefix > 0 )
429 {
430 SCIP_CALL( SCIPbacktrackProbing(scip, probingdepthofonefix - 1) );
431 probingdepthofonefix = 0;
432 ++nbacktracks;
433
434 /* because of the limited number of propagation rounds, it may happen that conflict analysis finds a
435 * valid global fixing for the last fixed variable that conflicts with applying the reverse fixing
436 * after backtracking; in that case, we ran into a deadend and stop
437 */
438 if( SCIPvarGetLbLocal(onefixvars[*nonefixvars - 1]) < 1.5 - onefixvals[*nonefixvars - 1]
439 && SCIPvarGetUbLocal(onefixvars[*nonefixvars - 1]) > 0.5 - onefixvals[*nonefixvars - 1] )
440 {
441 /* fix the last variable, which was fixed to 1 and led to the cutoff, to 0 */
442 SCIP_CALL( SCIPfixVarProbing(scip, onefixvars[*nonefixvars - 1], 1.0 - onefixvals[*nonefixvars - 1]) );
443 --(*nonefixvars);
444
445 /* propagate fixings */
447
448 SCIPdebugMsg(scip, "backtrack %d was %sfeasible\n", nbacktracks, (*cutoff ? "in" : ""));
449 }
450#ifndef NDEBUG
451 else
452 assert(*cutoff == TRUE);
453#endif
454 }
455 if( *cutoff )
456 {
457 SCIPdebugMsg(scip, "probing was infeasible after %d backtracks\n", nbacktracks);
458#ifndef NOCONFLICT
459 if( enabledconflicts )
460 {
461 SCIP_CONS* conflictcons;
462 char consname[SCIP_MAXSTRLEN];
463
464 /* create own conflict */
465 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "conf%" SCIP_LONGINT_FORMAT "", SCIPgetNNodes(scip));
466
467 /* get variables for the conflict */
468 for( i = 0; i < *nonefixvars; ++i )
469 {
470 /* if the variable was fixed to 1 by the heuristic, get its negated variable */
471 if( onefixvals[i] )
472 {
473 SCIP_CALL( SCIPgetNegatedVar(scip, onefixvars[i], &onefixvars[i]) );
474 }
475 }
476
477 /* create conflict constraint */
478 SCIP_CALL( SCIPcreateConsLogicor(scip, &conflictcons, consname, *nonefixvars, onefixvars,
480 SCIPdebugPrintCons(scip, conflictcons, NULL);
482 }
483#endif
484 break;
485 }
486 else if( nbacktracks > heurdata->maxbacktracks )
487 {
488 SCIPdebugMsg(scip, "interrupt probing after %d backtracks\n", nbacktracks);
489 break;
490 }
491 }
492 /* we had a cutoff without a single one-fixing, so the current problem seems to be infeasible already */
493 else
494 break;
495 }
496
498 }
499 }
500 assert((*nonefixvars > 0) || probingdepthofonefix == 0 );
501
502 SCIPfreeBufferArray(scip, &propagated);
503 SCIPfreeBufferArray(scip, &permutation);
504 SCIPfreeBufferArray(scip, &cliquesizes);
505
506 SCIPdebugMsg(scip, "fixed %d of %d variables in probing\n", v, SCIPgetNVars(scip) - SCIPgetNContVars(scip));
507 SCIPdebugMsg(scip, "applied %d of %d cliques in probing\n", c, ncliques);
508 SCIPdebugMsg(scip, "probing was %sfeasible\n", (*cutoff) ? "in" : "");
509
510 return SCIP_OKAY;
511}
512
513/*
514 * Callback methods of primal heuristic
515 */
516
517/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
518static
519SCIP_DECL_HEURCOPY(heurCopyClique)
520{ /*lint --e{715}*/
521 assert(scip != NULL);
522 assert(heur != NULL);
523 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
524
525 /* call inclusion method of primal heuristic */
527
528 return SCIP_OKAY;
529}
530
531/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
532static
533SCIP_DECL_HEURFREE(heurFreeClique)
534{ /*lint --e{715}*/
536
537 assert(heur != NULL);
538 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
539 assert(scip != NULL);
540
541 /* free heuristic data */
543 assert(heurdata != NULL);
544
546 SCIPheurSetData(heur, NULL);
547
548 return SCIP_OKAY;
549}
550
551
552/** initialization method of primal heuristic (called after problem was transformed) */
553static
554SCIP_DECL_HEURINIT(heurInitClique)
555{ /*lint --e{715}*/
557
558 assert(heur != NULL);
559 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
560 assert(scip != NULL);
561
562 /* reset heuristic data */
564 assert(heurdata != NULL);
565
566 heurdata->usednodes = 0;
567
568 return SCIP_OKAY;
569}
570
571/** execution method of primal heuristic */
572static
573SCIP_DECL_HEUREXEC(heurExecClique)
574{ /*lint --e{715}*/
576 SCIP_VAR** vars;
577 SCIP_Real lowerbound;
578 int nvars;
579 int nbinvars;
580 int oldnpscands;
581 int npscands;
582 int i;
585
586 SCIP_VAR** onefixvars;
587 SCIP_Shortbool* onefixvals;
588 int nonefixvars;
589 SCIP_Bool enabledconflicts;
590 SCIP_LPSOLSTAT lpstatus;
591 SCIP_CONS* conflictcons;
592 SCIP_Bool solvelp;
593 char consname[SCIP_MAXSTRLEN];
594
595 SCIP_Longint nstallnodes;
596
597 assert(heur != NULL);
598 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
599 assert(scip != NULL);
600 assert(result != NULL);
601
603
604 /* get heuristic's data */
606 assert(heurdata != NULL);
607
608 nbinvars = SCIPgetNBinVars(scip);
609
610 if( nbinvars < 2 )
611 return SCIP_OKAY;
612
613 /* check for necessary information to apply this heuristic */
614 if( SCIPgetNCliques(scip) == 0 )
615 return SCIP_OKAY;
616
617 lowerbound = SCIPgetLowerbound(scip);
618
619 /* calculate the maximal number of branching nodes until heuristic is aborted */
620 nstallnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
621
622 /* reward clique heuristic if it succeeded often */
623 nstallnodes = (SCIP_Longint)(nstallnodes * 3.0 * (SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur) + 1.0));
624 nstallnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-MIP as 100 nodes */
625 nstallnodes += heurdata->nodesofs;
626
627 /* determine the node limit for the current process */
628 nstallnodes -= heurdata->usednodes;
629 nstallnodes = MIN(nstallnodes, heurdata->maxnodes);
630
631 /* check whether we have enough nodes left to call subproblem solving */
632 if( nstallnodes < heurdata->minnodes )
633 {
634 SCIPdebugMsg(scip, "skipping " HEUR_NAME ": nstallnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->minnodes);
635 return SCIP_OKAY;
636 }
637
638 oldnpscands = SCIPgetNPseudoBranchCands(scip);
639 onefixvars = NULL;
640 onefixvals = NULL;
641
642 /* disable conflict analysis, because we can it better than SCIP itself, cause we have more information */
643 SCIP_CALL( SCIPgetBoolParam(scip, "conflict/enable", &enabledconflicts) );
644
645 if( !SCIPisParamFixed(scip, "conflict/enable") )
646 {
647 SCIP_CALL( SCIPsetBoolParam(scip, "conflict/enable", FALSE) );
648 }
649
650 solvelp = SCIPhasCurrentNodeLP(scip);
651
652 if( !SCIPisLPConstructed(scip) && solvelp )
653 {
655
656 /* manually cut off the node if the LP construction detected infeasibility (heuristics cannot return such a
657 * result); the cutoff result is safe to use in exact solving mode, but we don't have enough information to
658 * give a certificate for the cutoff
659 */
660 if( cutoff && !SCIPisCertified(scip) )
661 {
663 goto TERMINATE;
664 }
665
667 }
668
669 /* get number of possible binary variables */
670 nbinvars = SCIPgetNVars(scip) - SCIPgetNContVars(scip);
671 assert(nbinvars >= 2);
672
674
675 /* start probing */
677
678#ifdef COLLECTSTATISTICS
680#endif
681
682 /* allocate memory for all variables which will be fixed to one during probing */
683 SCIP_CALL( SCIPallocBufferArray(scip, &onefixvars, nbinvars) );
684 SCIP_CALL( SCIPallocBufferArray(scip, &onefixvals, nbinvars) );
685 nonefixvars = 0;
686
687 /* apply fixings due to clique information */
688 SCIP_CALL( applyCliqueFixings(scip, heurdata, enabledconflicts, onefixvars, onefixvals, &nonefixvars, &cutoff) );
689
690 if( cutoff || SCIPisStopped(scip) )
691 goto TERMINATE;
692
693 /* check that we had enough fixings */
695
696 SCIPdebugMsg(scip, "npscands=%d, oldnpscands=%d, heurdata->minintfixingrate=%g\n", npscands, oldnpscands, heurdata->minintfixingrate);
697
698 if( npscands > oldnpscands * (1.0 - heurdata->minintfixingrate) )
699 {
700 if( heurdata->uselockfixings && npscands <= 2.0 * oldnpscands * (1.0 - heurdata->minintfixingrate) )
701 {
702 SCIP_Bool allrowsfulfilled = FALSE;
703
704 SCIP_CALL( SCIPapplyLockFixings(scip, NULL, &cutoff, &allrowsfulfilled) );
705
706 if( cutoff || SCIPisStopped(scip) )
707 {
708 SCIPdebugMsg(scip, "cutoff or timeout in locks fixing\n");
709 goto TERMINATE;
710 }
711
713
714 SCIPdebugMsg(scip, "after lockfixings: npscands=%d, oldnpscands=%d, allrowsfulfilled=%u, heurdata->minintfixingrate=%g\n",
715 npscands, oldnpscands, allrowsfulfilled, heurdata->minintfixingrate);
716
717 if( !allrowsfulfilled && npscands > oldnpscands * (1 - heurdata->minintfixingrate) )
718 {
719 SCIPdebugMsg(scip, "--> too few fixings\n");
720
721 goto TERMINATE;
722 }
723 }
724 else
725 {
726 SCIPdebugMsg(scip, "--> too few fixings\n");
727
728 goto TERMINATE;
729 }
730 }
731
732 /*************************** Probing LP Solving ***************************/
733
734 lpstatus = SCIP_LPSOLSTAT_ERROR;
735 lperror = FALSE;
736
737 /* solve lp only if the problem is still feasible */
738 if( solvelp )
739 {
740 char strbuf[SCIP_MAXSTRLEN];
741 int ncols;
742
743 /* print message if relatively large LP is solved from scratch, since this could lead to a longer period during
744 * which the user sees no output; more detailed probing stats only in debug mode */
745 ncols = SCIPgetNLPCols(scip);
746 if( !SCIPisLPSolBasic(scip) && ncols > 1000 )
747 {
748 int nunfixedcols = SCIPgetNUnfixedLPCols(scip);
749
750 if( nunfixedcols > 0.5 * ncols )
751 {
753 "Heuristic " HEUR_NAME " solving LP from scratch with %.1f %% unfixed columns (%d of %d) ...\n",
754 100.0 * (nunfixedcols / (SCIP_Real)ncols), nunfixedcols, ncols);
755 }
756 }
757 SCIPdebugMsg(scip, "Heuristic " HEUR_NAME " probing LP: %s\n",
759
760 /* solve LP; errors in the LP solver should not kill the overall solving process, if the LP is just needed for a
761 * heuristic. hence in optimized mode, the return code is caught and a warning is printed, only in debug mode,
762 * SCIP will stop.
763 */
764 SCIPdebugMsg(scip, "starting solving clique-lp at time %g\n", SCIPgetSolvingTime(scip));
765#ifdef NDEBUG
766 {
767 SCIP_Bool retstat;
768 retstat = SCIPsolveProbingLP(scip, -1, &lperror, NULL);
769 if( retstat != SCIP_OKAY )
770 {
771 SCIPwarningMessage(scip, "Error while solving LP in clique heuristic; LP solve terminated with code <%d>\n",
772 retstat);
773 }
774 }
775#else
777#endif
778 SCIPdebugMsg(scip, "ending solving clique-lp at time %g\n", SCIPgetSolvingTime(scip));
779
780 lpstatus = SCIPgetLPSolstat(scip);
781
782 SCIPdebugMsg(scip, " -> new LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
783 SCIPdebugMsg(scip, " -> error=%u, status=%d\n", lperror, lpstatus);
784 }
785
786 /* check if this is a feasible solution */
787 if( lpstatus == SCIP_LPSOLSTAT_OPTIMAL && !lperror )
788 {
789 SCIP_SOL* sol;
790 SCIP_Bool stored;
791 SCIP_Bool success;
792
793 assert(!cutoff);
794
795 lowerbound = SCIPgetLPObjval(scip);
796
797 /* create a solution from the current LP solution */
798 SCIP_CALL( SCIPcreateSol(scip, &sol, heur) );
800
801 SCIP_CALL( SCIProundSol(scip, sol, &success) );
802
803 if( success )
804 {
805 SCIPdebugMsg(scip, "clique heuristic found roundable primal solution: obj=%g\n",
807
808 /* check solution for feasibility, and add it to solution store if possible.
809 * Neither integrality nor feasibility of LP rows have to be checked, because they
810 * are guaranteed by the heuristic at this stage.
811 */
812#ifdef SCIP_DEBUG
813 SCIP_CALL( SCIPtrySol(scip, sol, TRUE, TRUE, TRUE, TRUE, TRUE, &stored) );
814#else
816#endif
817
818 if( stored )
819 {
820 SCIPdebugMsg(scip, "found feasible solution:\n");
823 }
824
826
827 /* we found a solution, so we are done */
828 goto TERMINATE;
829 }
830
832 }
833 /*************************** END Probing LP Solving ***************************/
834
835 /*************************** Create Conflict ***************************/
836 if( enabledconflicts && SCIPallColsInLP(scip) &&
837 (lpstatus == SCIP_LPSOLSTAT_INFEASIBLE || lpstatus == SCIP_LPSOLSTAT_OBJLIMIT) )
838 {
839#ifndef NOCONFLICT
840 /* create own conflict */
841 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "conf%" SCIP_LONGINT_FORMAT "", SCIPgetNNodes(scip));
842
843 /* get variables for the conflict */
844 for( i = 0; i < nonefixvars; ++i )
845 {
846 /* if the variable was fixed to 1 by the heuristic, get its negated variable */
847 if( onefixvals[i] )
848 {
849 SCIP_CALL( SCIPgetNegatedVar(scip, onefixvars[i], &onefixvars[i]) );
850 }
851 }
852
853 /* create conflict constraint */
854 SCIP_CALL( SCIPcreateConsLogicor(scip, &conflictcons, consname, nonefixvars, onefixvars,
856 SCIPdebugPrintCons(scip, conflictcons, NULL);
858#endif
859 goto TERMINATE;
860 }
861 /*************************** End Conflict ***************************/
862
863 /*************************** Start Subscip Solving ***************************/
864 /* no solution has been found yet and the subproblem is still feasible --> fix all other variables by subscip if
865 * necessary
866 */
867 if( !lperror )
868 {
869 SCIP* subscip;
870 SCIP_VAR** subvars;
871 SCIP_HASHMAP* varmap;
873
874 /* check whether there is enough time and memory left */
876
877 if( !valid )
878 goto TERMINATE;
879
880 /* get all variables */
882
883 /* create subproblem */
884 SCIP_CALL( SCIPcreate(&subscip) );
885
886 /* allocate temporary memory for subscip variables */
888
889 /* create the variable mapping hash map */
890 SCIP_CALL( SCIPhashmapCreate(&varmap, SCIPblkmem(subscip), nvars) );
891
892 SCIP_CALL( SCIPcopyConsCompression(scip, subscip, varmap, NULL, "_clique", NULL, NULL, 0, FALSE, FALSE, FALSE,
893 TRUE, &valid) );
894
895 if( heurdata->copycuts )
896 {
897 /* copies all active cuts from cutpool of sourcescip to linear constraints in targetscip */
898 SCIP_CALL( SCIPcopyCuts(scip, subscip, varmap, NULL, FALSE, NULL) );
899 }
900
901 for( i = 0; i < nvars; i++ )
902 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmap, vars[i]);
903
904 /* free hash map */
905 SCIPhashmapFree(&varmap);
906
907 /* do not abort subproblem on CTRL-C */
908 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
909
910#ifdef SCIP_DEBUG
911 /* for debugging, enable full output */
912 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
913 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 100000000) );
914#else
915 /* disable statistic timing inside sub SCIP and output to console */
916 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
917 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
918#endif
919
920 /* set limits for the subproblem */
921 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
922 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/stallnodes", nstallnodes) );
923 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", heurdata->maxnodes) );
924
925 /* speed up sub-SCIP by not checking dual LP feasibility */
926 SCIP_CALL( SCIPsetBoolParam(subscip, "lp/checkdualfeas", FALSE) );
927
928 /* forbid call of heuristics and separators solving sub-CIPs */
929 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
930
931 /* disable cutting plane separation */
933
934 /* disable expensive presolving */
936
937 /* use inference branching */
938 if( SCIPfindBranchrule(subscip, "inference") != NULL && !SCIPisParamFixed(subscip, "branching/inference/priority") )
939 {
940 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
941 }
942
943 /* if there is already a solution, add an objective cutoff */
944 if( SCIPgetNSols(scip) > 0 )
945 {
946 SCIP_Real upperbound;
947 SCIP_Real minimprove;
948 SCIP_Real cutoffbound;
949
950 minimprove = heurdata->minimprove;
952
953 upperbound = SCIPgetUpperbound(scip) - SCIPsumepsilon(scip);
954
955 if( !SCIPisInfinity(scip, -1.0 * lowerbound) )
956 {
957 cutoffbound = (1-minimprove) * SCIPgetUpperbound(scip) + minimprove * lowerbound;
958 }
959 else
960 {
961 if( SCIPgetUpperbound ( scip ) >= 0 )
962 cutoffbound = (1 - minimprove) * SCIPgetUpperbound(scip);
963 else
964 cutoffbound = (1 + minimprove) * SCIPgetUpperbound(scip);
965 }
966 cutoffbound = MIN(upperbound, cutoffbound);
967 SCIP_CALL( SCIPsetObjlimit(subscip, cutoffbound) );
968 SCIPdebugMsg(scip, "setting objlimit for subscip to %g\n", cutoffbound);
969 }
970
971 SCIPdebugMsg(scip, "starting solving clique-submip at time %g\n", SCIPgetSolvingTime(scip));
972
973 /* solve the subproblem */
974 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
975 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
976 */
977 SCIP_CALL_ABORT( SCIPpresolve(subscip) );
978
979 SCIPdebugMsg(scip, "clique heuristic presolved subproblem at time %g : %d vars, %d cons; fixing value = %g\n", SCIPgetSolvingTime(scip), SCIPgetNVars(subscip), SCIPgetNConss(subscip), ((nvars - SCIPgetNVars(subscip)) / (SCIP_Real)nvars));
980
981 /* after presolving, we should have at least reached a certain fixing rate over ALL variables (including continuous)
982 * to ensure that not only the MIP but also the LP relaxation is easy enough
983 */
984 if( ((nvars - SCIPgetNVars(subscip)) / (SCIP_Real)nvars) >= heurdata->minmipfixingrate )
985 {
986 SCIP_Bool success;
987
988 SCIPdebugMsg(scip, "solving subproblem: nstallnodes=%" SCIP_LONGINT_FORMAT ", maxnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->maxnodes);
989
990 SCIP_CALL_ABORT( SCIPsolve(subscip) );
992
993 SCIPdebugMsg(scip, "ending solving clique-submip at time %g, status = %d\n", SCIPgetSolvingTime(scip), SCIPgetStatus(subscip));
994
995 /* check, whether a solution was found; due to numerics, it might happen that not all solutions are feasible ->
996 * try all solutions until one was accepted
997 */
998 SCIP_CALL( SCIPtranslateSubSols(scip, subscip, heur, subvars, &success, NULL) );
999 if( success )
1001
1002#ifndef NOCONFLICT
1003 /* if subscip was infeasible, add a conflict */
1004 if( SCIPgetStatus(subscip) == SCIP_STATUS_INFEASIBLE )
1005 {
1006 /* create own conflict */
1007 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "conf%" SCIP_LONGINT_FORMAT "", SCIPgetNNodes(scip));
1008
1009 /* get variables for the conflict */
1010 for( i = 0; i < nonefixvars; ++i )
1011 {
1012 /* if the variable was fixed to 1 by the heuristic, get its negated variable */
1013 if( onefixvals[i] )
1014 {
1015 SCIP_CALL( SCIPgetNegatedVar(scip, onefixvars[i], &onefixvars[i]) );
1016 }
1017 }
1018
1019 /* create conflict constraint */
1020 SCIP_CALL( SCIPcreateConsLogicor(scip, &conflictcons, consname, nonefixvars, onefixvars,
1023 SCIPdebugPrintCons(scip, conflictcons, NULL);
1024 SCIP_CALL( SCIPreleaseCons(scip, &conflictcons) );
1025 }
1026#endif
1027 }
1028
1029#ifdef SCIP_DEBUG
1030 SCIP_CALL( SCIPprintStatistics(subscip, NULL) );
1031#endif
1032
1033 /* free subproblem */
1034 SCIPfreeBufferArray(scip, &subvars);
1035 SCIP_CALL( SCIPfree(&subscip) );
1036 }
1037
1038 /*************************** End Subscip Solving ***************************/
1039
1040 TERMINATE:
1041
1042 /* reset the conflict analysis */
1043 if( !SCIPisParamFixed(scip, "conflict/enable") )
1044 {
1045 SCIP_CALL( SCIPsetBoolParam(scip, "conflict/enable", enabledconflicts) );
1046 }
1047
1048 /* free conflict variables */
1049 SCIPfreeBufferArrayNull(scip, &onefixvals);
1050 SCIPfreeBufferArrayNull(scip, &onefixvars);
1051
1052 /* end probing */
1053 if( SCIPinProbing(scip) )
1054 {
1056 }
1057
1058 return SCIP_OKAY;
1059}
1060
1061/*
1062 * primal heuristic specific interface methods
1063 */
1064
1065/** creates the clique primal heuristic and includes it in SCIP */
1067 SCIP* scip /**< SCIP data structure */
1068 )
1069{
1071 SCIP_HEUR* heur;
1072
1073 /* create clique primal heuristic data */
1075
1076 /* include primal heuristic */
1079 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecClique, heurdata) );
1080
1081 assert(heur != NULL);
1082
1083 /* primal heuristic is safe to use in exact solving mode */
1084 SCIPheurMarkExact(heur);
1085
1086 /* set non-NULL pointers to callback methods */
1087 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyClique) );
1088 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeClique) );
1089 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitClique) );
1090
1091 /* add clique primal heuristic parameters */
1092
1093 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minintfixingrate",
1094 "minimum percentage of integer variables that have to be fixable",
1095 &heurdata->minintfixingrate, FALSE, DEFAULT_MININTFIXINGRATE, 0.0, 1.0, NULL, NULL) );
1096
1097 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minmipfixingrate",
1098 "minimum percentage of fixed variables in the sub-MIP",
1099 &heurdata->minmipfixingrate, FALSE, DEFAULT_MINMIPFIXINGRATE, 0.0, 1.0, NULL, NULL) );
1100
1101 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
1102 "maximum number of nodes to regard in the subproblem",
1103 &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1104
1105 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
1106 "number of nodes added to the contingent of the total nodes",
1107 &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1108
1109 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
1110 "minimum number of nodes required to start the subproblem",
1111 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1112
1113 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
1114 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
1115 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
1116
1117 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
1118 "factor by which " HEUR_NAME " heuristic should at least improve the incumbent",
1119 &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
1120
1121 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxproprounds",
1122 "maximum number of propagation rounds during probing (-1 infinity)",
1123 &heurdata->maxproprounds, TRUE, DEFAULT_MAXPROPROUNDS, -1, INT_MAX/4, NULL, NULL) );
1124
1125 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
1126 "should all active cuts from cutpool be copied to constraints in subproblem?",
1127 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
1128
1129 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/uselockfixings",
1130 "should more variables be fixed based on variable locks if the fixing rate was not reached?",
1131 &heurdata->uselockfixings, TRUE, DEFAULT_USELOCKFIXINGS, NULL, NULL) );
1132
1133 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxbacktracks",
1134 "maximum number of backtracks during the fixing process",
1135 &heurdata->maxbacktracks, TRUE, DEFAULT_MAXBACKTRACKS, -1, INT_MAX/4, NULL, NULL) );
1136
1137 return SCIP_OKAY;
1138}
#define DEFAULT_MAXPROPROUNDS
#define DEFAULT_MAXNODES
#define DEFAULT_MINIMPROVE
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
#define NULL
Definition def.h:255
#define SCIP_MAXSTRLEN
Definition def.h:276
#define SCIP_Longint
Definition def.h:148
#define SCIP_MAXTREEDEPTH
Definition def.h:304
#define SCIP_Shortbool
Definition def.h:106
#define SCIP_Bool
Definition def.h:98
#define MIN(x, y)
Definition def.h:231
#define SCIP_Real
Definition def.h:163
#define TRUE
Definition def.h:100
#define FALSE
Definition def.h:101
#define SCIP_CALL_ABORT(x)
Definition def.h:341
#define SCIP_LONGINT_FORMAT
Definition def.h:155
#define SCIP_LONGINT_MAX
Definition def.h:149
#define SCIP_CALL(x)
Definition def.h:362
#define DEFAULT_MINNODES
SCIP_RETCODE SCIPcreateConsLogicor(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, 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 SCIPtranslateSubSols(SCIP *scip, SCIP *subscip, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_Bool *success, int *solindex)
Definition scip_copy.c:1437
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
SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
Definition scip_copy.c:3249
SCIP_RETCODE SCIPcopyCuts(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
Definition scip_copy.c:2113
SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
Definition scip_copy.c:3292
SCIP_Bool SCIPisStopped(SCIP *scip)
SCIP_RETCODE SCIPfree(SCIP **scip)
SCIP_RETCODE SCIPcreate(SCIP **scip)
SCIP_STATUS SCIPgetStatus(SCIP *scip)
int SCIPgetNContVars(SCIP *scip)
Definition scip_prob.c:2569
SCIP_RETCODE SCIPsetObjlimit(SCIP *scip, SCIP_Real objlimit)
Definition scip_prob.c:1661
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition scip_prob.c:2115
int SCIPgetNVars(SCIP *scip)
Definition scip_prob.c:2246
int SCIPgetNConss(SCIP *scip)
Definition scip_prob.c:3620
int SCIPgetNBinVars(SCIP *scip)
Definition scip_prob.c:2293
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition misc.c:3095
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition misc.c:3284
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition misc.c:3061
SCIP_RETCODE SCIPaddConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition scip_prob.c:3901
SCIP_RETCODE SCIPaddConflict(SCIP *scip, SCIP_NODE *node, SCIP_CONS **cons, SCIP_NODE *validnode, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
Definition scip_prob.c:3806
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
#define SCIPdebugMsg
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition scip_param.c:250
SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:111
SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
Definition scip_param.c:219
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:83
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition scip_param.c:545
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:139
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition scip_param.c:487
SCIP_RETCODE SCIPsetSubscipsOff(SCIP *scip, SCIP_Bool quiet)
Definition scip_param.c:904
SCIP_RETCODE SCIPsetPresolving(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition scip_param.c:956
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:57
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition scip_param.c:429
SCIP_RETCODE SCIPsetSeparating(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition scip_param.c:985
SCIP_RETCODE SCIPincludeHeurClique(SCIP *scip)
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
int SCIPgetNPseudoBranchCands(SCIP *scip)
SCIP_Bool SCIPisCertified(SCIP *scip)
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1173
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:183
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition heur.c:1368
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition scip_heur.c:122
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition heur.c:1613
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:167
SCIP_Longint SCIPheurGetNCalls(SCIP_HEUR *heur)
Definition heur.c:1593
void SCIPheurMarkExact(SCIP_HEUR *heur)
Definition heur.c:1457
SCIP_RETCODE SCIPsetHeurInit(SCIP *scip, SCIP_HEUR *heur,)
Definition scip_heur.c:199
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition heur.c:1467
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition heur.c:1378
SCIP_RETCODE SCIPflushLP(SCIP *scip)
Definition scip_lp.c:154
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition scip_lp.c:87
SCIP_RETCODE SCIPconstructLP(SCIP *scip, SCIP_Bool *cutoff)
Definition scip_lp.c:130
SCIP_Bool SCIPisLPConstructed(SCIP *scip)
Definition scip_lp.c:105
SCIP_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
int SCIPgetNUnfixedLPCols(SCIP *scip)
Definition scip_lp.c:554
int SCIPgetNLPCols(SCIP *scip)
Definition scip_lp.c:533
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
Definition scip_lp.c:673
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition scip_mem.c:57
#define SCIPallocClearBufferArray(scip, ptr, num)
Definition scip_mem.h:126
#define SCIPallocBufferArray(scip, ptr, num)
Definition scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition scip_mem.h:136
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition scip_mem.h:137
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
int SCIPgetProbingDepth(SCIP *scip)
char * SCIPsnprintfProbingStats(SCIP *scip, char *strbuf, int len)
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
SCIP_Bool SCIPinProbing(SCIP *scip)
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
SCIP_RETCODE SCIPfixVarProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval)
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition scip_sol.c:2353
int SCIPgetNSols(SCIP *scip)
Definition scip_sol.c:2889
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition scip_sol.c:3130
SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition scip_sol.c:4019
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:1892
SCIP_RETCODE SCIPpresolve(SCIP *scip)
SCIP_RETCODE SCIPsolve(SCIP *scip)
SCIP_Real SCIPgetUpperbound(SCIP *scip)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
SCIP_Real SCIPgetLowerbound(SCIP *scip)
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPsumepsilon(SCIP *scip)
SCIP_NODE * SCIPgetFocusNode(SCIP *scip)
Definition scip_tree.c:72
int SCIPgetDepth(SCIP *scip)
Definition scip_tree.c:672
SCIP_RETCODE SCIPcutoffNode(SCIP *scip, SCIP_NODE *node)
Definition scip_tree.c:436
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
Definition scip_tree.c:91
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:24268
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:23900
SCIP_CLIQUE ** SCIPgetCliques(SCIP *scip)
Definition scip_var.c:9566
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23267
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition scip_var.c:2166
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:24234
int SCIPgetNCliques(SCIP *scip)
Definition scip_var.c:9512
void SCIPenableVarHistory(SCIP *scip)
Definition scip_var.c:11083
void SCIPsort(int *perm, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
Definition misc.c:5581
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
SCIPfreeSol(scip, &heurdata->sol))
#define HEUR_NAME
#define HEUR_FREQ
#define HEUR_USESSUBSCIP
SCIPcreateSol(scip, &heurdata->sol, heur))
#define DEFAULT_NODESQUOT
Definition heur_alns.c:90
#define DEFAULT_COPYCUTS
Definition heur_alns.c:147
#define DEFAULT_MININTFIXINGRATE
Definition heur_clique.c:89
#define DEFAULT_NODESOFS
Definition heur_clique.c:95
#define DEFAULT_MINMIPFIXINGRATE
Definition heur_clique.c:90
#define DEFAULT_MAXBACKTRACKS
Definition heur_clique.c:98
static SCIP_RETCODE applyCliqueFixings(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_Bool enabledconflicts, SCIP_VAR **onefixvars, SCIP_Shortbool *onefixvals, int *nonefixvars, SCIP_Bool *cutoff)
static int getCliqueUnfixedVars(SCIP_CLIQUE *clique)
#define DEFAULT_USELOCKFIXINGS
LNS heuristic using a clique partition to restrict the search neighborhood.
SCIP_Bool lperror
int c
SCIPendProbing(scip))
SCIP_Bool cutoff
static SCIP_SOL * sol
SCIP_Real obj
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIPlinkLPSol(scip, sol))
heurdata usednodes
Definition heur_locks.c:160
SCIP_RETCODE SCIPapplyLockFixings(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_Bool *cutoff, SCIP_Bool *allrowsfulfilled)
Definition heur_locks.c:191
locks primal heuristic
SCIP_VAR * var
static SCIP_VAR ** vars
SCIP_VAR ** SCIPcliqueGetVars(SCIP_CLIQUE *clique)
Definition implics.c:3384
int SCIPcliqueGetNVars(SCIP_CLIQUE *clique)
Definition implics.c:3374
SCIP_Bool * SCIPcliqueGetValues(SCIP_CLIQUE *clique)
Definition implics.c:3396
memory allocation routines
public methods for primal heuristics
public methods for implications, variable bounds, and cliques
public methods for message output
#define SCIPdebug(x)
Definition pub_message.h:93
#define SCIPdebugPrintCons(x, y, z)
public data structures and miscellaneous methods
methods for sorting joint arrays of various types
public methods for problem variables
public methods for branching rule plugins and branching
public methods for certified solving
public methods for constraint handler plugins and constraints
public methods for problem copies
public methods for exact solving
general public methods
public methods for primal heuristic plugins and divesets
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for the probing mode
public methods for 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
@ SCIP_CONFTYPE_PROPAGATION
@ SCIP_CONFTYPE_INFEASLP
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
#define SCIP_DECL_HEURCOPY(x)
Definition type_heur.h:97
struct SCIP_HeurData SCIP_HEURDATA
Definition type_heur.h:77
struct SCIP_Heur SCIP_HEUR
Definition type_heur.h:76
#define SCIP_DECL_HEURINIT(x)
Definition type_heur.h:113
#define SCIP_DECL_HEURFREE(x)
Definition type_heur.h:105
#define SCIP_DECL_HEUREXEC(x)
Definition type_heur.h:163
struct SCIP_Clique SCIP_CLIQUE
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition type_lp.h:52
@ SCIP_LPSOLSTAT_ERROR
Definition type_lp.h:50
@ SCIP_LPSOLSTAT_OPTIMAL
Definition type_lp.h:44
@ SCIP_LPSOLSTAT_INFEASIBLE
Definition type_lp.h:45
@ SCIP_LPSOLSTAT_OBJLIMIT
Definition type_lp.h:47
@ SCIP_VERBLEVEL_FULL
struct SCIP_HashMap SCIP_HASHMAP
Definition type_misc.h:106
#define SCIP_DECL_SORTINDCOMP(x)
Definition type_misc.h:181
@ SCIP_PARAMSETTING_OFF
@ SCIP_PARAMSETTING_FAST
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_DIDNOTFIND
Definition type_result.h:44
@ SCIP_FOUNDSOL
Definition type_result.h:56
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
@ SCIP_STATUS_INFEASIBLE
Definition type_stat.h:44
struct SCIP_Var SCIP_VAR
Definition type_var.h:166