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