Scippy

SCIP

Solving Constraint Integer Programs

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-2025 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file heur_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? */
163 if( SCIPvarGetUbLocal(var) > SCIPvarGetLbLocal(var) + 0.5 )
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;
191 SCIP_Real obj;
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 */
292 if( SCIPvarGetUbLocal(var) < SCIPvarGetLbLocal(var) + 0.5 )
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 {
337 SCIP_CALL( SCIPfixVarProbing(scip, var, 0.0) );
338 }
339 else
340 {
341 SCIP_CALL( SCIPfixVarProbing(scip, var, 1.0) );
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
371 if( SCIPvarGetUbLocal(var) < SCIPvarGetLbLocal(var) + 0.5 )
372 continue;
373
374 if( cliquevals[v] )
375 {
376 SCIP_CALL( SCIPfixVarProbing(scip, var, 0.0) );
377 }
378 else
379 {
380 SCIP_CALL( SCIPfixVarProbing(scip, var, 1.0) );
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 */
412 SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, cutoff, NULL) );
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 */
446 SCIP_CALL( SCIPpropagateProbing(scip, heurdata->maxproprounds, cutoff, NULL) );
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}*/
535 SCIP_HEURDATA* heurdata;
536
537 assert(heur != NULL);
538 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
539 assert(scip != NULL);
540
541 /* free heuristic data */
542 heurdata = SCIPheurGetData(heur);
543 assert(heurdata != NULL);
544
545 SCIPfreeBlockMemory(scip, &heurdata);
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}*/
556 SCIP_HEURDATA* heurdata;
557
558 assert(heur != NULL);
559 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
560 assert(scip != NULL);
561
562 /* reset heuristic data */
563 heurdata = SCIPheurGetData(heur);
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}*/
575 SCIP_HEURDATA* heurdata;
576 SCIP_VAR** vars;
577 SCIP_Real lowerbound;
578 int nvars;
579 int nbinvars;
580 int oldnpscands;
581 int npscands;
582 int i;
583 SCIP_Bool cutoff;
584 SCIP_Bool lperror;
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
602 *result = SCIP_DIDNOTRUN;
603
604 /* get heuristic's data */
605 heurdata = SCIPheurGetData(heur);
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 {
654 SCIP_CALL( SCIPconstructLP(scip, &cutoff) );
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
673 *result = SCIP_DIDNOTFIND;
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
776 SCIP_CALL( SCIPsolveProbingLP(scip, -1, &lperror, NULL) );
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",
806 SCIPgetSolOrigObj(scip, sol));
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
815 SCIP_CALL( SCIPtrySol(scip, sol, FALSE, FALSE, TRUE, FALSE, FALSE, &stored) );
816#endif
817
818 if( stored )
819 {
820 SCIPdebugMsg(scip, "found feasible solution:\n");
822 *result = SCIP_FOUNDSOL;
823 }
824
825 SCIP_CALL( SCIPfreeSol(scip, &sol) );
826
827 /* we found a solution, so we are done */
828 goto TERMINATE;
829 }
830
831 SCIP_CALL( SCIPfreeSol(scip, &sol) );
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;
872 SCIP_Bool valid;
873
874 /* check whether there is enough time and memory left */
876
877 if( !valid )
878 goto TERMINATE;
879
880 /* get all variables */
881 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
882
883 /* create subproblem */
884 SCIP_CALL( SCIPcreate(&subscip) );
885
886 /* allocate temporary memory for subscip variables */
887 SCIP_CALL( SCIPallocBufferArray(scip, &subvars, nvars) );
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 )
1000 *result = SCIP_FOUNDSOL;
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{
1070 SCIP_HEURDATA* heurdata;
1071 SCIP_HEUR* heur;
1072
1073 /* create clique primal heuristic data */
1074 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
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}
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
#define NULL
Definition: def.h:248
#define SCIP_MAXSTRLEN
Definition: def.h:269
#define SCIP_Longint
Definition: def.h:141
#define SCIP_MAXTREEDEPTH
Definition: def.h:297
#define SCIP_Shortbool
Definition: def.h:99
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:224
#define SCIP_Real
Definition: def.h:156
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIP_CALL_ABORT(x)
Definition: def.h:334
#define SCIP_LONGINT_FORMAT
Definition: def.h:148
#define SCIP_LONGINT_MAX
Definition: def.h:142
#define SCIP_CALL(x)
Definition: def.h:355
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)
Definition: scip_general.c:759
SCIP_RETCODE SCIPfree(SCIP **scip)
Definition: scip_general.c:402
SCIP_RETCODE SCIPcreate(SCIP **scip)
Definition: scip_general.c:370
SCIP_STATUS SCIPgetStatus(SCIP *scip)
Definition: scip_general.c:562
int SCIPgetNContVars(SCIP *scip)
Definition: scip_prob.c:2569
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,...)
Definition: scip_message.c:225
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:250
SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:111
SCIP_Bool SCIPisParamFixed(SCIP *scip, const char *name)
Definition: scip_param.c:219
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:83
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
Definition: scip_param.c:545
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:139
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
Definition: scip_param.c:487
SCIP_RETCODE SCIPsetSubscipsOff(SCIP *scip, SCIP_Bool quiet)
Definition: scip_param.c:904
SCIP_RETCODE SCIPsetPresolving(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip_param.c:956
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:57
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
Definition: scip_param.c:429
SCIP_RETCODE SCIPsetSeparating(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
Definition: scip_param.c:985
SCIP_RETCODE SCIPincludeHeurClique(SCIP *scip)
Definition: heur_clique.c:1066
SCIP_BRANCHRULE * SCIPfindBranchrule(SCIP *scip, const char *name)
Definition: scip_branch.c:304
int SCIPgetNPseudoBranchCands(SCIP *scip)
Definition: scip_branch.c:766
SCIP_Bool SCIPisCertified(SCIP *scip)
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1173
SCIP_RETCODE SCIPsetHeurCopy(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURCOPY((*heurcopy)))
Definition: scip_heur.c:167
SCIP_HEURDATA * SCIPheurGetData(SCIP_HEUR *heur)
Definition: heur.c:1368
SCIP_RETCODE SCIPincludeHeurBasic(SCIP *scip, SCIP_HEUR **heur, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
Definition: scip_heur.c:122
SCIP_RETCODE SCIPsetHeurFree(SCIP *scip, SCIP_HEUR *heur, SCIP_DECL_HEURFREE((*heurfree)))
Definition: scip_heur.c:183
SCIP_Longint SCIPheurGetNBestSolsFound(SCIP_HEUR *heur)
Definition: heur.c:1613
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, SCIP_DECL_HEURINIT((*heurinit)))
Definition: scip_heur.c:199
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1467
void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
Definition: heur.c:1378
SCIP_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)
Definition: scip_probing.c:199
char * SCIPsnprintfProbingStats(SCIP *scip, char *strbuf, int len)
SCIP_RETCODE SCIPpropagateProbing(SCIP *scip, int maxproprounds, SCIP_Bool *cutoff, SCIP_Longint *ndomredsfound)
Definition: scip_probing.c:581
SCIP_RETCODE SCIPbacktrackProbing(SCIP *scip, int probingdepth)
Definition: scip_probing.c:226
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:98
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
Definition: scip_probing.c:120
SCIP_RETCODE SCIPnewProbingNode(SCIP *scip)
Definition: scip_probing.c:166
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
Definition: scip_probing.c:825
SCIP_RETCODE SCIPfixVarProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval)
Definition: scip_probing.c:419
SCIP_RETCODE SCIPendProbing(SCIP *scip)
Definition: scip_probing.c:261
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
Definition: scip_sol.c:516
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
Definition: scip_sol.c:1252
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition: scip_sol.c:2349
int SCIPgetNSols(SCIP *scip)
Definition: scip_sol.c:2882
SCIP_RETCODE SCIProundSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *success)
Definition: scip_sol.c:3123
SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
Definition: scip_sol.c:4012
SCIP_RETCODE SCIPlinkLPSol(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1295
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
Definition: scip_sol.c:1892
SCIP_RETCODE SCIPpresolve(SCIP *scip)
Definition: scip_solve.c:2449
SCIP_RETCODE SCIPsolve(SCIP *scip)
Definition: scip_solve.c:2635
SCIP_Real SCIPgetUpperbound(SCIP *scip)
SCIP_Longint SCIPgetNNodes(SCIP *scip)
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
SCIP_Real SCIPgetLowerbound(SCIP *scip)
SCIP_Longint SCIPgetNLPIterations(SCIP *scip)
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
Definition: scip_timing.c:378
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 DEFAULT_MININTFIXINGRATE
Definition: heur_clique.c:89
#define DEFAULT_NODESQUOT
Definition: heur_clique.c:96
#define DEFAULT_NODESOFS
Definition: heur_clique.c:95
#define DEFAULT_COPYCUTS
Definition: heur_clique.c:99
#define DEFAULT_MAXNODES
Definition: heur_clique.c:88
#define HEUR_TIMING
Definition: heur_clique.c:85
#define DEFAULT_MINNODES
Definition: heur_clique.c:94
static SCIP_DECL_SORTINDCOMP(compCliquesSize)
Definition: heur_clique.c:137
#define HEUR_FREQOFS
Definition: heur_clique.c:83
#define HEUR_DESC
Definition: heur_clique.c:79
static SCIP_DECL_HEURCOPY(heurCopyClique)
Definition: heur_clique.c:519
#define HEUR_DISPCHAR
Definition: heur_clique.c:80
#define HEUR_MAXDEPTH
Definition: heur_clique.c:84
#define HEUR_PRIORITY
Definition: heur_clique.c:81
static SCIP_DECL_HEURINIT(heurInitClique)
Definition: heur_clique.c:554
#define DEFAULT_MINIMPROVE
Definition: heur_clique.c:92
#define HEUR_NAME
Definition: heur_clique.c:78
#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)
Definition: heur_clique.c:172
static SCIP_DECL_HEUREXEC(heurExecClique)
Definition: heur_clique.c:573
static int getCliqueUnfixedVars(SCIP_CLIQUE *clique)
Definition: heur_clique.c:145
#define HEUR_FREQ
Definition: heur_clique.c:82
#define HEUR_USESSUBSCIP
Definition: heur_clique.c:86
#define DEFAULT_USELOCKFIXINGS
Definition: heur_clique.c:101
#define DEFAULT_MAXPROPROUNDS
Definition: heur_clique.c:97
static SCIP_DECL_HEURFREE(heurFreeClique)
Definition: heur_clique.c:533
LNS heuristic using a clique partition to restrict the search neighborhood.
SCIP_RETCODE SCIPapplyLockFixings(SCIP *scip, SCIP_HEURDATA *heurdata, SCIP_Bool *cutoff, SCIP_Bool *allrowsfulfilled)
Definition: heur_locks.c:191
locks primal heuristic
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)
Definition: pub_message.h:102
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
Definition: type_conflict.h:62
@ SCIP_CONFTYPE_INFEASLP
Definition: type_conflict.h:63
struct SCIP_HeurData SCIP_HEURDATA
Definition: type_heur.h:77
enum SCIP_LPSolStat SCIP_LPSOLSTAT
Definition: type_lp.h:52
@ SCIP_LPSOLSTAT_ERROR
Definition: type_lp.h:50
@ SCIP_LPSOLSTAT_OPTIMAL
Definition: type_lp.h:44
@ SCIP_LPSOLSTAT_INFEASIBLE
Definition: type_lp.h:45
@ SCIP_LPSOLSTAT_OBJLIMIT
Definition: type_lp.h:47
@ SCIP_VERBLEVEL_FULL
Definition: type_message.h:62
@ SCIP_PARAMSETTING_OFF
Definition: type_paramset.h:63
@ SCIP_PARAMSETTING_FAST
Definition: type_paramset.h:62
@ SCIP_DIDNOTRUN
Definition: type_result.h:42
@ SCIP_DIDNOTFIND
Definition: type_result.h:44
@ SCIP_FOUNDSOL
Definition: type_result.h:56
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_STATUS_INFEASIBLE
Definition: type_stat.h:44