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