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
76
77#define HEUR_NAME "clique"
78#define HEUR_DESC "LNS heuristic using a clique partition to restrict the search neighborhood"
79#define HEUR_DISPCHAR SCIP_HEURDISPCHAR_PROP
80#define HEUR_PRIORITY 5000
81#define HEUR_FREQ 0
82#define HEUR_FREQOFS 0
83#define HEUR_MAXDEPTH -1
84#define HEUR_TIMING SCIP_HEURTIMING_BEFORENODE
85#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
86
87#define DEFAULT_MAXNODES 5000LL /**< maximum number of nodes to regard in the subproblem */
88#define DEFAULT_MININTFIXINGRATE 0.65 /**< minimum percentage of integer variables that have to be fixed */
89#define DEFAULT_MINMIPFIXINGRATE 0.65 /**< minimum percentage of variables that have to be fixed within sub-SCIP
90 * (integer and continuous) */
91#define DEFAULT_MINIMPROVE 0.01 /**< factor by which clique heuristic should at least improve the
92 * incumbent */
93#define DEFAULT_MINNODES 500LL /**< minimum number of nodes to regard in the subproblem */
94#define DEFAULT_NODESOFS 500LL /**< number of nodes added to the contingent of the total nodes */
95#define DEFAULT_NODESQUOT 0.1 /**< subproblem nodes in relation to nodes of the original problem */
96#define DEFAULT_MAXPROPROUNDS 2 /**< maximum number of propagation rounds during probing */
97#define DEFAULT_MAXBACKTRACKS 10 /**< maximum number of backtracks during the fixing process */
98#define DEFAULT_COPYCUTS TRUE /**< should all active cuts from the cutpool of the
99 * original scip be copied to constraints of the subscip */
100#define DEFAULT_USELOCKFIXINGS FALSE /**< should more variables be fixed based on variable locks if
101 * the fixing rate was not reached? */
102
103
104/*
105 * Data structures
106 */
107
108/** primal heuristic data */
109struct SCIP_HeurData
110{
111 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in the subproblem */
112 SCIP_Longint minnodes; /**< minimum number of nodes to regard in the subproblem */
113 SCIP_Longint nodesofs; /**< number of nodes added to the contingent of the total nodes */
114 SCIP_Longint usednodes; /**< nodes already used by clique heuristic in earlier calls */
115 SCIP_Real minintfixingrate; /**< minimum percentage of integer variables that have to be fixed */
116 SCIP_Real minmipfixingrate; /**< minimum percentage of variables that have to be fixed within sub-SCIP
117 * (integer and continuous) */
118 SCIP_Real minimprove; /**< factor by which clique heuristic should at least improve the incumbent */
119 SCIP_Real nodesquot; /**< subproblem nodes in relation to nodes of the original problem */
120 int maxproprounds; /**< maximum number of propagation rounds during probing */
121 int maxbacktracks; /**< maximum number of backtracks during the fixing process */
122 SCIP_Bool copycuts; /**< should all active cuts from cutpool be copied to constraints in
123 * subproblem?
124 */
125 SCIP_Bool uselockfixings; /**< should more variables be fixed based on variable locks if
126 * the fixing rate was not reached?
127 */
128};
129
130/*
131 * Local methods
132 */
133
134/** comparison method for sorting cliques by their size */
135static
136SCIP_DECL_SORTINDCOMP(compCliquesSize)
137{
138 int* cliquesizes = (int*)dataptr;
139
140 return cliquesizes[ind2] - cliquesizes[ind1];
141}
142
143static
145 SCIP_CLIQUE* clique
146 )
147{
148 SCIP_VAR** cliquevars;
149 SCIP_VAR* var;
150 int ncliquevars;
151 int nunfixed = 0;
152 int v;
153
154 ncliquevars = SCIPcliqueGetNVars(clique);
155 cliquevars = SCIPcliqueGetVars(clique);
156
157 for( v = 0; v < ncliquevars; ++v )
158 {
159 var = cliquevars[v];
160
161 /* is variable unfixed? */
163 ++nunfixed;
164 }
165
166 return nunfixed;
167}
168
169/** apply clique fixing using probing */
170static
172 SCIP* scip, /**< original SCIP data structure */
173 SCIP_HEURDATA* heurdata, /**< structure containing heurdata */
174 SCIP_Bool enabledconflicts, /**< was conflict analysis enabled before the heuristic call? */
175 SCIP_VAR** onefixvars, /**< array to store all variables which are fixed to one in the cliques */
176 SCIP_Shortbool* onefixvals, /**< array to store the values of all variables fixed to one in the cliques */
177 int* nonefixvars, /**< pointer to store the number of variables fixed to one */
178 SCIP_Bool* cutoff /**< pointer to store whether the propagation stopped with infeasibility */
179 )
180{
181 SCIP_CLIQUE** cliques;
182 SCIP_CLIQUE* clique;
183 SCIP_VAR** cliquevars;
184 SCIP_VAR* var;
185 SCIP_Bool* cliquevals;
186 SCIP_Bool* propagated;
187 int* cliquesizes;
188 int* permutation;
189 SCIP_Real bestobj;
191 SCIP_Bool alreadyone;
192 SCIP_Bool newnode;
193 int probingdepthofonefix;
194 int ncliquevars;
195 int ncliques;
196 int bestpos;
197 int firstclique;
198 int bestclique;
199 int cliquesize;
200 int bestcliquesize;
201 int nbacktracks = 0;
202 int v = 0;
203 int c;
204 int i;
205
206 assert(scip != NULL);
207 assert(heurdata != NULL);
208 assert(onefixvars != NULL);
209 assert(nonefixvars != NULL);
210 assert(cutoff != NULL);
211
212 cliques = SCIPgetCliques(scip);
213 ncliques = SCIPgetNCliques(scip);
214
215 /* allocate memory */
216 SCIP_CALL( SCIPallocBufferArray(scip, &cliquesizes, ncliques) );
217 SCIP_CALL( SCIPallocBufferArray(scip, &permutation, ncliques) );
218 SCIP_CALL( SCIPallocClearBufferArray(scip, &propagated, ncliques) );
219
220 for( c = ncliques - 1; c >= 0; --c )
221 {
222 cliquesizes[c] = SCIPcliqueGetNVars(cliques[c]);
223 }
224
225 SCIPsort(permutation, compCliquesSize, (void*)cliquesizes, ncliques);
226
227#ifndef NDEBUG
228 for( c = ncliques - 1; c >= 1; --c )
229 {
230 assert(cliquesizes[permutation[c]] <= cliquesizes[permutation[c-1]]);
231 }
232#endif
233
234 *cutoff = FALSE;
235 probingdepthofonefix = 0;
236 firstclique = 0;
237
239
240 /* @todo maybe try to fix more than one variable to one in each probing node, to gain faster results */
241 for( c = 0; c < ncliques; ++c )
242 {
243 bestpos = -1;
244 bestobj = SCIPinfinity(scip);
245 alreadyone = FALSE;
246 newnode = FALSE;
247
248 bestclique = firstclique;
249
250 if( bestclique >= ncliques )
251 break;
252
253 bestcliquesize = getCliqueUnfixedVars(cliques[permutation[bestclique]]);
254 assert(!propagated[permutation[bestclique]]);
255
256 for( i = firstclique + 1; i < ncliques; ++i)
257 {
258 if( cliquesizes[permutation[i]] < bestcliquesize )
259 break;
260
261 if( propagated[permutation[i]] )
262 continue;
263
264 cliquesize = getCliqueUnfixedVars(cliques[permutation[i]]);
265
266 if( cliquesize > bestcliquesize )
267 {
268 bestclique = i;
269 bestcliquesize = cliquesize;
270 }
271 else if( cliquesize == 0 )
272 {
273 propagated[permutation[i]] = TRUE;
274 }
275 }
276 clique = cliques[permutation[bestclique]];
277 propagated[permutation[bestclique]] = TRUE;
278
279 while( firstclique < ncliques && propagated[permutation[firstclique]] )
280 ++firstclique;
281
282 ncliquevars = SCIPcliqueGetNVars(clique);
283 cliquevars = SCIPcliqueGetVars(clique);
284 cliquevals = SCIPcliqueGetValues(clique);
285
286 for( v = 0; v < ncliquevars; ++v )
287 {
288 var = cliquevars[v];
289
290 /* variable is already fixed */
292 {
293 SCIPdebugMsg(scip, "<%s> is already fixed to %g\n", SCIPvarGetName(var), SCIPvarGetUbLocal(var));
294
295 /* clique variable is fixed to 1 */
296 if( cliquevals[v] == (SCIPvarGetLbLocal(var) > 0.5) )
297 {
298 assert(!alreadyone);
299 alreadyone = TRUE;
300 break;
301 }
302 continue;
303 }
304
305 obj = cliquevals[v] ? SCIPvarGetObj(var) : -SCIPvarGetObj(var);
306
307 /* @todo use a tiebreaker (locks?) */
308 if( obj < bestobj )
309 {
310 /* variable is not the best one in the clique anymore, fix it to 0 */
311 if( bestpos >= 0 )
312 {
313 assert(bestpos < ncliquevars);
314 if( cliquevals[bestpos] )
315 {
316 SCIP_CALL( SCIPfixVarProbing(scip, cliquevars[bestpos], 0.0) );
317 }
318 else
319 {
320 SCIP_CALL( SCIPfixVarProbing(scip, cliquevars[bestpos], 1.0) );
321 }
322 SCIPdebugMsg(scip, "fixed <%s> to %g\n", SCIPvarGetName(cliquevars[bestpos]), SCIPvarGetUbLocal(cliquevars[bestpos]));
323 newnode = TRUE;
324 }
325
326 bestobj = obj;
327 bestpos = v;
328 }
329 /* variable is not the best one in the clique, fix it to 0 */
330 else
331 {
332 assert(bestpos >= 0);
333
334 if( cliquevals[v] )
335 {
337 }
338 else
339 {
341 }
342 SCIPdebugMsg(scip, "fixed <%s> to %g\n", SCIPvarGetName(var), SCIPvarGetUbLocal(var));
343 newnode = TRUE;
344 }
345 }
346 /* we found a variable in the clique which is already fixed to 1 */
347 if( alreadyone )
348 {
349 /* fix (so far) best candidate to 0 */
350 if( bestpos >= 0 )
351 {
352 assert(bestpos < ncliquevars);
353 if( cliquevals[bestpos] )
354 {
355 SCIP_CALL( SCIPfixVarProbing(scip, cliquevars[bestpos], 0.0) );
356 }
357 else
358 {
359 SCIP_CALL( SCIPfixVarProbing(scip, cliquevars[bestpos], 1.0) );
360 }
361 SCIPdebugMsg(scip, "fixed <%s> to %g\n", SCIPvarGetName(cliquevars[bestpos]), SCIPvarGetUbLocal(cliquevars[bestpos]));
362 newnode = TRUE;
363 }
364
365 /* fix all variables not yet processed to 0 */
366 for( ; v < ncliquevars; ++v )
367 {
368 var = cliquevars[v];
369
371 continue;
372
373 if( cliquevals[v] )
374 {
376 }
377 else
378 {
380 }
381 SCIPdebugMsg(scip, "fixed <%s> to %g\n", SCIPvarGetName(var), SCIPvarGetUbLocal(var));
382 newnode = TRUE;
383 }
384 }
385 /* fix the best variable to 1 */
386 else if( bestpos >= 0 )
387 {
388 assert(bestpos < ncliquevars);
389 onefixvars[*nonefixvars] = cliquevars[bestpos];
390 probingdepthofonefix = SCIPgetProbingDepth(scip);
391
392 /* @todo should we even fix the best candidate to 1? */
393 if( cliquevals[bestpos] )
394 {
395 SCIP_CALL( SCIPfixVarProbing(scip, cliquevars[bestpos], 1.0) );
396 onefixvals[*nonefixvars] = 1;
397 }
398 else
399 {
400 SCIP_CALL( SCIPfixVarProbing(scip, cliquevars[bestpos], 0.0) );
401 onefixvals[*nonefixvars] = 0;
402 }
403 SCIPdebugMsg(scip, "fixed <%s> to %g*\n", SCIPvarGetName(cliquevars[bestpos]), SCIPvarGetUbLocal(cliquevars[bestpos]));
404 ++(*nonefixvars);
405 newnode = TRUE;
406 }
407
408 if( newnode )
409 {
410 /* propagate fixings */
412
413 SCIPdebugMsg(scip, "propagate fixings of clique %d: cutoff=%u\n", c, *cutoff);
414
415 if( SCIPisStopped(scip) )
416 break;
417
418 /* stop if we reached the depth limit */
420 break;
421
422 /* probing detected infeasibility: backtrack */
423 if( *cutoff )
424 {
425 if( *nonefixvars > 0 )
426 {
427 if( probingdepthofonefix > 0 )
428 {
429 SCIP_CALL( SCIPbacktrackProbing(scip, probingdepthofonefix - 1) );
430 probingdepthofonefix = 0;
431 ++nbacktracks;
432
433 /* because of the limited number of propagation rounds, it may happen that conflict analysis finds a
434 * valid global fixing for the last fixed variable that conflicts with applying the reverse fixing
435 * after backtracking; in that case, we ran into a deadend and stop
436 */
437 if( SCIPvarGetLbLocal(onefixvars[*nonefixvars - 1]) < 1.5 - onefixvals[*nonefixvars - 1]
438 && SCIPvarGetUbLocal(onefixvars[*nonefixvars - 1]) > 0.5 - onefixvals[*nonefixvars - 1] )
439 {
440 /* fix the last variable, which was fixed to 1 and led to the cutoff, to 0 */
441 SCIP_CALL( SCIPfixVarProbing(scip, onefixvars[*nonefixvars - 1], 1.0 - onefixvals[*nonefixvars - 1]) );
442 --(*nonefixvars);
443
444 /* propagate fixings */
446
447 SCIPdebugMsg(scip, "backtrack %d was %sfeasible\n", nbacktracks, (*cutoff ? "in" : ""));
448 }
449#ifndef NDEBUG
450 else
451 assert(*cutoff == TRUE);
452#endif
453 }
454 if( *cutoff )
455 {
456 SCIPdebugMsg(scip, "probing was infeasible after %d backtracks\n", nbacktracks);
457#ifndef NOCONFLICT
458 if( enabledconflicts )
459 {
460 SCIP_CONS* conflictcons;
461 char consname[SCIP_MAXSTRLEN];
462
463 /* create own conflict */
464 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "conf%" SCIP_LONGINT_FORMAT "", SCIPgetNNodes(scip));
465
466 /* get variables for the conflict */
467 for( i = 0; i < *nonefixvars; ++i )
468 {
469 /* if the variable was fixed to 1 by the heuristic, get its negated variable */
470 if( onefixvals[i] )
471 {
472 SCIP_CALL( SCIPgetNegatedVar(scip, onefixvars[i], &onefixvars[i]) );
473 }
474 }
475
476 /* create conflict constraint */
477 SCIP_CALL( SCIPcreateConsLogicor(scip, &conflictcons, consname, *nonefixvars, onefixvars,
479 SCIPdebugPrintCons(scip, conflictcons, NULL);
481 }
482#endif
483 break;
484 }
485 else if( nbacktracks > heurdata->maxbacktracks )
486 {
487 SCIPdebugMsg(scip, "interrupt probing after %d backtracks\n", nbacktracks);
488 break;
489 }
490 }
491 /* we had a cutoff without a single one-fixing, so the current problem seems to be infeasible already */
492 else
493 break;
494 }
495
497 }
498 }
499 assert((*nonefixvars > 0) || probingdepthofonefix == 0 );
500
501 SCIPfreeBufferArray(scip, &propagated);
502 SCIPfreeBufferArray(scip, &permutation);
503 SCIPfreeBufferArray(scip, &cliquesizes);
504
505 SCIPdebugMsg(scip, "fixed %d of %d variables in probing\n", v, SCIPgetNVars(scip) - SCIPgetNContVars(scip));
506 SCIPdebugMsg(scip, "applied %d of %d cliques in probing\n", c, ncliques);
507 SCIPdebugMsg(scip, "probing was %sfeasible\n", (*cutoff) ? "in" : "");
508
509 return SCIP_OKAY;
510}
511
512/*
513 * Callback methods of primal heuristic
514 */
515
516/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
517static
518SCIP_DECL_HEURCOPY(heurCopyClique)
519{ /*lint --e{715}*/
520 assert(scip != NULL);
521 assert(heur != NULL);
522
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(scip != NULL);
539
541
542 /* free heuristic data */
544 assert(heurdata != NULL);
545
547 SCIPheurSetData(heur, NULL);
548
549 return SCIP_OKAY;
550}
551
552
553/** initialization method of primal heuristic (called after problem was transformed) */
554static
555SCIP_DECL_HEURINIT(heurInitClique)
556{ /*lint --e{715}*/
558
559 assert(heur != NULL);
560 assert(scip != NULL);
561
563
564 /* reset heuristic data */
566 assert(heurdata != NULL);
567
568 heurdata->usednodes = 0;
569
570 return SCIP_OKAY;
571}
572
573/** execution method of primal heuristic */
574static
575SCIP_DECL_HEUREXEC(heurExecClique)
576{ /*lint --e{715}*/
578 SCIP_VAR** vars;
579 SCIP_Real lowerbound;
580 int nvars;
581 int nbinvars;
582 int oldnpscands;
583 int npscands;
584 int i;
587
588 SCIP_VAR** onefixvars;
589 SCIP_Shortbool* onefixvals;
590 int nonefixvars;
591 SCIP_Bool enabledconflicts;
592 SCIP_LPSOLSTAT lpstatus;
593 SCIP_CONS* conflictcons;
594 SCIP_Bool solvelp;
595 char consname[SCIP_MAXSTRLEN];
596
597 SCIP_Longint nstallnodes;
598
599 assert(heur != NULL);
600 assert(scip != NULL);
601 assert(result != NULL);
602
604
606
607 /* get heuristic's data */
609 assert(heurdata != NULL);
610
611 nbinvars = SCIPgetNBinVars(scip);
612
613 if( nbinvars < 2 )
614 return SCIP_OKAY;
615
616 /* check for necessary information to apply this heuristic */
617 if( SCIPgetNCliques(scip) == 0 )
618 return SCIP_OKAY;
619
620 lowerbound = SCIPgetLowerbound(scip);
621
622 /* calculate the maximal number of branching nodes until heuristic is aborted */
623 nstallnodes = (SCIP_Longint)(heurdata->nodesquot * SCIPgetNNodes(scip));
624
625 /* reward clique heuristic if it succeeded often */
626 nstallnodes = (SCIP_Longint)(nstallnodes * 3.0 * (SCIPheurGetNBestSolsFound(heur)+1.0)/(SCIPheurGetNCalls(heur) + 1.0));
627 nstallnodes -= 100 * SCIPheurGetNCalls(heur); /* count the setup costs for the sub-MIP as 100 nodes */
628 nstallnodes += heurdata->nodesofs;
629
630 /* determine the node limit for the current process */
631 nstallnodes -= heurdata->usednodes;
632 nstallnodes = MIN(nstallnodes, heurdata->maxnodes);
633
634 /* check whether we have enough nodes left to call subproblem solving */
635 if( nstallnodes < heurdata->minnodes )
636 {
637 SCIPdebugMsg(scip, "skipping " HEUR_NAME ": nstallnodes=%" SCIP_LONGINT_FORMAT ", minnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->minnodes);
638 return SCIP_OKAY;
639 }
640
641 oldnpscands = SCIPgetNPseudoBranchCands(scip);
642 onefixvars = NULL;
643 onefixvals = NULL;
644
645 /* disable conflict analysis, because we can it better than SCIP itself, cause we have more information */
646 SCIP_CALL( SCIPgetBoolParam(scip, "conflict/enable", &enabledconflicts) );
647
648 if( !SCIPisParamFixed(scip, "conflict/enable") )
649 {
650 SCIP_CALL( SCIPsetBoolParam(scip, "conflict/enable", FALSE) );
651 }
652
653 solvelp = SCIPhasCurrentNodeLP(scip);
654
655 if( !SCIPisLPConstructed(scip) && solvelp )
656 {
658
659 /* manually cut off the node if the LP construction detected infeasibility (heuristics cannot return such a
660 * result); the cutoff result is safe to use in exact solving mode, but we don't have enough information to
661 * give a certificate for the cutoff
662 */
663 if( cutoff && !SCIPisCertified(scip) )
664 {
666 goto TERMINATE;
667 }
668
670 }
671
672 /* get number of possible binary variables */
673 nbinvars = SCIPgetNVars(scip) - SCIPgetNContVars(scip);
674 assert(nbinvars >= 2);
675
677
678 /* start probing */
680
681#ifdef COLLECTSTATISTICS
683#endif
684
685 /* allocate memory for all variables which will be fixed to one during probing */
686 SCIP_CALL( SCIPallocBufferArray(scip, &onefixvars, nbinvars) );
687 SCIP_CALL( SCIPallocBufferArray(scip, &onefixvals, nbinvars) );
688 nonefixvars = 0;
689
690 /* apply fixings due to clique information */
691 SCIP_CALL( applyCliqueFixings(scip, heurdata, enabledconflicts, onefixvars, onefixvals, &nonefixvars, &cutoff) );
692
693 if( cutoff || SCIPisStopped(scip) )
694 goto TERMINATE;
695
696 /* check that we had enough fixings */
698
699 SCIPdebugMsg(scip, "npscands=%d, oldnpscands=%d, heurdata->minintfixingrate=%g\n", npscands, oldnpscands, heurdata->minintfixingrate);
700
701 if( npscands > oldnpscands * (1.0 - heurdata->minintfixingrate) )
702 {
703 if( heurdata->uselockfixings && npscands <= 2.0 * oldnpscands * (1.0 - heurdata->minintfixingrate) )
704 {
705 SCIP_Bool allrowsfulfilled = FALSE;
706
707 SCIP_CALL( SCIPapplyLockFixings(scip, NULL, &cutoff, &allrowsfulfilled) );
708
709 if( cutoff || SCIPisStopped(scip) )
710 {
711 SCIPdebugMsg(scip, "cutoff or timeout in locks fixing\n");
712 goto TERMINATE;
713 }
714
716
717 SCIPdebugMsg(scip, "after lockfixings: npscands=%d, oldnpscands=%d, allrowsfulfilled=%u, heurdata->minintfixingrate=%g\n",
718 npscands, oldnpscands, allrowsfulfilled, heurdata->minintfixingrate);
719
720 if( !allrowsfulfilled && npscands > oldnpscands * (1 - heurdata->minintfixingrate) )
721 {
722 SCIPdebugMsg(scip, "--> too few fixings\n");
723
724 goto TERMINATE;
725 }
726 }
727 else
728 {
729 SCIPdebugMsg(scip, "--> too few fixings\n");
730
731 goto TERMINATE;
732 }
733 }
734
735 /*************************** Probing LP Solving ***************************/
736
737 lpstatus = SCIP_LPSOLSTAT_ERROR;
738 lperror = FALSE;
739
740 /* solve lp only if the problem is still feasible */
741 if( solvelp )
742 {
743 char strbuf[SCIP_MAXSTRLEN];
744 int ncols;
745
746 /* print message if relatively large LP is solved from scratch, since this could lead to a longer period during
747 * which the user sees no output; more detailed probing stats only in debug mode */
748 ncols = SCIPgetNLPCols(scip);
749 if( !SCIPisLPSolBasic(scip) && ncols > 1000 )
750 {
751 int nunfixedcols = SCIPgetNUnfixedLPCols(scip);
752
753 if( nunfixedcols > 0.5 * ncols )
754 {
756 "Heuristic " HEUR_NAME " solving LP from scratch with %.1f %% unfixed columns (%d of %d) ...\n",
757 100.0 * (nunfixedcols / (SCIP_Real)ncols), nunfixedcols, ncols);
758 }
759 }
760 SCIPdebugMsg(scip, "Heuristic " HEUR_NAME " probing LP: %s\n",
762
763 /* solve LP; errors in the LP solver should not kill the overall solving process, if the LP is just needed for a
764 * heuristic. hence in optimized mode, the return code is caught and a warning is printed, only in debug mode,
765 * SCIP will stop.
766 */
767 SCIPdebugMsg(scip, "starting solving clique-lp at time %g\n", SCIPgetSolvingTime(scip));
768#ifdef NDEBUG
769 {
770 SCIP_Bool retstat;
771 retstat = SCIPsolveProbingLP(scip, -1, &lperror, NULL);
772 if( retstat != SCIP_OKAY )
773 {
774 SCIPwarningMessage(scip, "Error while solving LP in clique heuristic; LP solve terminated with code <%d>\n",
775 retstat);
776 }
777 }
778#else
780#endif
781 SCIPdebugMsg(scip, "ending solving clique-lp at time %g\n", SCIPgetSolvingTime(scip));
782
783 lpstatus = SCIPgetLPSolstat(scip);
784
785 SCIPdebugMsg(scip, " -> new LP iterations: %" SCIP_LONGINT_FORMAT "\n", SCIPgetNLPIterations(scip));
786 SCIPdebugMsg(scip, " -> error=%u, status=%d\n", lperror, lpstatus);
787 }
788
789 /* check if this is a feasible solution */
790 if( lpstatus == SCIP_LPSOLSTAT_OPTIMAL && !lperror )
791 {
792 SCIP_SOL* sol;
793 SCIP_Bool stored;
794 SCIP_Bool success;
795
796 assert(!cutoff);
797
798 lowerbound = SCIPgetLPObjval(scip);
799
800 /* create a solution from the current LP solution */
801 SCIP_CALL( SCIPcreateSol(scip, &sol, heur) );
803
804 SCIP_CALL( SCIProundSol(scip, sol, &success) );
805
806 if( success )
807 {
808 SCIPdebugMsg(scip, "clique heuristic found roundable primal solution: obj=%g\n",
810
811 /* check solution for feasibility, and add it to solution store if possible.
812 * Neither integrality nor feasibility of LP rows have to be checked, because they
813 * are guaranteed by the heuristic at this stage.
814 */
815#ifdef SCIP_DEBUG
816 SCIP_CALL( SCIPtrySol(scip, sol, TRUE, TRUE, TRUE, TRUE, TRUE, &stored) );
817#else
819#endif
820
821 if( stored )
822 {
823 SCIPdebugMsg(scip, "found feasible solution:\n");
826 }
827
829
830 /* we found a solution, so we are done */
831 goto TERMINATE;
832 }
833
835 }
836 /*************************** END Probing LP Solving ***************************/
837
838 /*************************** Create Conflict ***************************/
839 if( enabledconflicts && SCIPallColsInLP(scip) &&
840 (lpstatus == SCIP_LPSOLSTAT_INFEASIBLE || lpstatus == SCIP_LPSOLSTAT_OBJLIMIT) )
841 {
842#ifndef NOCONFLICT
843 /* create own conflict */
844 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "conf%" SCIP_LONGINT_FORMAT "", SCIPgetNNodes(scip));
845
846 /* get variables for the conflict */
847 for( i = 0; i < nonefixvars; ++i )
848 {
849 /* if the variable was fixed to 1 by the heuristic, get its negated variable */
850 if( onefixvals[i] )
851 {
852 SCIP_CALL( SCIPgetNegatedVar(scip, onefixvars[i], &onefixvars[i]) );
853 }
854 }
855
856 /* create conflict constraint */
857 SCIP_CALL( SCIPcreateConsLogicor(scip, &conflictcons, consname, nonefixvars, onefixvars,
859 SCIPdebugPrintCons(scip, conflictcons, NULL);
861#endif
862 goto TERMINATE;
863 }
864 /*************************** End Conflict ***************************/
865
866 /*************************** Start Subscip Solving ***************************/
867 /* no solution has been found yet and the subproblem is still feasible --> fix all other variables by subscip if
868 * necessary
869 */
870 if( !lperror )
871 {
872 SCIP* subscip;
873 SCIP_VAR** subvars;
874 SCIP_HASHMAP* varmap;
876
877 /* check whether there is enough time and memory left */
879
880 if( !valid )
881 goto TERMINATE;
882
883 /* get all variables */
885
886 /* create subproblem */
887 SCIP_CALL( SCIPcreate(&subscip) );
888
889 /* allocate temporary memory for subscip variables */
891
892 /* create the variable mapping hash map */
893 SCIP_CALL( SCIPhashmapCreate(&varmap, SCIPblkmem(subscip), nvars) );
894
895 SCIP_CALL( SCIPcopyConsCompression(scip, subscip, varmap, NULL, "_clique", NULL, NULL, 0, FALSE, FALSE, FALSE,
896 TRUE, &valid) );
897
898 if( heurdata->copycuts )
899 {
900 /* copies all active cuts from cutpool of sourcescip to linear constraints in targetscip */
901 SCIP_CALL( SCIPcopyCuts(scip, subscip, varmap, NULL, FALSE, NULL) );
902 }
903
904 for( i = 0; i < nvars; i++ )
905 subvars[i] = (SCIP_VAR*) SCIPhashmapGetImage(varmap, vars[i]);
906
907 /* free hash map */
908 SCIPhashmapFree(&varmap);
909
910 /* do not abort subproblem on CTRL-C */
911 SCIP_CALL( SCIPsetBoolParam(subscip, "misc/catchctrlc", FALSE) );
912
913#ifdef SCIP_DEBUG
914 /* for debugging, enable full output */
915 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 5) );
916 SCIP_CALL( SCIPsetIntParam(subscip, "display/freq", 100000000) );
917#else
918 /* disable statistic timing inside sub SCIP and output to console */
919 SCIP_CALL( SCIPsetIntParam(subscip, "display/verblevel", 0) );
920 SCIP_CALL( SCIPsetBoolParam(subscip, "timing/statistictiming", FALSE) );
921#endif
922
923 /* set limits for the subproblem */
924 SCIP_CALL( SCIPcopyLimits(scip, subscip) );
925 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/stallnodes", nstallnodes) );
926 SCIP_CALL( SCIPsetLongintParam(subscip, "limits/nodes", heurdata->maxnodes) );
927
928 /* speed up sub-SCIP by not checking dual LP feasibility */
929 SCIP_CALL( SCIPsetBoolParam(subscip, "lp/checkdualfeas", FALSE) );
930
931 /* forbid call of heuristics and separators solving sub-CIPs */
932 SCIP_CALL( SCIPsetSubscipsOff(subscip, TRUE) );
933
934 /* disable cutting plane separation */
936
937 /* disable expensive presolving */
939
940 /* use inference branching */
941 if( SCIPfindBranchrule(subscip, "inference") != NULL && !SCIPisParamFixed(subscip, "branching/inference/priority") )
942 {
943 SCIP_CALL( SCIPsetIntParam(subscip, "branching/inference/priority", INT_MAX/4) );
944 }
945
946 /* if there is already a solution, add an objective cutoff */
947 if( SCIPgetNSols(scip) > 0 )
948 {
949 SCIP_Real upperbound;
950 SCIP_Real minimprove;
951 SCIP_Real cutoffbound;
952
953 minimprove = heurdata->minimprove;
955
956 upperbound = SCIPgetUpperbound(scip) - SCIPsumepsilon(scip);
957
958 if( !SCIPisInfinity(scip, -1.0 * lowerbound) )
959 {
960 cutoffbound = (1-minimprove) * SCIPgetUpperbound(scip) + minimprove * lowerbound;
961 }
962 else
963 {
964 if( SCIPgetUpperbound ( scip ) >= 0 )
965 cutoffbound = (1 - minimprove) * SCIPgetUpperbound(scip);
966 else
967 cutoffbound = (1 + minimprove) * SCIPgetUpperbound(scip);
968 }
969 cutoffbound = MIN(upperbound, cutoffbound);
970 SCIP_CALL( SCIPsetObjlimit(subscip, cutoffbound) );
971 SCIPdebugMsg(scip, "setting objlimit for subscip to %g\n", cutoffbound);
972 }
973
974 SCIPdebugMsg(scip, "starting solving clique-submip at time %g\n", SCIPgetSolvingTime(scip));
975
976 /* solve the subproblem */
977 /* Errors in the LP solver should not kill the overall solving process, if the LP is just needed for a heuristic.
978 * Hence in optimized mode, the return code is caught and a warning is printed, only in debug mode, SCIP will stop.
979 */
980 SCIP_CALL_ABORT( SCIPpresolve(subscip) );
981
982 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));
983
984 /* after presolving, we should have at least reached a certain fixing rate over ALL variables (including continuous)
985 * to ensure that not only the MIP but also the LP relaxation is easy enough
986 */
987 if( ((nvars - SCIPgetNVars(subscip)) / (SCIP_Real)nvars) >= heurdata->minmipfixingrate )
988 {
989 SCIP_Bool success;
990
991 SCIPdebugMsg(scip, "solving subproblem: nstallnodes=%" SCIP_LONGINT_FORMAT ", maxnodes=%" SCIP_LONGINT_FORMAT "\n", nstallnodes, heurdata->maxnodes);
992
993 SCIP_CALL_ABORT( SCIPsolve(subscip) );
995
996 SCIPdebugMsg(scip, "ending solving clique-submip at time %g, status = %d\n", SCIPgetSolvingTime(scip), SCIPgetStatus(subscip));
997
998 /* check, whether a solution was found; due to numerics, it might happen that not all solutions are feasible ->
999 * try all solutions until one was accepted
1000 */
1001 SCIP_CALL( SCIPtranslateSubSols(scip, subscip, heur, subvars, &success, NULL) );
1002 if( success )
1004
1005#ifndef NOCONFLICT
1006 /* if subscip was infeasible, add a conflict */
1007 if( SCIPgetStatus(subscip) == SCIP_STATUS_INFEASIBLE )
1008 {
1009 /* create own conflict */
1010 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "conf%" SCIP_LONGINT_FORMAT "", SCIPgetNNodes(scip));
1011
1012 /* get variables for the conflict */
1013 for( i = 0; i < nonefixvars; ++i )
1014 {
1015 /* if the variable was fixed to 1 by the heuristic, get its negated variable */
1016 if( onefixvals[i] )
1017 {
1018 SCIP_CALL( SCIPgetNegatedVar(scip, onefixvars[i], &onefixvars[i]) );
1019 }
1020 }
1021
1022 /* create conflict constraint */
1023 SCIP_CALL( SCIPcreateConsLogicor(scip, &conflictcons, consname, nonefixvars, onefixvars,
1026 SCIPdebugPrintCons(scip, conflictcons, NULL);
1027 SCIP_CALL( SCIPreleaseCons(scip, &conflictcons) );
1028 }
1029#endif
1030 }
1031
1032#ifdef SCIP_DEBUG
1033 SCIP_CALL( SCIPprintStatistics(subscip, NULL) );
1034#endif
1035
1036 /* free subproblem */
1037 SCIPfreeBufferArray(scip, &subvars);
1038 SCIP_CALL( SCIPfree(&subscip) );
1039 }
1040
1041 /*************************** End Subscip Solving ***************************/
1042
1043 TERMINATE:
1044
1045 /* reset the conflict analysis */
1046 if( !SCIPisParamFixed(scip, "conflict/enable") )
1047 {
1048 SCIP_CALL( SCIPsetBoolParam(scip, "conflict/enable", enabledconflicts) );
1049 }
1050
1051 /* free conflict variables */
1052 SCIPfreeBufferArrayNull(scip, &onefixvals);
1053 SCIPfreeBufferArrayNull(scip, &onefixvars);
1054
1055 /* end probing */
1056 if( SCIPinProbing(scip) )
1057 {
1059 }
1060
1061 return SCIP_OKAY;
1062}
1063
1064/*
1065 * primal heuristic specific interface methods
1066 */
1067
1068/** creates the clique primal heuristic and includes it in SCIP */
1070 SCIP* scip /**< SCIP data structure */
1071 )
1072{
1074 SCIP_HEUR* heur;
1075
1076 /* create clique primal heuristic data */
1078
1079 /* include primal heuristic */
1082 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecClique, heurdata) );
1083
1084 assert(heur != NULL);
1085
1086 /* primal heuristic is safe to use in exact solving mode */
1087 SCIPheurMarkExact(heur);
1088
1089 /* set non-NULL pointers to callback methods */
1090 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyClique) );
1091 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeClique) );
1092 SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitClique) );
1093
1094 /* add clique primal heuristic parameters */
1095
1096 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minintfixingrate",
1097 "minimum percentage of integer variables that have to be fixable",
1098 &heurdata->minintfixingrate, FALSE, DEFAULT_MININTFIXINGRATE, 0.0, 1.0, NULL, NULL) );
1099
1100 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minmipfixingrate",
1101 "minimum percentage of fixed variables in the sub-MIP",
1102 &heurdata->minmipfixingrate, FALSE, DEFAULT_MINMIPFIXINGRATE, 0.0, 1.0, NULL, NULL) );
1103
1104 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
1105 "maximum number of nodes to regard in the subproblem",
1106 &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1107
1108 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/nodesofs",
1109 "number of nodes added to the contingent of the total nodes",
1110 &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1111
1112 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/minnodes",
1113 "minimum number of nodes required to start the subproblem",
1114 &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
1115
1116 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/nodesquot",
1117 "contingent of sub problem nodes in relation to the number of nodes of the original problem",
1118 &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) );
1119
1120 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/minimprove",
1121 "factor by which " HEUR_NAME " heuristic should at least improve the incumbent",
1122 &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) );
1123
1124 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxproprounds",
1125 "maximum number of propagation rounds during probing (-1 infinity)",
1126 &heurdata->maxproprounds, TRUE, DEFAULT_MAXPROPROUNDS, -1, INT_MAX/4, NULL, NULL) );
1127
1128 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/copycuts",
1129 "should all active cuts from cutpool be copied to constraints in subproblem?",
1130 &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) );
1131
1132 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/uselockfixings",
1133 "should more variables be fixed based on variable locks if the fixing rate was not reached?",
1134 &heurdata->uselockfixings, TRUE, DEFAULT_USELOCKFIXINGS, NULL, NULL) );
1135
1136 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxbacktracks",
1137 "maximum number of backtracks during the fixing process",
1138 &heurdata->maxbacktracks, TRUE, DEFAULT_MAXBACKTRACKS, -1, INT_MAX/4, NULL, NULL) );
1139
1140 return SCIP_OKAY;
1141}
#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:257
#define SCIP_MAXSTRLEN
Definition def.h:278
#define SCIP_Longint
Definition def.h:150
#define SCIP_MAXTREEDEPTH
Definition def.h:306
#define SCIP_Shortbool
Definition def.h:108
#define SCIP_Bool
Definition def.h:100
#define MIN(x, y)
Definition def.h:233
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define SCIP_CALL_ABORT(x)
Definition def.h:343
#define SCIP_LONGINT_FORMAT
Definition def.h:157
#define SCIP_LONGINT_MAX
Definition def.h:151
#define SCIP_CALL(x)
Definition def.h:364
#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:1438
SCIP_RETCODE SCIPcopyConsCompression(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool global, SCIP_Bool enablepricing, SCIP_Bool threadsafe, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
Definition scip_copy.c:2962
SCIP_RETCODE SCIPcheckCopyLimits(SCIP *sourcescip, SCIP_Bool *success)
Definition scip_copy.c:3250
SCIP_RETCODE SCIPcopyCuts(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
Definition scip_copy.c:2114
SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
Definition scip_copy.c:3293
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:2351
int SCIPgetNSols(SCIP *scip)
Definition scip_sol.c:2887
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition scip_sol.c:3128
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:4017
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition scip_sol.c:1890
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:24300
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition var.c:23932
SCIP_CLIQUE ** SCIPgetCliques(SCIP *scip)
Definition scip_var.c:9566
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23299
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:24266
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:88
#define DEFAULT_NODESOFS
Definition heur_clique.c:94
#define DEFAULT_MINMIPFIXINGRATE
Definition heur_clique.c:89
#define DEFAULT_MAXBACKTRACKS
Definition heur_clique.c:97
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:163
SCIP_RETCODE SCIPapplyLockFixings(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_Bool *cutoff, SCIP_Bool *allrowsfulfilled)
Definition heur_locks.c:194
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
@ SCIP_INVALIDCALL
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