Scippy

    SCIP

    Solving Constraint Integer Programs

    heur_dks.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file heur_dks.c
    26 * @ingroup DEFPLUGINS_HEUR
    27 * @brief dks primal heuristic
    28 * @author Adrian Göß
    29 * @author Dieter Weninger
    30 *
    31 * Primal heuristic based on ideas published in the paper
    32 * "Exploiting user-supplied Decompositions inside Heuristics" by Katrin Halbig, Adrian Göß and Dieter Weninger.
    33 */
    34
    35/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+--*/
    36
    37#include "scip/pub_lp.h"
    39#include "scip/cons_linear.h"
    40#include "scip/debug.h"
    41#include "scip/heuristics.h"
    42#include "scip/pub_cons.h"
    43#include "scip/pub_event.h"
    44#include "scip/pub_fileio.h"
    45#include "scip/pub_tree.h"
    46#include "scip/pub_heur.h"
    47#include "scip/pub_message.h"
    48#include "scip/pub_misc.h"
    50#include "scip/pub_sol.h"
    51#include "scip/pub_var.h"
    52#include "scip/scipdefplugins.h"
    53#include "scip/scip_branch.h"
    54#include "scip/scip_cons.h"
    55#include "scip/scip_copy.h"
    56#include "scip/scip_dcmp.h"
    57#include "scip/scip_event.h"
    58#include "scip/scip_general.h"
    59#include "scip/scip_heur.h"
    60#include "scip/scip_lp.h"
    61#include "scip/scip_mem.h"
    62#include "scip/scip_message.h"
    63#include "scip/scip_nodesel.h"
    64#include "scip/scip_numerics.h"
    65#include "scip/scip_param.h"
    66#include "scip/scip_prob.h"
    68#include "scip/scip_sol.h"
    69#include "scip/scip_solve.h"
    71#include "scip/scip_table.h"
    72#include "scip/scip_timing.h"
    73#include "scip/scip_tree.h"
    74#include "scip/scip_var.h"
    75#include "scip/sol.h"
    76#include "scip/heur_dks.h"
    77
    78
    79#define HEUR_NAME "dks"
    80#define HEUR_DESC "decomposition kernel search"
    81#define HEUR_DISPCHAR 'D'
    82#define HEUR_PRIORITY -1102500
    83#define HEUR_FREQ -1
    84#define HEUR_FREQOFS 0
    85#define HEUR_MAXDEPTH 0
    86#define HEUR_TIMING SCIP_HEURTIMING_AFTERLPNODE
    87#define HEUR_USESSUBSCIP TRUE /**< does the heuristic use a secondary SCIP instance? */
    88
    89#define DEFAULT_MAXBUCKS 20 /**< default value for the number of buckets to investigate */
    90#define DEFAULT_KERNELSIZEFACTOR 2.0 /**< default value for the maximal growing of the kernel size */
    91#define DEFAULT_ADDUSECONSS TRUE /**< default value to add a use constraint */
    92#define DEFAULT_LINKBUCKSIZE TRUE /**< default value to respect kernel linking vars for the bucket size */
    93#define DEFAULT_TRANSLBKERNEL TRUE /**< default value to respect the diff of var lb in trans and orig prob */
    94#define DEFAULT_LESSLOCKSKERNEL FALSE /**< default value to respect <= 1 up- & downlock in kernel construction */
    95#define DEFAULT_USETRANSPROB TRUE /**< default value to use the original or transformed problem **/
    96#define DEFAULT_BUCKMAXGAP 0.01 /**< default value for the maximal mip gap of a bucket */
    97#define DEFAULT_MAXLINKSCORE 1.0 /**< default value for the maximal linking score of an instance */
    98#define DEFAULT_MAXBUCKFRAC 0.10 /**< default value to respect buckets with <= this share of bin/int vars */
    99#define DEFAULT_MAXNODES 5000LL /**< default node limit of the heuristic */
    100#define DEFAULT_USETWOLEVEL TRUE /**< default value to use a two level structure for the buckets */
    101#define DEFAULT_USEDECOMP TRUE /**< default value to use the decomp if given */
    102#define DEFAULT_USEBESTSOL TRUE /**< default value to use the best existing solution or the lp solution */
    103#define DEFAULT_REDCOSTSORT TRUE /**< default value to sort the non kernel vars before bucket split */
    104#define DEFAULT_PRIMALONLY FALSE /**< default value to kill dks after the first primal solution is found */
    105#define DEFAULT_REDCOSTLOGSORT TRUE /**< default value to sort non kernel vars logarithmically by redcost */
    106#define DEFAULT_OBJCUTOFF TRUE /**< default value to add an objective cutoff */
    107#define DEFAULT_RUNBINPROBSONLY FALSE /**< default value to run only for bin or bin + int only problems */
    108
    109/*
    110 * Data structures
    111 */
    112
    113/** data related to one bucket list, details see below **/
    114typedef struct Bucketlist BUCKETLIST;
    115
    116/** data related to one bucket **/
    117typedef struct Bucket
    118{
    119 BUCKETLIST* bucketlist; /**< the bucketlist the bucket belongs to */
    120 SCIP* subscip; /**< scip structure to solve smaller MIPs later */
    121 int number; /**< component number */
    122 SCIP_VAR** contbucketvars; /**< continuous variables for this bucket */
    123 SCIP_VAR** bucketvars; /**< variables of this bucket, just binary if 2-level bucket */
    124 SCIP_VAR** intbucketvars; /**< just integer variables if 2-level bucket */
    125 int ncontbucketvars; /**< amount of continuous variables in this bucket */
    126 int nbucketvars; /**< amount of variables in this bucket */
    127 int nintbucketvars; /**< amount of integer variables in a 2-level bucket */
    128 SCIP_Bool twolevel; /**< is the current bucket a 2-level one */
    129 SCIP_VAR** sub2scip; /**< mapping the variables to the original ones */
    130 SCIP_VAR** scip2sub; /**< mapping original variables to subscip ones */
    132
    133/** data related to one whole list of buckets **/
    135{
    136 SCIP* scip; /**< scip instance this bucketlist belongs to */
    137 BUCKET* buckets; /**< buckets in this bucketlist */
    138 int nbuckets; /**< amount of buckets in this bucketlist */
    139};
    140
    141/** primal heuristic data */
    142struct SCIP_HeurData
    143{
    144 int maxbucks; /**< maximum amount of buckets that are investigated */
    145 SCIP_Real kernelsizefactor; /**< factor with which initial kernel can grow max */
    146 SCIP_Bool addUseConss; /**< add a constraint that ensures a use of the bucket variables or not */
    147 SCIP_Bool linkbucksize; /**< respect the kernel linking variables for the initial bucket size */
    148 SCIP_Bool translbkernel; /**< respect the variable's lb in transprob at kernel construction */
    149 SCIP_Bool lesslockskernel; /**< respect variables with <= 1 up & downlock at kernel construction */
    150 SCIP_Bool usetransprob; /**< use the transformed problem instead of the original one */
    151 SCIP_Real buckmaxgap; /**< set an upper bound for the maximum mip gap of each bucket */
    152 SCIP_Real maxlinkscore; /**< set an upper bound for the linking score to get solved by dks */
    153 SCIP_Real maxbuckfrac; /**< maximal share of int/bin variables for a bucket to be computed */
    154 SCIP_Longint maxnodes; /**< maximum number of nodes to regard in all subproblems */
    155 SCIP_Bool usetwolevel; /**< use two level structure for the buckets if possible */
    156 SCIP_Bool usedecomp; /**< use decomp if given */
    157 SCIP_Bool usebestsol; /**< use best solution or alt. LP sol */
    158 SCIP_Bool redcostsort; /**< sort the non kernel variables by reduced costs */
    159 SCIP_Bool primalonly; /**< terminate after the first found primal solution */
    160 SCIP_Bool redcostlogsort; /**< flag indicating logarithmically sorted reduced costs at bucket init */
    161 SCIP_Bool objcutoff; /**< add an objective cutoff for the current best sol */
    162 int ncalls; /**< amount of calls of the heuristic */
    163 SCIP_Bool runbinprobsonly; /**< flag indicating if executing only on bin/int problems */
    164 SCIP_Bool uselesscall; /**< flag indicating if DKS has been called once & not found a solution */
    165};
    166
    167
    168/*
    169 * Local methods
    170 */
    171
    172/** calculate the linking score of a given decomposition */
    173static
    175 int* blocklabels, /**< int array to store the different block labels */
    176 int* varlabels, /**< array of variable labels */
    177 int* conslabels, /**< array of constraint labels */
    178 SCIP_Real* linkscore, /**< linking score to return */
    179 int* nblocklabels, /**< number of block labels to return */
    180 int nblocks, /**< number of blocks */
    181 int nvars, /**< number of variables */
    182 int nconss /**< number of constraints */
    183 )
    184{
    185 int v;
    186 int b;
    187
    188 int nlinkscoreconss = 0; /* number of linking conss for calculation */
    189 int nlinkscorevars = 0; /* number of linking vars for calculation */
    190
    191 assert(nblocklabels != NULL);
    192
    193 *nblocklabels = 0; /* number of distinct block labels */
    194
    195 for( v = 0; v < nvars; v++ )
    196 {
    197 assert(varlabels != NULL);
    198
    199 /* counting of linking variables */
    200 if( varlabels[v] == SCIP_DECOMP_LINKVAR )
    201 nlinkscorevars++;
    202 /* fill an array for the existing distinct block labels that are not linking variables */
    203 else if( *nblocklabels < nblocks && blocklabels != NULL )
    204 {
    205 SCIP_Bool newlabel = TRUE; /* indication of finding a new label */
    206
    207 /* check the current label for novelty */
    208 for( b = 0; b < *nblocklabels; b++ )
    209 {
    210 if( blocklabels[b] == varlabels[v] )
    211 {
    212 newlabel = FALSE;
    213 break;
    214 }
    215 }
    216
    217 /* add unseen labels */
    218 if( newlabel )
    219 blocklabels[(*nblocklabels)++] = varlabels[v];
    220 }
    221 }
    222
    223 /* counting of linking constraints */
    224 for( v = 0; v < nconss; v++ )
    225 {
    226 assert(conslabels != NULL);
    227 if( conslabels[v] == SCIP_DECOMP_LINKCONS )
    228 nlinkscoreconss++;
    229 }
    230
    231 /* linking score calculation */
    232 *linkscore = ( (SCIP_Real)nlinkscorevars*(SCIP_Real)nconss + (SCIP_Real)nlinkscoreconss*(SCIP_Real)nvars -
    233 (SCIP_Real)nlinkscorevars*(SCIP_Real)nlinkscoreconss ) / ((SCIP_Real)nconss*(SCIP_Real)nvars);
    234
    235 return SCIP_OKAY;
    236}
    237
    238/** count of potential kernel variables for one level or two level structure */
    239static
    241 SCIP* scip, /**< main SCIP data structure */
    242 SCIP_VAR** vars, /**< array of variables */
    243 SCIP_SOL* bestcurrsol, /**< best current solution */
    244 SCIP_HASHMAP* lbvarmap, /**< original lower bound of transformed variables */
    245 SCIP_Bool twolevel, /**< usage of one or two level structure */
    246 SCIP_Bool usebestsol, /**< usage of best or lp solution */
    247 SCIP_Bool usetransprob, /**< usage of transformed or original problem */
    248 SCIP_Bool usetranslb, /**< usage of transformed lb in comparison to original lb */
    249 int* bw_ncontkernelvars, /**< blockwise number of continuous kernel variables */
    250 int* bw_ncontnonkernelvars, /**< blockwise number of continuous non-kernel variables */
    251 int* bw_nkernelvars, /**< blockwise number of (binary) kernel variables */
    252 int* bw_nnonkernelvars, /**< blockwise number of (binary) non-kernel variables */
    253 int* bw_nintkernelvars, /**< blockwise number of integer kernel variables */
    254 int* bw_nintnonkernelvars, /**< blockwise number of integer non-kernel variables */
    255 int* ncontkernelvars, /**< number of continuous kernel variables */
    256 int* ncontnonkernelvars, /**< number of continuous non-kernel variables */
    257 int* nkernelvars, /**< number of (binary) kernel variables */
    258 int* nnonkernelvars, /**< number of (binary) non-kernel variables */
    259 int* nintkernelvars, /**< number of integer kernel variables */
    260 int* nintnonkernelvars, /**< number of integer non-kernel variables */
    261 int* block2index, /**< mapping of block labels to block index */
    262 int* varlabels, /**< array of variable labels */
    263 int blklbl_offset, /**< optional offset for the blocklabels, if it exists a block 0 */
    264 int nvars /**< number of variables */
    265 )
    266{
    267 SCIP_Real lpval; /* variable value in LP solution */
    268 SCIP_Real lb;
    269 SCIP_Real lborig;
    270 int i;
    271 int block;
    272
    273 assert(bw_ncontkernelvars != NULL);
    274 assert(bw_ncontnonkernelvars != NULL);
    275 assert(bw_nkernelvars != NULL);
    276 assert(bw_nnonkernelvars != NULL);
    277
    278 assert(ncontkernelvars != NULL);
    279 assert(ncontnonkernelvars != NULL);
    280 assert(nkernelvars != NULL);
    281 assert(nnonkernelvars != NULL);
    282
    283 /* count all possible kernel variables dependent on their type blockwise and overall */
    284 for( i = 0; i < nvars; i++ )
    285 {
    286 /* calculate the variable's LP solution value, the lower bound in the transformed and original problem */
    287 lpval = usebestsol ? SCIPgetSolVal(scip, bestcurrsol, vars[i]) : SCIPvarGetLPSol(vars[i]);
    288 lb = SCIPvarGetLbLocal(vars[i]);
    289 lborig = usetransprob ? SCIPhashmapGetImageReal(lbvarmap, vars[i]) : SCIPvarGetLbOriginal(vars[i]);
    290
    291 /* definition of the variable's block (SCIP_DECOMP_LINKVAR = -1, but is stored as 0) */
    292 block = block2index[MAX(varlabels[i] + blklbl_offset, 0)];
    293
    294 switch( SCIPvarGetType(vars[i]) )
    295 {
    296 /* compare binaries only to the lower bound of 0.0 and count as kernel or non-kernel variable */
    298 if( !SCIPisEQ(scip, lpval, 0.0) )
    299 {
    300 (*nkernelvars)++;
    301 bw_nkernelvars[block]++;
    302 }
    303 else
    304 {
    305 (*nnonkernelvars)++;
    306 bw_nnonkernelvars[block]++;
    307 }
    308 break;
    309
    310 /* LP value > lb -> count integer as kernel variable else not */
    311 /* count separatly if binaries and integers are present */
    313 if( (!SCIPisEQ(scip, lpval, 0.0) && !SCIPisEQ(scip, lpval, lb))
    314 || (usetranslb && SCIPisGT(scip, lb, lborig)) )
    315 {
    316 if( twolevel )
    317 {
    318 if( nintkernelvars != NULL )
    319 (*nintkernelvars)++;
    320 if( bw_nintkernelvars != NULL )
    321 bw_nintkernelvars[block]++;
    322 }
    323 else
    324 {
    325 (*nkernelvars)++;
    326 bw_nkernelvars[block]++;
    327 }
    328 }
    329 else
    330 {
    331 if( twolevel )
    332 {
    333 if( nintnonkernelvars != NULL )
    334 (*nintnonkernelvars)++;
    335 if( bw_nintnonkernelvars != NULL )
    336 bw_nintnonkernelvars[block]++;
    337 }
    338 else
    339 {
    340 (*nnonkernelvars)++;
    341 bw_nnonkernelvars[block]++;
    342 }
    343 }
    344 break;
    345
    346 /* LP value > lower bound -> potential kernel variable else not for continuous vars */
    348 default:
    349 if( (!SCIPisEQ(scip, lpval, 0.0) && !SCIPisEQ(scip, lpval, lb) )
    350 || (usetranslb && SCIPisGT(scip, lb, lborig)) )
    351 {
    352 (*ncontkernelvars)++;
    353 bw_ncontkernelvars[block]++;
    354 }
    355 else
    356 {
    357 (*ncontnonkernelvars)++;
    358 bw_ncontnonkernelvars[block]++;
    359 }
    360 break;
    361 } /*lint !e788*/
    362 }
    363
    364 return SCIP_OKAY;
    365}
    366
    367/** fill the blockwise kernels with the respective variables */
    368static
    370 SCIP* scip, /**< main SCIP data structure */
    371 SCIP_VAR** vars, /**< array of variables */
    372 SCIP_VAR** binintvars, /**< array of binary and integer variables */
    373 SCIP_VAR*** bw_contkernelvars, /**< blockwise array of continuous kernel variables */
    374 SCIP_VAR*** bw_contnonkernelvars, /**< blockwise array of continuous non-kernel variables */
    375 SCIP_VAR*** bw_kernelvars, /**< blockwise array of (binary) kernel variables */
    376 SCIP_VAR*** bw_nonkernelvars, /**< blockwise array of (binary) non-kernel variables */
    377 SCIP_VAR*** bw_intkernelvars, /**< blockwise array of integer kernel variables */
    378 SCIP_VAR*** bw_intnonkernelvars, /**< blockwise array of integer non-kernel variables */
    379 SCIP_SOL* bestcurrsol, /**< best current solution */
    380 SCIP_HASHMAP* lbvarmap, /**< original lower bound of transformed variables */
    381 SCIP_Bool twolevel, /**< usage of one or two level structure */
    382 SCIP_Bool usebestsol, /**< usage of best or lp solution */
    383 SCIP_Bool usetransprob, /**< usage of transformed or original problem */
    384 SCIP_Bool usetranslb, /**< usage of transformed lb in comparison to original lb */
    385 int* bw_contkernelcount, /**< blockwise counter of continuous kernel variables */
    386 int* bw_contnonkernelcount, /**< blockwise counter of continuous non-kernel variables */
    387 int* bw_kernelcount, /**< blockwise counter of (binary) kernel variables */
    388 int* bw_nonkernelcount, /**< blockwise counter of (binary) non-kernel variables */
    389 int* bw_intkernelcount, /**< blockwise counter of integer kernel variables */
    390 int* bw_intnonkernelcount, /**< blockwise counter of integer non-kernel variables */
    391 int* bw_ncontkernelvars, /**< blockwise number of continuous kernel variables */
    392 int* bw_ncontnonkernelvars, /**< blockwise number of continuous non-kernel variables */
    393 int* bw_nkernelvars, /**< blockwise number of (binary) kernel variables */
    394 int* bw_nnonkernelvars, /**< blockwise number of (binary) non-kernel variables */
    395 int* bw_nintkernelvars, /**< blockwise number of integer kernel variables */
    396 int* bw_nintnonkernelvars, /**< blockwise number of integer non-kernel variables */
    397 int* block2index, /**< mapping of block labels to block index */
    398 int* varlabels, /**< array of variable labels */
    399 int blklbl_offset, /**< optional offset for the blocklabels, if it exists a block 0 */
    400 int nvars, /**< number of variables */
    401 int nbinintvars /**< number of binary and integer variables */
    402 )
    403{
    404 SCIP_Real lpval; /* variable value in LP solution */
    405 SCIP_Real lb;
    406 SCIP_Real lborig;
    407 int i; /* variable counter */
    408 int j = 0; /* integer and binary variable counter */
    409 int m; /* temporary integer variable index */
    410 int n; /* temporary (binary) variable index */
    411 int l; /* temporary continuous variable index */
    412 int block_index;
    413
    414 assert(bw_contkernelvars != NULL);
    415 assert(bw_contnonkernelvars != NULL);
    416 assert(bw_kernelvars != NULL);
    417 assert(bw_nonkernelvars != NULL);
    418 assert(bw_contkernelcount != NULL);
    419 assert(bw_contnonkernelcount != NULL);
    420 assert(bw_kernelcount != NULL);
    421 assert(bw_nonkernelcount != NULL);
    422
    423 /* assign all variables dependent on their type blockwise to a kernel or a non-kernel */
    424 for( i = 0; i < nvars; i++ )
    425 {
    426 /* calculate the variable's LP solution value, the lower bound in the transformed and original problem */
    427 lpval = usebestsol ? SCIPgetSolVal(scip, bestcurrsol, vars[i]) : SCIPvarGetLPSol(vars[i]);
    428 lb = SCIPvarGetLbLocal(vars[i]);
    429 lborig = usetransprob ? SCIPhashmapGetImageReal(lbvarmap, vars[i]) : SCIPvarGetLbOriginal(vars[i]);
    430
    431 /* definition of the variable's block index (SCIP_DECOMP_LINKVAR = -1, but is stored as 0 in block2index) */
    432 block_index = block2index[MAX(varlabels[i] + blklbl_offset, 0)];
    433
    434 switch( SCIPvarGetType(vars[i]) )
    435 {
    436 /* compare binaries only to the lower bound of 0.0 and add to kernel or non-kernel variables */
    438 /* adding the variable to the binary and integer variable array */
    439 assert(j < nbinintvars);
    440 binintvars[j++] = vars[i];
    441
    442 if( !SCIPisEQ(scip, lpval, 0.0) )
    443 {
    444 n = bw_kernelcount[block_index];
    445 assert(bw_nnonkernelvars != NULL);
    446 assert(n < bw_nkernelvars[block_index] + bw_nnonkernelvars[block_index]);
    447 bw_kernelvars[block_index][n] = vars[i];
    448 bw_kernelcount[block_index]++;
    449 }
    450 else
    451 {
    452 n = bw_nonkernelcount[block_index];
    453 assert(bw_nnonkernelvars != NULL);
    454 assert(n < bw_nkernelvars[block_index] + bw_nnonkernelvars[block_index]);
    455 bw_nonkernelvars[block_index][n] = vars[i];
    456 bw_nonkernelcount[block_index]++;
    457 }
    458 break;
    459
    460 /* LP value > lb -> integer kernel variable else non-kernel variable */
    461 /* count separatly if binaries and integers are present */
    463 /* adding the variable to the binary and integer variable array */
    464 assert(j < nbinintvars);
    465 binintvars[j++] = vars[i];
    466
    467 if( (!SCIPisEQ(scip, lpval, 0.0) && !SCIPisEQ(scip, lpval, lb))
    468 || (usetranslb && SCIPisGT(scip, lb, lborig)) )
    469 {
    470 if( twolevel )
    471 {
    472 if( bw_intkernelcount != NULL )
    473 {
    474 m = bw_intkernelcount[block_index];
    475 assert(bw_nintnonkernelvars != NULL);
    476 assert(bw_nintkernelvars != NULL);
    477 assert(m < bw_nintkernelvars[block_index] + bw_nintnonkernelvars[block_index]);
    478 if( bw_intkernelvars != NULL )
    479 bw_intkernelvars[block_index][m] = vars[i];
    480 bw_intkernelcount[block_index]++;
    481 }
    482 }
    483 else
    484 {
    485 m = bw_kernelcount[block_index];
    486 assert(bw_nnonkernelvars != NULL);
    487 assert(m < bw_nkernelvars[block_index] + bw_nnonkernelvars[block_index]);
    488 bw_kernelvars[block_index][m] = vars[i];
    489 bw_kernelcount[block_index]++;
    490 }
    491 }
    492 else
    493 {
    494 if( twolevel )
    495 {
    496 if( bw_intnonkernelcount != NULL )
    497 {
    498 m = bw_intnonkernelcount[block_index];
    499 assert(bw_nintnonkernelvars != NULL);
    500 assert(bw_nintkernelvars != NULL);
    501 assert(m < bw_nintkernelvars[block_index] + bw_nintnonkernelvars[block_index]);
    502 if( bw_intnonkernelvars != NULL )
    503 bw_intnonkernelvars[block_index][m] = vars[i];
    504 bw_intnonkernelcount[block_index]++;
    505 }
    506 }
    507 else
    508 {
    509 m = bw_nonkernelcount[block_index];
    510 assert(bw_nnonkernelvars != NULL);
    511 assert(m < bw_nkernelvars[block_index] + bw_nnonkernelvars[block_index]);
    512 bw_nonkernelvars[block_index][m] = vars[i];
    513 bw_nonkernelcount[block_index]++;
    514 }
    515 }
    516 break;
    517
    518 /* LP value > lower bound -> continuous kernel variable else non-kernel variable */
    520 default:
    521 if( (!SCIPisEQ(scip, lpval, 0.0) && !SCIPisEQ(scip, lpval, lb) )
    522 || (usetranslb && SCIPisGT(scip, lb, lborig)) )
    523 {
    524 l = bw_contkernelcount[block_index];
    525 assert(bw_ncontnonkernelvars != NULL);
    526 assert(l < bw_ncontkernelvars[block_index] + bw_ncontnonkernelvars[block_index]);
    527 bw_contkernelvars[block_index][l] = vars[i];
    528 bw_contkernelcount[block_index]++;
    529 }
    530 else
    531 {
    532 l = bw_contnonkernelcount[block_index];
    533 assert(bw_ncontnonkernelvars != NULL);
    534 assert(l < bw_ncontkernelvars[block_index] + bw_ncontnonkernelvars[block_index]);
    535 bw_contnonkernelvars[block_index][l] = vars[i];
    536 bw_contnonkernelcount[block_index]++;
    537 }
    538 break;
    539 } /*lint !e788*/
    540 }
    541
    542 return SCIP_OKAY;
    543}
    544
    545/** calculation of reduced costs and non-decreasing sorting **/
    546static
    548 SCIP* scip, /**< main SCIP data structure */
    549 SCIP_VAR*** bw_contnonkernelvars, /**< array pointer of continuous, non-kernel variables */
    550 SCIP_VAR*** bw_nonkernelvars, /**< array pointer of (binary,) non-kernel variables */
    551 SCIP_VAR*** bw_intnonkernelvars, /**< array pointer of integer, non-kernel variables */
    552 SCIP_Real*** bw_cont_redcost, /**< array pointer with reduced costs for continuous variables */
    553 SCIP_Real*** bw_redcost, /**< array pointer with reduced costs for (binary) variables */
    554 SCIP_Real*** bw_int_redcost, /**< array pointer with reduced costs for integer variables */
    555 int* bw_ncontnonkernelvars, /**< blockwise number of continuous, non-kernel variables */
    556 int* bw_nnonkernelvars, /**< blockwise number of (binary,) non-kernel variables */
    557 int* bw_nintnonkernelvars, /**< blockwise number of integer, non-kernel variables */
    558 SCIP_Bool twolevel, /**< usage of one or two level structure */
    559 int nblocks /**< number of blocks */
    560 )
    561{
    562 int b; /* block counter */
    563 int i; /* variable counter */
    564
    565 SCIP_CALL( SCIPallocBufferArray(scip, bw_cont_redcost, nblocks + 1) );
    566 SCIP_CALL( SCIPallocBufferArray(scip, bw_redcost, nblocks + 1) );
    567 if( twolevel )
    568 SCIP_CALL( SCIPallocBufferArray(scip, bw_int_redcost, nblocks + 1) );
    569
    570 /* blockwise and type-wise extraction of reduced costs and sorting in non-decreasing order */
    571 for( b = 0; b < nblocks + 1; b++ )
    572 {
    573 SCIP_CALL( SCIPallocBufferArray(scip, &((*bw_cont_redcost)[b]), bw_ncontnonkernelvars[b]) );
    574 SCIP_CALL( SCIPallocBufferArray(scip, &((*bw_redcost)[b]), bw_nnonkernelvars[b]) );
    575
    576 for( i = 0; i < bw_ncontnonkernelvars[b]; i++ )
    577 {
    578 (*bw_cont_redcost)[b][i] = SCIPgetVarRedcost(scip, bw_contnonkernelvars[b][i]);
    579 /* if a var is not in LP (SCIP_INVALID), we assign a reduced cost of zero & thus the var to an early bucket */
    580 if( (*bw_cont_redcost)[b][i] == SCIP_INVALID ) /*lint !e777*/
    581 (*bw_cont_redcost)[b][i] = 0.0;
    582 }
    583
    584 for( i = 0; i < bw_nnonkernelvars[b]; i++ )
    585 {
    586 (*bw_redcost)[b][i] = SCIPgetVarRedcost(scip, bw_nonkernelvars[b][i]);
    587 /* if a var is not in LP (SCIP_INVALID), we assign a reduced cost of zero & thus the var to an early bucket */
    588 if( (*bw_redcost)[b][i] == SCIP_INVALID ) /*lint !e777*/
    589 (*bw_redcost)[b][i] = 0.0;
    590 }
    591
    592 SCIPsortRealPtr((*bw_cont_redcost)[b], (void**)bw_contnonkernelvars[b], bw_ncontnonkernelvars[b]);
    593 SCIPsortRealPtr((*bw_redcost)[b], (void**)bw_nonkernelvars[b], bw_nnonkernelvars[b]);
    594
    595 if( twolevel )
    596 {
    597 SCIP_CALL( SCIPallocBufferArray(scip, &((*bw_int_redcost)[b]), bw_nintnonkernelvars[b]) );
    598
    599 for( i = 0; i < bw_nintnonkernelvars[b]; i++ )
    600 {
    601 (*bw_int_redcost)[b][i] = SCIPgetVarRedcost(scip, bw_intnonkernelvars[b][i]);
    602 /* if a var is not in LP (SCIP_INVALID), we assign a red cost of zero & thus the var to an early bucket */
    603 if( (*bw_int_redcost)[b][i] == SCIP_INVALID ) /*lint !e777*/
    604 (*bw_int_redcost)[b][i] = 0.0;
    605 }
    606
    607 SCIPsortRealPtr((*bw_int_redcost)[b], (void**)bw_intnonkernelvars[b], bw_nintnonkernelvars[b]);
    608 }
    609 }
    610
    611 return SCIP_OKAY;
    612}
    613
    614/** free memory of reduced cost arrays */
    615static
    617 SCIP* scip, /**< main SCIP data structure */
    618 SCIP_Real*** bw_cont_redcost, /**< array pointer with reduced costs for continuous variables */
    619 SCIP_Real*** bw_redcost, /**< array pointer with reduced costs for (binary) variables */
    620 SCIP_Real*** bw_int_redcost, /**< array pointer with reduced costs for integer variables */
    621 int nblocks /**< number of blocks */
    622 )
    623{
    624 int b;
    625
    626 /* type-wise and blockwise freeing of reduced cost arrays */
    627 if( *bw_cont_redcost != NULL )
    628 {
    629 for( b = 0; b < nblocks + 1; b++ )
    630 {
    631 if( (*bw_cont_redcost)[b] != NULL )
    632 SCIPfreeBufferArray(scip, &((*bw_cont_redcost)[b]));
    633 }
    634
    635 SCIPfreeBufferArray(scip, bw_cont_redcost);
    636 }
    637
    638 if( *bw_redcost != NULL )
    639 {
    640 for( b = 0; b < nblocks + 1; b++ )
    641 {
    642 if( (*bw_redcost)[b] != NULL )
    643 SCIPfreeBufferArray(scip, &((*bw_redcost)[b]));
    644 }
    645
    646 SCIPfreeBufferArray(scip, bw_redcost);
    647 }
    648
    649 if( *bw_int_redcost != NULL )
    650 {
    651 for( b = 0; b < nblocks + 1; b++ )
    652 {
    653 if( (*bw_int_redcost)[b] != NULL )
    654 SCIPfreeBufferArray(scip, &((*bw_int_redcost)[b]));
    655 }
    656
    657 SCIPfreeBufferArray(scip, bw_int_redcost);
    658 }
    659
    660 return SCIP_OKAY;
    661}
    662
    663/** determines affiliation to a redcost (logsorted) bucket, avoiding inf to inf comparison */
    664static
    666 SCIP* scip, /**< SCIP data structure */
    667 SCIP_Real base, /**< the nbuckets-th-root of the shifted max red costs in current bucket */
    668 SCIP_Real redcost, /**< the reduced cost of the current variable */
    669 SCIP_Real redcostmin, /**< the minimal reduced cost of the current block for shifting */
    670 int currentindex, /**< current iteration index */
    671 int nbuckets /**< number of buckets */
    672 )
    673{
    674 /* compute the reduced cost bounds for the current interval for logarithmic sorting */
    675 SCIP_Real redcostlb = pow(base, (double)(currentindex - 1));
    676 SCIP_Real redcostub = pow(base, (double)currentindex);
    677
    678 /* shift the current reduced cost for determining the membership to the current interval */
    679 SCIP_Real shifted_redcost = redcost - redcostmin + 1.0;
    680
    681 /* check whether the current reduced cost is in (min, max] */
    682 SCIP_Bool greatermincost = SCIPisGT(scip, shifted_redcost, redcostlb);
    683 SCIP_Bool lessequalmaxcost = SCIPisLE(scip, shifted_redcost, redcostub);
    684
    685 assert(base >= 1);
    686 assert(!SCIPisInfinity(scip, base));
    687
    688 /* respecting the edge cases, return the result */
    689 if( currentindex == 1 )
    690 /* there is no minimal reduced cost to respect */
    691 return lessequalmaxcost;
    692 else if ( currentindex == nbuckets )
    693 /* there is no maximal reduced cost to respect */
    694 return greatermincost;
    695 else
    696 /* both interval bounds must be respected */
    697 return greatermincost && lessequalmaxcost;
    698}
    699
    700/** fill bucket with its variables */
    701static
    703 SCIP* scip, /**< main SCIP data structure */
    704 BUCKETLIST** bucketlist, /**< array pointer of buckets to fill */
    705 SCIP_VAR*** bw_contnonkernelvars, /**< array of continuous, non-kernel variables */
    706 SCIP_VAR*** bw_nonkernelvars, /**< array of (binary,) non-kernel variables */
    707 SCIP_VAR*** bw_intnonkernelvars, /**< array of integer, non-kernel variables */
    708 int* bw_ncontnonkernelvars, /**< blockwise number of continuous, non-kernel variables */
    709 int* bw_nnonkernelvars, /**< blockwise number of (binary,) non-kernel variables */
    710 int* bw_nintnonkernelvars, /**< blockwise number of integer, non-kernel variables */
    711 SCIP_Real** bw_cont_redcost, /**< blockwise reduced costs of continuous, non-kernel variables */
    712 SCIP_Real** bw_redcost, /**< blockwise reduced costs of (binary,) non-kernel variables */
    713 SCIP_Real** bw_int_redcost, /**< blockwise reduced costs of integer, non-kernel variables */
    714 SCIP_Bool twolevel, /**< usage of one or two level structure */
    715 SCIP_Bool redcostlogsort, /**< filling the buckets by logarithmically reduced cost sort */
    716 int nbuckets, /**< number of buckets */
    717 int nblocks /**< number of blocks */
    718 )
    719{
    720 BUCKET* bucket; /* temporary bucket */
    721 int contbucklength; /* temporary length of the continuous bucket */
    722 int bucklength; /* temporary length of the (binary) bucket */
    723 int intbucklength; /* temporary length of the integer bucket */
    724 int fromcontvars; /* temporary start index for the variables of a continuous bucket */
    725 int tocontvars; /* temporary end index for the variables of a continuous bucket */
    726 int fromvars; /* temporary start index for the variables of a (binary) bucket */
    727 int tovars; /* temporary end index for the variables of a (binary) bucket */
    728 int fromintvars; /* temporary start index for the variables of a integer bucket */
    729 int tointvars; /* temporary end index for the variables of a integer bucket */
    730 int k; /* bucket counter */
    731 int b; /* block counter */
    732 int l; /* variable counter */
    733 int j; /* temporary continuous variable counter */
    734 int n; /* temporary (binary) variable counter */
    735 int m; /* temporary integer variable counter */
    736 SCIP_Real* contbases = NULL; /* blockwise the nbuckets-th-root of the max reduced costs of cont vars */
    737 SCIP_Real* bases = NULL; /* blockwise the nbuckets-th-root of the max reduced costs of (bin) vars */
    738 SCIP_Real* intbases = NULL; /* blockwise the nbuckets-th-root of the max reduced costs of int vars */
    739
    740 assert(nbuckets > 0);
    741
    742 /* when sorting logarithmically by reduced costs, get maximum per block and its shifted nbuckets-th-root */
    743 if( redcostlogsort )
    744 {
    745 SCIP_Real tmp_max;
    746 SCIP_Real tmp_min;
    747
    748 SCIP_CALL( SCIPallocBufferArray(scip, &contbases, nblocks + 1) );
    749 SCIP_CALL( SCIPallocBufferArray(scip, &bases, nblocks + 1) );
    750 if( twolevel )
    751 SCIP_CALL( SCIPallocBufferArray(scip, &intbases, nblocks + 1) );
    752
    753 for( b = 0; b < nblocks + 1; b++ )
    754 {
    755 if( bw_ncontnonkernelvars[b] > 0 )
    756 {
    757 /* reduced costs are not supposed to be +inf or -inf */
    758 tmp_max = bw_cont_redcost[b][bw_ncontnonkernelvars[b] - 1];
    759 tmp_min = bw_cont_redcost[b][0];
    760 assert(!(SCIPisInfinity(scip, tmp_max) || SCIPisInfinity(scip, -tmp_max)));
    761 assert(!(SCIPisInfinity(scip, tmp_min) || SCIPisInfinity(scip, -tmp_min)));
    762
    763 /* compute the nbuckets-th root of (redcostmax - redcostmin + 1.0) from the sorted(!) bw_cont_redcost[b] */
    764 contbases[b] = (SCIP_Real) pow(tmp_max - tmp_min + 1.0, 1.0/nbuckets);
    765 }
    766 else
    767 /* save -1.0 as placeholder */
    768 contbases[b] = -1.0;
    769
    770 if( bw_nnonkernelvars[b] > 0 )
    771 {
    772 /* reduced costs are not supposed to be +inf or -inf */
    773 tmp_max = bw_redcost[b][bw_nnonkernelvars[b] - 1];
    774 tmp_min = bw_redcost[b][0];
    775 assert(!(SCIPisInfinity(scip, tmp_max) || SCIPisInfinity(scip, -tmp_max)));
    776 assert(!(SCIPisInfinity(scip, tmp_min) || SCIPisInfinity(scip, -tmp_min)));
    777
    778 /* compute the nbuckets-th root of (redcostmax - redcostmin + 1.0) from the sorted(!) bw_cont_redcost[b] */
    779 bases[b] = (SCIP_Real) pow(tmp_max - tmp_min + 1.0, 1.0/nbuckets);
    780 }
    781 else
    782 /* save -1.0 as placeholder */
    783 bases[b] = -1.0;
    784
    785 if( twolevel )
    786 {
    787 if( bw_nintnonkernelvars[b] > 0 )
    788 {
    789 /* reduced costs are not supposed to be +inf or -inf */
    790 tmp_max = bw_int_redcost[b][bw_nintnonkernelvars[b] - 1];
    791 tmp_min = bw_int_redcost[b][0];
    792 assert(!(SCIPisInfinity(scip, tmp_max) || SCIPisInfinity(scip, -tmp_max)));
    793 assert(!(SCIPisInfinity(scip, tmp_min) || SCIPisInfinity(scip, -tmp_min)));
    794
    795 intbases[b] = (SCIP_Real) pow(tmp_max - tmp_min + 1.0, 1.0/nbuckets);
    796 }
    797 else
    798 /* save -1.0 as placeholder */
    799 intbases[b] = -1.0;
    800 }
    801 }
    802 }
    803
    804 /* iteration over all buckets to fill, k = 0 is empty bucket by definition */
    805 for( k = 1; k < nbuckets + 1; k++ )
    806 {
    807 bucket = &(*bucketlist)->buckets[k];
    808
    809 contbucklength = 0;
    810 bucklength = 0;
    811 intbucklength = 0;
    812
    813 /* calculate the length of the variable arrays for the current bucket typewise */
    814 for( b = 0; b < nblocks + 1; b++ )
    815 {
    816 if( redcostlogsort )
    817 {
    818 /* calculation of the variable array length for each type */
    819 for( l = 0; l < bw_ncontnonkernelvars[b]; l++ )
    820 {
    821 if( isInCurrentLogBucket(scip, contbases[b], bw_cont_redcost[b][l], bw_cont_redcost[b][0], k, nbuckets) )
    822 contbucklength++;
    823 }
    824
    825 for( l = 0; l < bw_nnonkernelvars[b]; l++ )
    826 {
    827 if( isInCurrentLogBucket(scip, bases[b], bw_redcost[b][l], bw_redcost[b][0], k, nbuckets) )
    828 bucklength++;
    829 }
    830
    831 if( twolevel )
    832 {
    833 for( l = 0; l < bw_nintnonkernelvars[b]; l++ )
    834 {
    835 if( isInCurrentLogBucket(scip, intbases[b], bw_int_redcost[b][l], bw_int_redcost[b][0], k, nbuckets) )
    836 intbucklength++;
    837 }
    838 }
    839 }
    840 else
    841 {
    842 /* initialize the start/end indices to split the non-kernel vars typewise and compute the bucket length */
    843 fromcontvars = (int)SCIPceil(scip, (bw_ncontnonkernelvars[b] / (SCIP_Real)nbuckets) * (k - 1) );
    844 tocontvars = (int)SCIPceil(scip, (bw_ncontnonkernelvars[b] / (SCIP_Real)nbuckets) * k );
    845 fromvars = (int)SCIPceil(scip, (bw_nnonkernelvars[b] / (SCIP_Real)nbuckets) * (k - 1) );
    846 tovars = (int)SCIPceil(scip, (bw_nnonkernelvars[b] / (SCIP_Real)nbuckets) * k );
    847
    848 contbucklength += tocontvars - fromcontvars;
    849 bucklength += tovars - fromvars;
    850
    851 if( twolevel )
    852 {
    853 fromintvars = (int)SCIPceil(scip, (bw_nintnonkernelvars[b] / (SCIP_Real)nbuckets) * (k - 1) );
    854 tointvars = (int)SCIPceil(scip, (bw_nintnonkernelvars[b] / (SCIP_Real)nbuckets) * k );
    855
    856 intbucklength += tointvars - fromintvars;
    857 }
    858 }
    859 }
    860
    861 /* initialize all buffer arrays for the continuous, binary/integer and (if necessary) integer bucket variables */
    862 SCIP_CALL( SCIPallocBufferArray(scip, &(bucket->contbucketvars), contbucklength) );
    863 bucket->ncontbucketvars = contbucklength;
    864 SCIP_CALL( SCIPallocBufferArray(scip, &(bucket->bucketvars), bucklength) );
    865 bucket->nbucketvars = bucklength;
    866 if( twolevel )
    867 {
    868 SCIP_CALL( SCIPallocBufferArray(scip, &(bucket->intbucketvars), intbucklength) );
    869 bucket->nintbucketvars = intbucklength;
    870 }
    871
    872 /* fill the initialized arrays with the respective variables */
    873 j = 0;
    874 n = 0;
    875 m = 0;
    876 for( b = 0; b < nblocks + 1; b++ )
    877 {
    878 if( redcostlogsort )
    879 {
    880 /* assignment of the variables to the respective bucket variable arrays for each type */
    881 for( l = 0; l < bw_ncontnonkernelvars[b]; l++ )
    882 {
    883 if( isInCurrentLogBucket(scip, contbases[b], bw_cont_redcost[b][l], bw_cont_redcost[b][0], k, nbuckets) )
    884 bucket->contbucketvars[j++] = bw_contnonkernelvars[b][l];
    885 }
    886
    887 for( l = 0; l < bw_nnonkernelvars[b]; l++ )
    888 {
    889 if( isInCurrentLogBucket(scip, bases[b], bw_redcost[b][l], bw_redcost[b][0], k, nbuckets) )
    890 bucket->bucketvars[n++] = bw_nonkernelvars[b][l];
    891 }
    892
    893 if( twolevel )
    894 {
    895 for( l = 0; l < bw_nintnonkernelvars[b]; l++ )
    896 {
    897 if( isInCurrentLogBucket(scip, intbases[b], bw_int_redcost[b][l], bw_int_redcost[b][0], k, nbuckets) )
    898 bucket->intbucketvars[m++] = bw_intnonkernelvars[b][l];
    899 }
    900 }
    901 }
    902 else
    903 {
    904 /* calculate again the necessary start and end indices to split the non-kernel variables typewise */
    905 fromcontvars = (int)SCIPceil(scip, (bw_ncontnonkernelvars[b] / (SCIP_Real)nbuckets) * (k - 1) );
    906 tocontvars = (int)SCIPceil(scip, (bw_ncontnonkernelvars[b] / (SCIP_Real)nbuckets) * k );
    907 fromvars = (int)SCIPceil(scip, (bw_nnonkernelvars[b] / (SCIP_Real)nbuckets) * (k - 1) );
    908 tovars = (int)SCIPceil(scip, (bw_nnonkernelvars[b] / (SCIP_Real)nbuckets) * k );
    909
    910 /* fill the variable arrays */
    911 for( l = 0; l < tocontvars - fromcontvars; l++ )
    912 bucket->contbucketvars[j++] = bw_contnonkernelvars[b][fromcontvars + l];
    913 for( l = 0; l < tovars - fromvars; l++ )
    914 bucket->bucketvars[n++] = bw_nonkernelvars[b][fromvars + l];
    915
    916 /* apply the procedure above for the integer variables if necessary */
    917 if( twolevel )
    918 {
    919 fromintvars = (int)SCIPceil(scip, (bw_nintnonkernelvars[b] / (SCIP_Real)nbuckets) * (k - 1) );
    920 tointvars = (int)SCIPceil(scip, (bw_nintnonkernelvars[b] / (SCIP_Real)nbuckets) * k );
    921
    922 for( l = 0; l < tointvars - fromintvars; l++ )
    923 bucket->intbucketvars[m++] = bw_intnonkernelvars[b][fromintvars + l];
    924 }
    925 }
    926 }
    927
    928 assert(j == contbucklength);
    929 assert(n == bucklength);
    930 if( twolevel )
    931 assert(m == intbucklength);
    932 }
    933
    934 if( redcostlogsort )
    935 {
    936 SCIPfreeBufferArray(scip, &contbases);
    937 SCIPfreeBufferArray(scip, &bases);
    938 if( twolevel )
    939 SCIPfreeBufferArray(scip, &intbases);
    940 }
    941
    942 return SCIP_OKAY;
    943}
    944
    945/** release memory of bucket arrays */
    946static
    948 SCIP* scip, /**< main SCIP data structure */
    949 BUCKET* bucket, /**< bucket to free the arrays from */
    950 SCIP_Bool twolevel /**< usage of one or two level structure */
    951 )
    952{
    953 if( bucket->contbucketvars != NULL )
    955 if( bucket->bucketvars != NULL )
    957 if( twolevel && bucket->intbucketvars != NULL )
    959
    960 return SCIP_OKAY;
    961}
    962
    963/** initialize a bucket */
    964static
    966 BUCKETLIST* bucketlist /**< bucketlist structure where the bucket belongs to */
    967 )
    968{
    969 BUCKET* bucket;
    970
    971 assert(bucketlist != NULL);
    972 assert(bucketlist->scip != NULL);
    973
    974 bucket = &bucketlist->buckets[bucketlist->nbuckets];
    975
    976 bucket->bucketlist = bucketlist;
    977 bucket->subscip = NULL;
    978 bucket->contbucketvars = NULL;
    979 bucket->bucketvars = NULL;
    980 bucket->intbucketvars = NULL;
    981 bucket->ncontbucketvars = 0;
    982 bucket->nbucketvars = 0;
    983 bucket->nintbucketvars = 0;
    984 bucket->number = bucketlist->nbuckets;
    985 bucket->twolevel = FALSE;
    986 bucket->scip2sub = NULL;
    987 bucket->sub2scip = NULL;
    988
    989 ++bucketlist->nbuckets;
    990
    991 return SCIP_OKAY;
    992}
    993
    994/** free bucket structure */
    995static
    997 SCIP* scip, /**< SCIP data structure */
    998 BUCKET* bucket /**< bucket structure to free */
    999 )
    1000{
    1001 assert(scip != NULL);
    1002 assert(bucket != NULL);
    1003
    1004 assert(bucket->subscip != NULL);
    1005
    1006 /* free variable mappings subscip -> scip and scip -> subscip */
    1009
    1010 SCIP_CALL( SCIPfree(&bucket->subscip) );
    1011 bucket->subscip = NULL;
    1012
    1013 return SCIP_OKAY;
    1014}
    1015
    1016/** initialize the bucketlist */
    1017static
    1019 SCIP* scip, /**< SCIP data structure */
    1020 BUCKETLIST** bucketlist, /**< pointer to bucketlist */
    1021 int nbuckets /**< number of buckets */
    1022 )
    1023{
    1024 char name[SCIP_MAXSTRLEN];
    1025
    1026 assert(scip != NULL);
    1027 assert(bucketlist != NULL);
    1028
    1029 SCIP_CALL( SCIPallocBlockMemory(scip, bucketlist) );
    1030 assert(*bucketlist != NULL);
    1031
    1032 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s", SCIPgetProbName(scip));
    1033
    1034 SCIPdebugMessage("initialized problem %s\n", name);
    1035
    1036 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &(*bucketlist)->buckets, nbuckets) );
    1037
    1038 (*bucketlist)->scip = scip;
    1039 (*bucketlist)->nbuckets = 0;
    1040
    1041 return SCIP_OKAY;
    1042}
    1043
    1044/** free bucketlist structure */
    1045static
    1047 BUCKETLIST** bucketlist, /**< pointer to bucketlist to free */
    1048 int nbuckets /**< number of buckets to free */
    1049 )
    1050{
    1051 SCIP* scip;
    1052
    1053 assert(bucketlist != NULL);
    1054 assert(*bucketlist != NULL);
    1055
    1056 scip = (*bucketlist)->scip;
    1057 assert(scip != NULL);
    1058
    1059 if( (*bucketlist)->buckets != NULL )
    1060 SCIPfreeBlockMemoryArray(scip, &(*bucketlist)->buckets, nbuckets);
    1061
    1062 SCIPfreeBlockMemory(scip, bucketlist);
    1063 *bucketlist = NULL;
    1064
    1065 return SCIP_OKAY;
    1066}
    1067
    1068/** creates the subscip for each bucket */
    1069static
    1071 BUCKET* bucket, /**< the bucket to create the subscip for */
    1072 SCIP_Bool usetransprob, /**< indicating whether the transformed or the original problem is used */
    1073 SCIP_Bool* success /**< pointer to store if the creation process was successfull */
    1074 )
    1075{
    1076 BUCKETLIST* bucketlist;
    1077 SCIP* scip;
    1078 SCIP_VAR** vars;
    1079 SCIP_VAR** subvars;
    1080 SCIP_VAR* var;
    1081 SCIP_VAR* subvar;
    1082 SCIP_HASHMAP* varsmap;
    1083 SCIP_HASHMAP* consmap;
    1084 char probname[SCIP_MAXSTRLEN];
    1085 int i;
    1086 int nvars;
    1087 int nsubvars;
    1088
    1089 SCIP_CONS** conss;
    1090 SCIP_CONS* newcons;
    1091
    1092 assert(bucket != NULL);
    1093 assert(success != NULL);
    1094
    1095 bucketlist = bucket->bucketlist;
    1096 assert(bucketlist != NULL);
    1097
    1098 scip = bucketlist->scip;
    1099 assert(scip != NULL);
    1100
    1101 /* start new creation process */
    1102 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
    1103
    1104 /* initializing the subproblem */
    1105 SCIP_CALL( SCIPcreate(&bucket->subscip) );
    1106
    1107 /* create variable hash mapping scip -> subscip */
    1108 SCIP_CALL( SCIPhashmapCreate(&varsmap, SCIPblkmem(scip), nvars) );
    1109
    1110 (*success) = TRUE;
    1111
    1112#ifdef SCIP_DEBUG /* we print statistics later, so we need to copy statistics tables */
    1114 TRUE, FALSE, TRUE, TRUE, TRUE,
    1115 TRUE, TRUE, TRUE, TRUE, TRUE,
    1116 TRUE, TRUE, TRUE, FALSE, TRUE,
    1117 TRUE, TRUE, TRUE, TRUE, TRUE, success) );
    1118#else
    1120 TRUE, FALSE, TRUE, TRUE, TRUE,
    1121 TRUE, TRUE, TRUE, TRUE, TRUE,
    1122 TRUE, TRUE, TRUE, FALSE, FALSE,
    1123 TRUE, FALSE, FALSE, TRUE, TRUE, success) );
    1124#endif
    1125
    1126 /* copy parameter settings */
    1128
    1129 /* adapt limit settings */
    1130 SCIP_CALL( SCIPcopyLimits(scip, bucket->subscip) );
    1131
    1132 /* create problem in subscip */
    1133 /* get name of the original problem and add "dksbucket" + [bucketnumber] */
    1134 (void) SCIPsnprintf(probname, SCIP_MAXSTRLEN, "%s_dksbucket%d", SCIPgetProbName(scip), bucket->number);
    1135
    1136 /* from before: avoid recursive calls */
    1138
    1139 /* copy all variables */
    1140 SCIP_CALL( SCIPcopyProb(scip, bucket->subscip, varsmap, NULL, FALSE, probname) );
    1141 SCIP_CALL( SCIPcopyVars(scip, bucket->subscip, varsmap, NULL, NULL, NULL, 0, TRUE) );
    1142
    1143 /* copy as many constraints as possible */
    1145
    1146 conss = SCIPgetConss(scip);
    1147
    1148 for( i = 0; i < SCIPgetNConss(scip); ++i )
    1149 {
    1150 /* do not check this if we use the transformed problem */
    1151 if( !usetransprob )
    1152 assert(!SCIPconsIsModifiable(conss[i]));
    1153 /* copy the constraint */
    1154 SCIP_CALL( SCIPgetConsCopy(scip, bucket->subscip, conss[i], &newcons, SCIPconsGetHdlr(conss[i]), varsmap, consmap,
    1155 NULL, SCIPconsIsInitial(conss[i]), SCIPconsIsSeparated(conss[i]), SCIPconsIsEnforced(conss[i]),
    1156 SCIPconsIsChecked(conss[i]), SCIPconsIsPropagated(conss[i]), FALSE, FALSE, SCIPconsIsDynamic(conss[i]),
    1157 SCIPconsIsRemovable(conss[i]), FALSE, FALSE, success) );
    1158
    1159 /* abort if constraint was not successfully copied */
    1160 if( !(*success) )
    1161 {
    1162 *success = FALSE;
    1163 if( newcons != NULL )
    1164 {
    1165 SCIP_CALL( SCIPreleaseCons(bucket->subscip, &newcons) );
    1166 }
    1167 SCIPhashmapFree(&varsmap);
    1168 SCIPhashmapFree(&consmap);
    1169 return SCIP_OKAY;
    1170 }
    1171
    1172 if( newcons != NULL )
    1173 {
    1174 SCIP_CALL( SCIPaddCons(bucket->subscip, newcons) );
    1175 SCIP_CALL( SCIPreleaseCons(bucket->subscip, &newcons) );
    1176 }
    1177 }
    1178
    1179 SCIPhashmapFree(&consmap);
    1180 if( !(*success) )
    1181 {
    1182 SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "In heur_dks: failed to copy some constraints, continuing\n");
    1183 SCIPdebugMsg(scip, "In heur_dks: failed to copy some constraints to subscip, continue anyway\n");
    1184 }
    1185
    1186 /* create arrays translating scip transformed vars to subscip original vars, and vice versa
    1187 * capture variables in scip and subscip
    1188 * catch global bound change events
    1189 */
    1190
    1191 SCIP_CALL( SCIPgetVarsData(bucket->subscip, &subvars, &nsubvars, NULL, NULL, NULL, NULL) );
    1192
    1193 SCIP_CALL( SCIPallocClearBufferArray(scip, &bucket->sub2scip, nsubvars) );
    1194 SCIP_CALL( SCIPallocClearBufferArray(scip, &bucket->scip2sub, nvars) );
    1195
    1196 /* iteration over varsmap to get the original and corresponding subscip variables*/
    1197 for( i = 0; i < SCIPhashmapGetNEntries(varsmap); i++ )
    1198 {
    1199 SCIP_HASHMAPENTRY* entry;
    1200 entry = SCIPhashmapGetEntry(varsmap, i);
    1201 if( entry != NULL )
    1202 {
    1203 var = (SCIP_VAR*) SCIPhashmapEntryGetOrigin(entry);
    1204 subvar = (SCIP_VAR*) SCIPhashmapEntryGetImage(entry);
    1205 assert(subvar != NULL);
    1206 assert(SCIPvarGetProbindex(subvar) >= 0);
    1207 assert(SCIPvarGetProbindex(subvar) <= nsubvars);
    1208
    1209 if( SCIPvarIsActive(var) )
    1210 {
    1211 assert(SCIPvarGetProbindex(var) <= nvars);
    1212 assert(bucket->scip2sub[SCIPvarGetProbindex(var)] == NULL);
    1213 bucket->scip2sub[SCIPvarGetProbindex(var)] = subvar;
    1214 }
    1215 assert(bucket->sub2scip[SCIPvarGetProbindex(subvar)] == NULL);
    1216 bucket->sub2scip[SCIPvarGetProbindex(subvar)] = var;
    1217 }
    1218 }
    1219
    1220#ifdef SCIP_DEBUG
    1221 for( i = 0; i < nsubvars; i++ )
    1222 {
    1223 subvar = SCIPgetVars(bucket->subscip)[i];
    1224 assert(SCIPvarGetProbindex(subvar) == i);
    1225 var = bucket->sub2scip[i];
    1226
    1229 }
    1230#endif
    1231
    1232 SCIPhashmapFree(&varsmap);
    1233
    1234 /* avoid recursive calls */
    1236
    1237 /* do not abort subproblem on CTRL-C */
    1238 SCIP_CALL( SCIPsetBoolParam(bucket->subscip, "misc/catchctrlc", FALSE) );
    1239
    1240 /* forbid recursive call of DKS heuristic on subproblems */
    1241 if( SCIPisParamFixed(bucket->subscip, "heuristics/" HEUR_NAME "/freq") )
    1242 {
    1243 SCIPwarningMessage(scip, "unfixing param heuristics/" HEUR_NAME "/freq in DKS to avoid recursive calls\n");
    1244 SCIP_CALL( SCIPunfixParam(bucket->subscip, "heuristics/" HEUR_NAME "/freq") );
    1245 }
    1246 SCIP_CALL( SCIPsetIntParam(bucket->subscip, "heuristics/" HEUR_NAME "/freq", -1) );
    1247
    1248#ifdef SCIP_DEBUG
    1249 /* for debugging, enable full output */
    1250 SCIP_CALL( SCIPsetIntParam(bucket->subscip, "display/verblevel", 5) );
    1251 SCIP_CALL( SCIPsetIntParam(bucket->subscip, "display/freq", 100000000) );
    1252#else
    1253 /* disable statistic timing inside sub SCIP and output to console */
    1254 SCIP_CALL( SCIPsetIntParam(bucket->subscip, "display/verblevel", 0) );
    1255 SCIP_CALL( SCIPsetBoolParam(bucket->subscip, "timing/statistictiming", FALSE) );
    1256#endif
    1257
    1258 SCIPdebugMsg(scip, "created subscip of bucket %d\n", bucket->number);
    1259
    1260 return SCIP_OKAY;
    1261}
    1262
    1263/** create bucketlist and initialize buckets */
    1264static
    1266 SCIP* scip, /**< SCIP data structure */
    1267 SCIP_Bool usetransprob, /**< indication whether to use the transformed problem (or the original) */
    1268 int nbuckets, /**< number of buckets (without kernel only) */
    1269 BUCKETLIST** bucketlist, /**< pointer to store bucketlist structure */
    1270 SCIP_Bool* success /**< pointer to store if the creation process was successfull */
    1271 )
    1272{
    1273 BUCKET* bucket;
    1274 int b;
    1275
    1276 bucket = NULL;
    1277 *success = TRUE;
    1278
    1279 /* init bucketlist data structure with nbucket + 1 because the initial bucket with kernel vars is included */
    1280 SCIP_CALL( initBucketlist(scip, bucketlist, nbuckets + 1) );
    1281 assert((*bucketlist)->buckets != NULL);
    1282
    1283 /* loop over all buckets and the initial "kernel"bucket */
    1284 for( b = 0; b < nbuckets + 1; b++ )
    1285 {
    1286 SCIP_CALL( initBucket(*bucketlist) );
    1287 assert((*bucketlist)->nbuckets == b + 1);
    1288
    1289 bucket = &(*bucketlist)->buckets[b];
    1290
    1291 /* build subscip for bucket */
    1292 SCIP_CALL( bucketCreateSubscip(bucket, usetransprob, success) );
    1293
    1294 if( !(*success) )
    1295 return SCIP_OKAY;
    1296 }
    1297 assert(nbuckets + 1 == (*bucketlist)->nbuckets);
    1298
    1299 return SCIP_OKAY;
    1300}
    1301
    1302/** search variable in kernel and bucket */
    1303static
    1305 BUCKET* bucket, /**< bucket to be solved next */
    1306 SCIP_VAR** contkernelvars, /**< continuous variables in the latest kernel */
    1307 int ncontkernelvars, /**< amount of continuous variables in the latest kernel */
    1308 SCIP_VAR** kernelvars, /**< variables in the kernel */
    1309 int nkernelvars, /**< amount of variables in the kernel */
    1310 SCIP_VAR** intkernelvars, /**< variables in the integer kernel, if 2-level buckets are present */
    1311 int nintkernelvars, /**< amount of variables in the integer kernel */
    1312 SCIP_VAR* var, /**< variable to search for in the kernel/buckets */
    1313 SCIP_Bool* found /**< is the variable present in the current bucket or the kernel? */
    1314 )
    1315{
    1316 int j;
    1317
    1318 *found = FALSE;
    1319
    1320 /* search in the current continuous kernel for the given variable */
    1322 {
    1323 for( j = 0; j < ncontkernelvars; j++ )
    1324 {
    1325 if( contkernelvars[j] != NULL && var == contkernelvars[j] )
    1326 {
    1327 *found = TRUE;
    1328 return SCIP_OKAY;
    1329 }
    1330 }
    1331
    1332 /* search for the current variable in the continuous bucket variables */
    1333 for( j = 0; j < bucket->ncontbucketvars; j++ )
    1334 {
    1335 if( var == bucket->contbucketvars[j] )
    1336 {
    1337 *found = TRUE;
    1338 return SCIP_OKAY;
    1339 }
    1340 }
    1341 }
    1342
    1343 /* search in the current (binary) kernel for the variable */
    1344 for( j = 0; j < nkernelvars; j++ )
    1345 {
    1346 if( kernelvars[j] != NULL && var == kernelvars[j] )
    1347 {
    1348 *found = TRUE;
    1349 return SCIP_OKAY;
    1350 }
    1351 }
    1352
    1353 /* if 2-level buckets are used, also search for the current variable in the integer kernel */
    1354 for( j = 0; j < nintkernelvars; j++ )
    1355 {
    1356 if( intkernelvars[j] != NULL && var == intkernelvars[j] )
    1357 {
    1358 *found = TRUE;
    1359 return SCIP_OKAY;
    1360 }
    1361 }
    1362
    1363 /* search for the current variable in the (binary) bucket variables */
    1364 for( j = 0; j < bucket->nbucketvars; j++ )
    1365 {
    1366 if( var == bucket->bucketvars[j] )
    1367 {
    1368 *found = TRUE;
    1369 return SCIP_OKAY;
    1370 }
    1371 }
    1372
    1373 /* if 2-level buckets are used, also search for the current variable in the integer bucket variables */
    1374 for( j = 0; j < bucket->nintbucketvars; j++ )
    1375 {
    1376 if( var == bucket->intbucketvars[j] )
    1377 {
    1378 *found = TRUE;
    1379 return SCIP_OKAY;
    1380 }
    1381 }
    1382
    1383 return SCIP_OKAY;
    1384}
    1385
    1386/** adjust the kernel variables */
    1387static
    1389 SCIP* scip, /**< current scip */
    1390 BUCKET* bucket, /**< bucket that was solved last */
    1391 SCIP_VAR*** contkernelvars, /**< cont. kernelvars to adjust */
    1392 int* ncontkernelvars, /**< amount of cont. kernelvars */
    1393 int maxcontkernelsize, /**< maximal size of the continuous kernel */
    1394 SCIP_VAR*** kernelvars, /**< kernelvars to adjust */
    1395 int* nkernelvars, /**< amount of kernelvars */
    1396 int maxkernelsize, /**< maximal size of the kernel */
    1397 SCIP_VAR*** intkernelvars, /**< integer kernelvars to adjust */
    1398 int* nintkernelvars, /**< amount of integer kernelvars */
    1399 int maxintkernelsize, /**< maximal size of the integer kernel */
    1400 SCIP_Bool twolevel /**< is a twolevel structure necessary */
    1401 )
    1402{
    1403 SCIP_VAR** contkvars; /* temporary storage for the continuous kernel variables */
    1404 SCIP_VAR** kvars; /* temporary storage for the (binary/integer) kernel variables */
    1405 SCIP_VAR** intkvars; /* temporary storage for the integer kernel variables */
    1406 SCIP_VAR *var; /* temporary variable */
    1407 SCIP_Real val; /* variable value in solution */
    1408 SCIP_Real lb; /* variable lower bound */
    1409 SCIP_SOL* solution; /* solution of the current bucket */
    1410 int nnewcontkernelvars; /* number of new continuous kernel variables */
    1411 int nnewkernelvars; /* number of new (binary/integer) kernel variables */
    1412 int nnewintkernelvars; /* number of new integer kernel variables */
    1413 int n; /* temporary variable counter */
    1414
    1415 /* definition of old kernel arrays to update the actual ones live */
    1416 contkvars = *contkernelvars;
    1417 kvars = *kernelvars;
    1418 intkvars = *intkernelvars;
    1419
    1420 solution = SCIPgetBestSol(bucket->subscip);
    1421
    1422 /* deletion of variables from the kernel */
    1423 /* continuous kernelvariables with value equal to zero or their lb get deleted from the kernel */
    1424 /* todo: after x tries, maybe with seperate kernelindexarray */
    1425 nnewintkernelvars = 0;
    1426 nnewcontkernelvars = 0;
    1427 for( n = 0; n < *ncontkernelvars; n++ )
    1428 {
    1429 if( contkvars[n] == NULL )
    1430 continue;
    1431
    1432 /* get the value of the current variable and its lower bound */
    1433 if( SCIPvarIsActive(contkvars[n]) )
    1434 {
    1435 assert(SCIPvarGetProbindex(contkvars[n]) <= SCIPgetNVars(scip));
    1436 var = bucket->scip2sub[SCIPvarGetProbindex(contkvars[n])];
    1437
    1438 if( var != NULL )
    1439 val = SCIPgetSolVal(bucket->subscip, solution, var);
    1440 else
    1441 continue;
    1442 }
    1443 else
    1444 continue;
    1445
    1446 lb = SCIPvarGetLbLocal(contkvars[n]);
    1447
    1448 /* if deviating from lb and zero, re-add into current kernel vars */
    1449 if( (!SCIPisEQ(scip, val, 0.0) && !SCIPisEQ(scip, val, lb)) )
    1450 (*contkernelvars)[nnewcontkernelvars++] = contkvars[n];
    1451 /* otherwise, delete it */
    1452 else
    1453 contkvars[n] = NULL;
    1454 }
    1455
    1456 /* dependent on #levels, check the solution value of the bin/int value to be unequal to 0 and/or its lb */
    1457 nnewkernelvars = 0;
    1458 for( n = 0; n < *nkernelvars; n++ )
    1459 {
    1460 if( kvars[n] == NULL )
    1461 continue;
    1462
    1463 /* get the value of the current kernel variable in the solution and its lower bound */
    1464 if( SCIPvarIsActive(kvars[n]) )
    1465 {
    1466 assert(SCIPvarGetProbindex(kvars[n]) <= SCIPgetNVars(scip));
    1467 var = bucket->scip2sub[SCIPvarGetProbindex(kvars[n])];
    1468 if( var != NULL )
    1469 val = SCIPgetSolVal(bucket->subscip, solution, var);
    1470 else
    1471 continue;
    1472 }
    1473 else
    1474 continue;
    1475
    1476 lb = SCIPvarGetLbLocal(kvars[n]);
    1477
    1478 /* if two-level structure is required, the binary case occurs and only deviation to 0 has to be checked */
    1479 if( (twolevel && !SCIPisEQ(scip, val, 0.0)) )
    1480 (*kernelvars)[nnewkernelvars++] = kvars[n];
    1481 /* if one-level case, the variable has to deviate from 0 and its lb */
    1482 else if( (!twolevel && !SCIPisEQ(scip, val, 0.0) && !SCIPisEQ(scip, val, lb)) )
    1483 (*kernelvars)[nnewkernelvars++] = kvars[n];
    1484 /* otherwise delete the variable from its current position in the kernel */
    1485 else
    1486 kvars[n] = NULL;
    1487 }
    1488
    1489 /* if necessary check the relevance of pure integer variables in the current kernel */
    1490 if( twolevel )
    1491 {
    1492 nnewintkernelvars = 0;
    1493
    1494 for( n = 0; n < *nintkernelvars; n++ )
    1495 {
    1496 if( intkvars[n] == NULL )
    1497 continue;
    1498
    1499 /* get the value of the current variable in the solution and its lower bound */
    1500 if( SCIPvarIsActive(intkvars[n]) )
    1501 {
    1502 assert(SCIPvarGetProbindex(intkvars[n]) <= SCIPgetNVars(scip));
    1503 var = bucket->scip2sub[SCIPvarGetProbindex(intkvars[n])];
    1504
    1505 if( var != NULL )
    1506 val = SCIPgetSolVal(bucket->subscip, solution, var);
    1507 else
    1508 continue;
    1509 }
    1510 else
    1511 continue;
    1512
    1513 lb = SCIPvarGetLbLocal(intkvars[n]);
    1514
    1515 /* if variable value is unequal to 0 and its lower bound, it is re-added into the kernel */
    1516 if( (!SCIPisEQ(scip, val, 0.0) && !SCIPisEQ(scip, val, lb)) )
    1517 (*intkernelvars)[nnewintkernelvars++] = intkvars[n];
    1518 else
    1519 intkvars[n] = NULL;
    1520 }
    1521 }
    1522
    1523 /* addition of new variables from the bucket to the kernel */
    1524
    1525 /* add continuous bucket variables with suitable values to the kernel */
    1526 for( n = 0; n < bucket->ncontbucketvars; n++ )
    1527 {
    1528 if( bucket->contbucketvars[n] == NULL )
    1529 continue;
    1530
    1531 if( SCIPvarIsActive(bucket->contbucketvars[n]) )
    1532 {
    1533 assert(SCIPvarGetProbindex(bucket->contbucketvars[n]) <= SCIPgetNVars(scip));
    1534 var = bucket->scip2sub[SCIPvarGetProbindex(bucket->contbucketvars[n])];
    1535
    1536 if( var != NULL )
    1537 val = SCIPgetSolVal(bucket->subscip, solution, var);
    1538 else
    1539 continue;
    1540 }
    1541 else
    1542 continue;
    1543
    1544 lb = SCIPvarGetLbLocal(bucket->contbucketvars[n]);
    1545
    1546 /* if the solution value of the bucket var != zero and != its lb, add it to the cont kernel vars */
    1547 if( !SCIPisEQ(scip, val, 0.0) && !SCIPisEQ(scip, val, lb) )
    1548 {
    1549 if( SCIPisGT(scip, (SCIP_Real)nnewcontkernelvars, (SCIP_Real)maxcontkernelsize) )
    1550 break;
    1551 else
    1552 (*contkernelvars)[nnewcontkernelvars++] = bucket->contbucketvars[n];
    1553 }
    1554 }
    1555
    1556 /* the size of the continuous kernel might be different -> change it */
    1557 *ncontkernelvars = nnewcontkernelvars;
    1558
    1559 /* add binary/integer bucketvariables with suitable values to the kernel */
    1560 for( n = 0; n < bucket->nbucketvars; n++ )
    1561 {
    1562 if( bucket->bucketvars[n] == NULL )
    1563 continue;
    1564
    1565 if( SCIPvarIsActive(bucket->bucketvars[n]) )
    1566 {
    1567 assert(SCIPvarGetProbindex(bucket->bucketvars[n]) <= SCIPgetNVars(scip));
    1568 var = bucket->scip2sub[SCIPvarGetProbindex(bucket->bucketvars[n])];
    1569 if( var != NULL )
    1570 val = SCIPgetSolVal(bucket->subscip, solution, var);
    1571 else
    1572 continue;
    1573 }
    1574 else
    1575 continue;
    1576
    1577 lb = SCIPvarGetLbLocal(bucket->bucketvars[n]);
    1578
    1579 /* if bucket var != zero and != its lower bound (in epsilon), try adding it to the kernel vars */
    1580 if( twolevel && !SCIPisEQ(scip, val, 0.0) )
    1581 {
    1582 if( SCIPisGT(scip, (SCIP_Real)nnewkernelvars, (SCIP_Real)maxkernelsize) )
    1583 break;
    1584 else
    1585 (*kernelvars)[nnewkernelvars++] = bucket->bucketvars[n];
    1586 }
    1587 /* if one-level case, the variable has to deviate from 0 and its lb */
    1588 else if( !twolevel && !SCIPisEQ(scip, val, 0.0) && !SCIPisEQ(scip, val, lb) )
    1589 {
    1590 if( SCIPisGT(scip, (SCIP_Real)nnewkernelvars, (SCIP_Real)maxkernelsize) )
    1591 break; /* @potential todo: if kernel is "full", find a suitable variable to delete or extend kernel */
    1592 else
    1593 (*kernelvars)[nnewkernelvars++] = bucket->bucketvars[n];
    1594 }
    1595 }
    1596
    1597 /* the size of the kernel might be different, so change it */
    1598 *nkernelvars = nnewkernelvars;
    1599
    1600 /* if necessary, add integer bucket variables with suitable values to the integer kernel */
    1601 if( twolevel )
    1602 {
    1603 for( n = 0; n < bucket->nintbucketvars; n++ )
    1604 {
    1605 if( bucket->intbucketvars[n] == NULL )
    1606 continue;
    1607
    1608 if( SCIPvarIsActive(bucket->intbucketvars[n]) )
    1609 {
    1610 assert(SCIPvarGetProbindex(bucket->intbucketvars[n]) <= SCIPgetNVars(scip));
    1611 var = bucket->scip2sub[SCIPvarGetProbindex(bucket->intbucketvars[n])];
    1612 if( var != NULL )
    1613 val = SCIPgetSolVal(bucket->subscip, solution, var);
    1614 else
    1615 continue;
    1616 }
    1617 else
    1618 continue;
    1619
    1620 lb = SCIPvarGetLbLocal(bucket->intbucketvars[n]);
    1621
    1622 /* if the bucket variable's value is unequal to zero and its lb, try adding it to the integer kernel */
    1623 if( !SCIPisEQ(scip, val, 0.0) && !SCIPisEQ(scip, val, lb) )
    1624 {
    1625 if( SCIPisGT(scip, (SCIP_Real)nnewintkernelvars, (SCIP_Real)maxintkernelsize) )
    1626 break;
    1627 else
    1628 (*intkernelvars)[nnewintkernelvars++] = bucket->intbucketvars[n];
    1629 }
    1630 }
    1631 /* if the size of the kernel is different, change it */
    1632 *nintkernelvars = nnewintkernelvars;
    1633 }
    1634
    1635 return SCIP_OKAY;
    1636}
    1637
    1638/** add usuage constraint */
    1639static
    1641 BUCKET* bucket /**< current bucket to look at */
    1642 )
    1643{
    1644 SCIP_CONS* constraint;
    1645 SCIP_VAR** subvars;
    1646 SCIP_VAR *var;
    1647 char consname[SCIP_MAXSTRLEN];
    1648 SCIP_Real* coeffs;
    1649 SCIP_Real rhs;
    1650 SCIP_Real lb;
    1651 int n;
    1652 int k;
    1653
    1654 /* add an array to store the binary and integer variables of the constraint to add separatly */
    1655 SCIP_CALL( SCIPallocBufferArray(bucket->subscip, &subvars, bucket->nbucketvars + bucket->nintbucketvars) );
    1656
    1657 /* add an array for the coefficients of the binary and integer variables in the constraint */
    1658 SCIP_CALL( SCIPallocBufferArray(bucket->subscip, &coeffs, bucket->nbucketvars + bucket->nintbucketvars) );
    1659
    1660 /* for all (binary/integer) variables in the current bucket add the variables to the subvars and add coeff -1 */
    1661 k = 0;
    1662 rhs = -1.0;
    1663 for( n = 0; n < bucket->nbucketvars ; n++ )
    1664 {
    1665 if( bucket->bucketvars[n] == NULL )
    1666 continue;
    1667 if( SCIPvarIsActive(bucket->bucketvars[n]) )
    1668 var = bucket->scip2sub[SCIPvarGetProbindex(bucket->bucketvars[n])];
    1669 else
    1670 var = NULL;
    1671
    1672 if( var != NULL )
    1673 {
    1674 lb = SCIPvarGetLbLocal(bucket->bucketvars[n]);
    1675
    1676 /* skip variables with infinite lower bound, since subtraction is not reasonable */
    1677 /**@todo optionally take the upper bound if finite and add with coefficient +1 to bound away from the ub */
    1678 if( SCIPisInfinity(bucket->subscip, -lb) )
    1679 continue;
    1680
    1681 subvars[k] = var;
    1682 coeffs[k++] = -1.0; /* constraint: (sum of x_i >= 1) iff (-1 * sum of x_1 <= -1) */
    1683
    1684 /* if the variable has a positive lower bound, it is substracted from the rhs of the constraint */
    1685 rhs -= lb;
    1686 }
    1687 }
    1688
    1689 for( n = 0; n < bucket->nintbucketvars; n++ )
    1690 {
    1691 if( bucket->intbucketvars[n] == NULL )
    1692 continue;
    1693 if( SCIPvarIsActive(bucket->intbucketvars[n]) )
    1694 var = bucket->scip2sub[SCIPvarGetProbindex(bucket->intbucketvars[n])];
    1695 else
    1696 var = NULL;
    1697
    1698 if( var != NULL )
    1699 {
    1700 lb = SCIPvarGetLbLocal(bucket->intbucketvars[n]);
    1701
    1702 /* skip variables with infinite lower bound, since subtraction is not reasonable */
    1703 /**@todo optionally take the upper bound if finite and add with coefficient +1 to bound away from the ub */
    1704 if( SCIPisInfinity(bucket->subscip, -lb) )
    1705 continue;
    1706
    1707 subvars[k] = var;
    1708 coeffs[k++] = -1.0;
    1709
    1710 /* if the integer variable has a positive lower bound, it is added to the rhs of the new constraint */
    1711 rhs -= lb;
    1712 }
    1713 }
    1714
    1715 (void)SCIPsnprintf(consname, SCIP_MAXSTRLEN, "useconstraint_bucket_%d", bucket->number);
    1716
    1717 /* add the constraint: (-1 * sum of bucket variables <= - sum of lbs - 1) s.t. at least 1 of these vars is nonzero */
    1718 SCIP_CALL( SCIPcreateConsBasicLinear(bucket->subscip, &constraint, consname, k, subvars, coeffs, -SCIPinfinity(bucket->subscip), rhs) );
    1719 SCIP_CALL( SCIPaddCons(bucket->subscip, constraint) );
    1720 SCIP_CALL( SCIPreleaseCons(bucket->subscip, &constraint) );
    1721
    1722 /* free the arrays */
    1723 if( subvars != NULL )
    1724 SCIPfreeBufferArray(bucket->subscip, &subvars);
    1725
    1726 if( coeffs != NULL )
    1727 SCIPfreeBufferArray(bucket->subscip, &coeffs);
    1728
    1729 return SCIP_OKAY;
    1730}
    1731
    1732/*
    1733 * Callback methods of primal heuristic
    1734 */
    1735
    1736/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    1737static
    1739{ /*lint --e{715}*/
    1740 assert(scip != NULL);
    1741 assert(heur != NULL);
    1742 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    1743
    1744 /* call inclusion method of primal heuristic */
    1746
    1747 return SCIP_OKAY;
    1748}
    1749
    1750
    1751/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    1752static
    1754{ /*lint --e{715}*/
    1755 SCIP_HEURDATA* heurdata;
    1756
    1757 assert(heur != NULL);
    1758 assert(scip != NULL);
    1759
    1760 heurdata = SCIPheurGetData(heur);
    1761 assert(heurdata != NULL);
    1762
    1763 SCIPfreeBlockMemory(scip, &heurdata);
    1764 SCIPheurSetData(heur, NULL);
    1765
    1766 return SCIP_OKAY;
    1767}
    1768
    1769/** execution method of primal heuristic */
    1770static
    1772{ /*lint --e{715}*/
    1773 SCIP_HEURDATA* heurdata;
    1774 SCIP_DECOMP** alldecomps;
    1775 SCIP_DECOMP* decomp = NULL;
    1776 SCIP_HASHMAP* lbvarmap = NULL; /* variable map connecting transformed vars to their original lower bd */
    1777 SCIP_CONSHDLR* conshdlr; /* constraint handler to check for indicator constraints */
    1778 SCIP_VAR*** bw_contkernelvars = NULL;
    1779 SCIP_VAR*** bw_contnonkernelvars = NULL;
    1780 SCIP_VAR*** bw_kernelvars = NULL;
    1781 SCIP_VAR*** bw_nonkernelvars = NULL;
    1782 SCIP_VAR*** bw_intkernelvars = NULL;
    1783 SCIP_VAR*** bw_intnonkernelvars = NULL;
    1784 SCIP_VAR** vars = NULL;
    1785 SCIP_VAR** contkernelvars = NULL;
    1786 SCIP_VAR** contnonkernelvars = NULL;
    1787 SCIP_VAR** kernelvars = NULL; /* just the bin kernel vars if problem includes bin AND int vars */
    1788 SCIP_VAR** nonkernelvars = NULL; /* just the bin non kernel vars if problem includes bin AND int vars */
    1789 SCIP_VAR** intkernelvars = NULL; /* used if problem includes binary AND integer variables */
    1790 SCIP_VAR** intnonkernelvars = NULL; /* used if problem includes binary AND integer variables */
    1791 SCIP_VAR** binintvars = NULL;
    1792 SCIP_CONS** conss = NULL;
    1793 SCIP_CONS** bucketconss = NULL;
    1794 SCIP_Real gapfactor;
    1795 SCIP_Real maxcontkernelsize;
    1796 SCIP_Real maxcontnonkernelsize;
    1797 SCIP_Real maxkernelsize;
    1798 SCIP_Real maxnonkernelsize;
    1799 SCIP_Real maxintkernelsize; /* used if problem includes binary AND integer variables */
    1800 SCIP_Real maxintnonkernelsize;
    1801 SCIP_Real memory;
    1802 SCIP_Real bestlocval;
    1803 SCIP_Real mipgap;
    1804 SCIP_Real linkscore;
    1805 SCIP_Real** bw_cont_redcost = NULL;
    1806 SCIP_Real** bw_redcost = NULL;
    1807 SCIP_Real** bw_int_redcost = NULL;
    1808 SCIP_STATUS status;
    1809 SCIP_Bool success;
    1810 SCIP_Bool twolevel; /* clarifying if two level buckets are used */
    1811 SCIP_Bool usebestsol;
    1812 SCIP_SOL* bestcurrsol = NULL;
    1813 BUCKETLIST* bucketlist = NULL;
    1814 BUCKET* bucket;
    1815 int* varlabels = NULL;
    1816 int* conslabels = NULL;
    1817 int* block2index = NULL;
    1818 int* blocklabels = NULL;
    1819 int* bw_ncontkernelvars = NULL;
    1820 int* bw_ncontnonkernelvars = NULL;
    1821 int* bw_nkernelvars = NULL;
    1822 int* bw_nnonkernelvars = NULL;
    1823 int* bw_nintkernelvars = NULL;
    1824 int* bw_nintnonkernelvars = NULL;
    1825 int* bw_contkernelcount = NULL;
    1826 int* bw_contnonkernelcount = NULL;
    1827 int* bw_kernelcount = NULL;
    1828 int* bw_nonkernelcount = NULL;
    1829 int* bw_intkernelcount = NULL;
    1830 int* bw_intnonkernelcount = NULL;
    1831 SCIP_Longint nodesleft;
    1833 int gapcall;
    1834 int blklbl_offset;
    1835 int nblocks;
    1836 int ndecomps;
    1837 int nvars;
    1838 int ncontkernelvars;
    1839 int ncontnonkernelvars;
    1840 int nkernelvars;
    1841 int nnonkernelvars;
    1842 int nintkernelvars;
    1843 int nintnonkernelvars;
    1844 int nbinvars;
    1845 int nintvars;
    1846 int nbinintvars;
    1847 int nbuckets;
    1848 int nconss;
    1849 int nbestbucket;
    1850 int nusedratios;
    1851 int nblocklabels;
    1852 int iters;
    1853 int b;
    1854 int i;
    1855 int j;
    1856 int k;
    1857 int l;
    1858 int m;
    1859 int n;
    1860
    1861 assert(scip != NULL);
    1862 assert(heur != NULL);
    1863 assert(result != NULL);
    1864
    1865 heurdata = SCIPheurGetData(heur);
    1866 assert(heurdata != NULL);
    1867
    1868 *result = SCIP_DIDNOTRUN;
    1869
    1870 bestlocval = SCIPinfinity(scip);
    1871 twolevel = FALSE;
    1872 success = TRUE;
    1873
    1874 gapfactor = 1.0;
    1875 gapcall = 0;
    1876 blklbl_offset = 0;
    1877 ndecomps = 0;
    1878 ncontkernelvars = 0;
    1879 ncontnonkernelvars = 0;
    1880 nkernelvars = 0;
    1881 nnonkernelvars = 0;
    1882 nintkernelvars = 0;
    1883 nintnonkernelvars = 0;
    1884 nbestbucket = -1;
    1885 iters = 0;
    1886 nblocklabels = 0;
    1887
    1888#ifdef DKS_WRITE_PROBLEMS
    1889 SCIP_CALL( SCIPwriteOrigProblem(scip, "orig_problem.lp", NULL, FALSE) );
    1890 SCIP_CALL( SCIPwriteTransProblem(scip, "trans_problem.lp", NULL, FALSE) );
    1891#endif
    1892
    1893 /* exit DKS whenever indicator constraints are present as they can not handle fixed variables */
    1894 conshdlr = SCIPfindConshdlr(scip, "indicator");
    1895 if( conshdlr != NULL && SCIPconshdlrGetNConss(conshdlr) > 0 )
    1896 return SCIP_OKAY;
    1897
    1898 /* exit DKS whenever there is not even an LP solution */
    1900 return SCIP_OKAY;
    1901
    1902 /* do not run heuristic if it was not successful in previous calls */
    1903 if( heurdata->uselesscall )
    1904 return SCIP_OKAY;
    1905
    1906 heurdata->ncalls++;
    1907
    1908 /* extract variables, constraints and number of constraints */
    1909 if( heurdata->usetransprob )
    1910 {
    1911 SCIP_VAR* tempvar = NULL; /* the transformed variable to each original variable */
    1912
    1913 /* Extract the decompositions of the transformed problem */
    1914 SCIPgetDecomps(scip, &alldecomps, &ndecomps, FALSE);
    1915
    1916 /* get all transformed binary, integer, and continuous variables */
    1917 vars = SCIPgetVars(scip);
    1918 nvars = SCIPgetNVars(scip);
    1921
    1922 /* create and initialize the hashmap for the original lower bounds */
    1923 SCIP_CALL( SCIPhashmapCreate(&lbvarmap, SCIPblkmem(scip), nvars) );
    1924 for( i = 0; i < nvars; i++ )
    1925 {
    1926 SCIP_Real scalar;
    1927 SCIP_Real constant;
    1928 tempvar = vars[i];
    1929
    1930 SCIP_CALL( SCIPvarGetOrigvarSum(&tempvar, &scalar, &constant) );
    1931
    1932 if( tempvar != NULL )
    1933 SCIP_CALL( SCIPhashmapSetImageReal(lbvarmap, vars[i], SCIPvarGetLbOriginal(tempvar)) );
    1934 }
    1935
    1936 /* initialize the constraints of the transformed problem */
    1937 nconss = SCIPgetNConss(scip);
    1938 conss = SCIPgetConss(scip);
    1939 }
    1940 else
    1941 {
    1942 /* extract the decompositions of the original problem */
    1943 SCIPgetDecomps(scip, &alldecomps, &ndecomps, TRUE);
    1944
    1945 /* get all original binary, integer, and continuous variables */
    1946 vars = SCIPgetOrigVars(scip);
    1947 nvars = SCIPgetNOrigVars(scip);
    1950
    1951 /* it is necessary to take the original constraints here, otherwise they can not be used later on */
    1952 nconss = SCIPgetNOrigConss(scip);
    1953 conss = SCIPgetOrigConss(scip);
    1954 }
    1955
    1956 nbinintvars = nbinvars + nintvars;
    1957
    1958 if( ndecomps > 0 && heurdata->usedecomp )
    1959 {
    1960 /* take the first decomposition */
    1961 decomp = alldecomps[0];
    1962 SCIPdebugMsg(scip, "First original decomposition is selected\n");
    1963 assert(decomp != NULL);
    1964
    1965 nblocks = SCIPdecompGetNBlocks(decomp);
    1966 }
    1967 else
    1968 {
    1969 SCIPdebugMsg(scip, "No decompositions available or wanted, going ahead without decomp\n");
    1970 ndecomps = 0; /* set to 0 for later unnecessary ifs */
    1971 nblocks = 0; /* 0 means no decomp in use */
    1972 }
    1973
    1974 /* if problem has no constraints or no variables, terminate */
    1975 if( nvars == 0 || nconss == 0 )
    1976 {
    1977 SCIPdebugMsg(scip, "problem has no constraints or variables\n");
    1978 goto TERMINATE;
    1979 }
    1980
    1981 /* verify if the heuristic should be used only for problems with binary and no continuous variables */
    1982 if( heurdata->runbinprobsonly )
    1983 {
    1984 if( nbinvars == 0 || nbinintvars < nvars )
    1985 {
    1986 SCIPdebugMsg(scip, "do not run dks if continuous variables or only integer variables are present\n");
    1987 goto TERMINATE;
    1988 }
    1989 }
    1990
    1991 /* estimate required memory and terminate if not enough memory is available */
    1992 SCIP_CALL( SCIPgetRealParam(scip, "limits/memory", &memory) );
    1993 if( (SCIPgetMemUsed(scip) + SCIPgetMemExternEstim(scip)) / 1048576.0 >= memory )
    1994 {
    1995 SCIPdebugMsg(scip, "The estimated memory usage is too large.\n");
    1996 goto TERMINATE;
    1997 }
    1998
    1999 SCIP_CALL( SCIPallocBufferArray(scip, &varlabels, nvars) );
    2000 SCIP_CALL( SCIPallocBufferArray(scip, &conslabels, nconss) );
    2001
    2002 if( ndecomps > 0 && heurdata->usedecomp )
    2003 {
    2004 /* extract the varlabels to identify linking variables */
    2005 SCIPdecompGetVarsLabels(decomp, vars, varlabels, nvars);
    2006 SCIPdecompGetConsLabels(decomp, conss, conslabels, nconss);
    2007
    2008 /* prepare the distinct finding of blocklabels */
    2009 SCIP_CALL( SCIPallocBufferArray(scip, &blocklabels, nblocks) );
    2010
    2011 /* check if linking score of the instance is sufficiently low to get called */
    2012 SCIP_CALL( getLinkingScoreAndBlocklabels(blocklabels, varlabels, conslabels, &linkscore, &nblocklabels,
    2013 nblocks, nvars, nconss) );
    2014 if( linkscore > heurdata->maxlinkscore )
    2015 {
    2016 SCIPdebugMsg(scip, "decomposition has not required linking score\n");
    2017 goto TERMINATE;
    2018 }
    2019
    2020 if( nblocklabels > 0 )
    2021 {
    2022 SCIPsortInt(blocklabels, nblocklabels);
    2023
    2024 /* if it exists the blocklabel 0, we have to add an offset of 1 to store the linking variables at 0 */
    2025 if( blocklabels[0] == 0 )
    2026 blklbl_offset = 1;
    2027
    2028 /* fill the mapping of blocklabels to blockindices */
    2029 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &block2index, blocklabels[nblocklabels - 1] + 1 + blklbl_offset) );
    2030 }
    2031 else
    2032 {
    2033 assert(nblocks == 0);
    2034 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &block2index, 1) );
    2035 }
    2036
    2037 block2index[0] = 0; /* SCIP_DECOMP_LINKVAR = -1, but are saved at index 0 */
    2038 for( b = 0; b < nblocklabels; b++ )
    2039 block2index[blocklabels[b] + blklbl_offset] = b + 1;
    2040 }
    2041 else
    2042 {
    2043 /* initialize dummy varlabels to avoid further distinctions in the following code*/
    2044 int v;
    2045
    2046 for( v = 0; v < nvars; v++ )
    2047 varlabels[v] = 0;
    2048
    2049 /* fill the mapping of blocklabels 0 to blockindices 0; nblocks = 0 in this case */
    2050 assert(nblocks == 0);
    2051 SCIP_CALL( SCIPallocClearBlockMemoryArray(scip, &block2index, 1) );
    2052 block2index[0] = 0;
    2053 }
    2054
    2055 /* if necessary store the current best solution for later use */
    2056 usebestsol = heurdata->usebestsol;
    2057 if( heurdata->usebestsol )
    2058 {
    2059 if( SCIPgetNSols(scip) > 1 )
    2060 bestcurrsol = SCIPgetBestSol(scip);
    2061 else
    2062 usebestsol = FALSE;
    2063 }
    2064
    2065 /* initialize a kernel variable counter and a non kernel variable counter for each block + linking block (="+ 1") */
    2066 SCIP_CALL( SCIPallocClearBufferArray(scip, &bw_ncontkernelvars, nblocks + 1) );
    2067 SCIP_CALL( SCIPallocClearBufferArray(scip, &bw_ncontnonkernelvars, nblocks + 1) );
    2068 SCIP_CALL( SCIPallocClearBufferArray(scip, &bw_nkernelvars, nblocks + 1) );
    2069 SCIP_CALL( SCIPallocClearBufferArray(scip, &bw_nnonkernelvars, nblocks + 1) );
    2070
    2071 /* if there are either integer variables or binary variables only, just consider these */
    2072 if( nbinvars == 0 || nintvars == 0 || !heurdata->usetwolevel )
    2073 {
    2074 SCIP_CALL( countKernelVariables(scip, vars, bestcurrsol, lbvarmap,
    2075 twolevel, usebestsol, heurdata->usetransprob, heurdata->translbkernel,
    2076 bw_ncontkernelvars, bw_ncontnonkernelvars, bw_nkernelvars, bw_nnonkernelvars, NULL, NULL,
    2077 &ncontkernelvars, &ncontnonkernelvars, &nkernelvars, &nnonkernelvars, NULL, NULL,
    2078 block2index, varlabels, blklbl_offset, nvars) );
    2079
    2080 SCIPdebugMsg(scip, "%d initial kernel variables\n", nkernelvars);
    2081
    2082 /* if every variable is zero or its lower bound in the lp solution, terminate */
    2083 if( nkernelvars == 0 )
    2084 {
    2085 SCIPdebugMsg(scip, "No suitable variables for dks found. Leaving heuristic. \n");
    2086 goto TERMINATE;
    2087 }
    2088 else if( nkernelvars > nnonkernelvars )
    2089 /* @possible todo: if kernel vars >> nonkernel vars or >x% of all integer/binary variables => adjust */
    2090 SCIPdebugMsg(scip, "There are more kernel variables than not in the kernel\n");
    2091 }
    2092 else
    2093 {
    2094 SCIP_CALL( SCIPallocClearBufferArray(scip, &bw_nintkernelvars, nblocks + 1) );
    2095 SCIP_CALL( SCIPallocClearBufferArray(scip, &bw_nintnonkernelvars, nblocks + 1) );
    2096
    2097 /* assumption before kernel variable count: we use 2-level buckets */
    2098 twolevel = TRUE;
    2099
    2100 SCIP_CALL( countKernelVariables(scip, vars, bestcurrsol, lbvarmap,
    2101 twolevel, usebestsol, heurdata->usetransprob, heurdata->translbkernel,
    2102 bw_ncontkernelvars, bw_ncontnonkernelvars, bw_nkernelvars, bw_nnonkernelvars, bw_nintkernelvars,
    2103 bw_nintnonkernelvars, &ncontkernelvars, &ncontnonkernelvars, &nkernelvars, &nnonkernelvars,
    2104 &nintkernelvars, &nintnonkernelvars, block2index, varlabels, blklbl_offset, nvars) );
    2105
    2106 SCIPdebugMsg(scip, "%d initial bin kernel vars\n%d initial int kernel vars\n", nkernelvars, nintkernelvars);
    2107
    2108 if( nkernelvars == 0 )
    2109 {
    2110 if( nintkernelvars == 0 )
    2111 {
    2112 SCIPdebugMsg(scip, "No suitable variables for the construction of a kernel. Leaving heuristic. \n");
    2113 goto TERMINATE; /* @possible todo: if continuous variables are also considered, possibly continue here */
    2114 }
    2115 else
    2116 {
    2117 /* bin vars are all zero in lp sol -> 1-level buckets with int first and bin vars in kernel afterwards */
    2118 nkernelvars = nintkernelvars;
    2119 nnonkernelvars += nintnonkernelvars;
    2120 nintkernelvars = 0;
    2121 nintnonkernelvars = 0;
    2122
    2123 /* update the blockwise figures describing kernel sizes */
    2124 for( b = 0; b < nblocks + 1; b++ )
    2125 {
    2126 bw_nkernelvars[b] = bw_nintkernelvars[b];
    2127 bw_nnonkernelvars[b] += bw_nintnonkernelvars[b];
    2128 bw_nintnonkernelvars[b] = 0;
    2129 }
    2130
    2131 twolevel = FALSE;
    2132 }
    2133 }
    2134 else if( nintkernelvars == 0 )
    2135 {
    2136 /* int vars are all zero in lp sol -> 1-level buckets with bin first and int vars in the kernel afterwards */
    2137 nnonkernelvars += nintnonkernelvars;
    2138 nintnonkernelvars = 0;
    2139
    2140 /* update the blockwise figures describing kernel sizes */
    2141 for( b = 0; b < nblocks + 1; b++ )
    2142 {
    2143 bw_nnonkernelvars[b] += bw_nintnonkernelvars[b];
    2144 bw_nintnonkernelvars[b] = 0;
    2145 }
    2146
    2147 twolevel = FALSE;
    2148 }
    2149 else if( nkernelvars > nnonkernelvars || nintkernelvars > nintnonkernelvars )
    2150 /* @potential todo: if kernel vars >> nonkernel vars or >x% of all integer/binary variables => adjust */
    2151 SCIPdebugMsg(scip, "There are more kernel variables than not in the kernel\n");
    2152 }
    2153
    2154 /* kernel initialization for all blocks + the linking block (= "+ 1") */
    2155 SCIP_CALL( SCIPallocBufferArray(scip, &bw_contkernelvars, nblocks + 1) );
    2156 SCIP_CALL( SCIPallocBufferArray(scip, &bw_contnonkernelvars, nblocks + 1) );
    2157 SCIP_CALL( SCIPallocBufferArray(scip, &bw_kernelvars, nblocks + 1) );
    2158 SCIP_CALL( SCIPallocBufferArray(scip, &bw_nonkernelvars, nblocks + 1) );
    2159
    2160 if( twolevel )
    2161 {
    2162 SCIP_CALL( SCIPallocBufferArray(scip, &bw_intkernelvars, nblocks + 1 ) );
    2163 SCIP_CALL( SCIPallocBufferArray(scip, &bw_intnonkernelvars, nblocks + 1) );
    2164 }
    2165
    2166 /* initialize kernel and non kernel variables for each block */
    2167 for( b = 0; b < nblocks + 1; b++ )
    2168 {
    2169 int contblocksize = bw_ncontkernelvars[b] + bw_ncontnonkernelvars[b];
    2170 int blocksize = bw_nkernelvars[b] + bw_nnonkernelvars[b];
    2171
    2172 SCIP_CALL( SCIPallocBufferArray(scip, &(bw_contkernelvars[b]), contblocksize) );
    2173 SCIP_CALL( SCIPallocBufferArray(scip, &(bw_contnonkernelvars[b]), contblocksize) );
    2174 SCIP_CALL( SCIPallocBufferArray(scip, &(bw_kernelvars[b]), blocksize) );
    2175 SCIP_CALL( SCIPallocBufferArray(scip, &(bw_nonkernelvars[b]), blocksize) );
    2176
    2177 if( twolevel )
    2178 {
    2179 int intblocksize;
    2180
    2181 assert(bw_nintkernelvars != NULL);
    2182 assert(bw_nintnonkernelvars != NULL);
    2183
    2184 intblocksize = bw_nintkernelvars[b] + bw_nintnonkernelvars[b];
    2185
    2186 SCIP_CALL( SCIPallocBufferArray(scip, &(bw_intkernelvars[b]), intblocksize) );
    2187 SCIP_CALL( SCIPallocBufferArray(scip, &(bw_intnonkernelvars[b]), intblocksize) );
    2188 }
    2189 }
    2190
    2191 if( (int)SCIPfloor(scip, heurdata->kernelsizefactor * ncontkernelvars) < (ncontkernelvars + ncontnonkernelvars) )
    2192 maxcontkernelsize = (int)SCIPfloor(scip, heurdata->kernelsizefactor * ncontkernelvars);
    2193 else
    2194 maxcontkernelsize = ncontkernelvars + ncontnonkernelvars;
    2195
    2196 if( (int)SCIPfloor(scip, heurdata->kernelsizefactor * ncontnonkernelvars) < (ncontkernelvars + ncontnonkernelvars) )
    2197 maxcontnonkernelsize = (int)SCIPfloor(scip, heurdata->kernelsizefactor * ncontnonkernelvars);
    2198 else
    2199 maxcontnonkernelsize = ncontkernelvars + ncontnonkernelvars;
    2200
    2201 if( (int)SCIPfloor(scip, heurdata->kernelsizefactor * nkernelvars) < (nkernelvars + nnonkernelvars) )
    2202 maxkernelsize = (int)SCIPfloor(scip, heurdata->kernelsizefactor * nkernelvars);
    2203 else
    2204 maxkernelsize = nkernelvars + nnonkernelvars;
    2205
    2206 if( (int)SCIPfloor(scip, heurdata->kernelsizefactor * nnonkernelvars) < (nkernelvars + nnonkernelvars) )
    2207 maxnonkernelsize = (int)SCIPfloor(scip, heurdata->kernelsizefactor * nnonkernelvars);
    2208 else
    2209 maxnonkernelsize = nkernelvars + nnonkernelvars;
    2210
    2211 /* initialize the kernel and non kernel variable arrays (just binary (non/)kernel variables if 2-level buckets) */
    2212 SCIP_CALL( SCIPallocBufferArray(scip, &contkernelvars, maxcontkernelsize) );
    2213 SCIP_CALL( SCIPallocBufferArray(scip, &contnonkernelvars, maxcontnonkernelsize) );
    2214 SCIP_CALL( SCIPallocBufferArray(scip, &kernelvars, maxkernelsize) );
    2215 SCIP_CALL( SCIPallocBufferArray(scip, &nonkernelvars, maxnonkernelsize) );
    2216
    2217 /* include all binary AND integer variables as a separate array */
    2218 SCIP_CALL( SCIPallocBufferArray(scip, &binintvars, nbinintvars) );
    2219
    2220 /* extract (potential) init kernel vars (value > 0) and not kernel vars for all blocks + the linking one (= "+ 1") */
    2221 SCIP_CALL( SCIPallocClearBufferArray(scip, &bw_contkernelcount, nblocks + 1) );
    2222 SCIP_CALL( SCIPallocClearBufferArray(scip, &bw_contnonkernelcount, nblocks + 1) );
    2223 SCIP_CALL( SCIPallocClearBufferArray(scip, &bw_kernelcount, nblocks + 1) );
    2224 SCIP_CALL( SCIPallocClearBufferArray(scip, &bw_nonkernelcount, nblocks + 1) );
    2225
    2226 maxintkernelsize = 0;
    2227
    2228 /* 2-level buckets are necessary */
    2229 if( twolevel )
    2230 {
    2231 /* additionally determine maximal integer kernel size */
    2232 if( (int)SCIPfloor(scip, heurdata->kernelsizefactor * nintkernelvars) < (nintkernelvars + nintnonkernelvars) )
    2233 maxintkernelsize = (int)SCIPfloor(scip, heurdata->kernelsizefactor * nintkernelvars);
    2234 else
    2235 maxintkernelsize = nintkernelvars + nintnonkernelvars;
    2236
    2237 if( (int)SCIPfloor(scip, heurdata->kernelsizefactor * nintnonkernelvars) < (nintkernelvars + nintnonkernelvars) )
    2238 maxintnonkernelsize = (int)SCIPfloor(scip, heurdata->kernelsizefactor * nintnonkernelvars);
    2239 else
    2240 maxintnonkernelsize = nintkernelvars + nintnonkernelvars;
    2241
    2242 /* additionally initialize the integer kernel and the non integer kernel variable arrays */
    2243 SCIP_CALL( SCIPallocBufferArray(scip, &intkernelvars, maxintkernelsize) );
    2244 SCIP_CALL( SCIPallocBufferArray(scip, &intnonkernelvars, maxintnonkernelsize) );
    2245
    2246 /* allocate memory for counting the pure integer variables for all blocks + the linking block (= "+ 1") */
    2247 SCIP_CALL( SCIPallocClearBufferArray(scip, &bw_intkernelcount, nblocks + 1) );
    2248 SCIP_CALL( SCIPallocClearBufferArray(scip, &bw_intnonkernelcount, nblocks + 1) );
    2249
    2250 /* filling of the kernels with the variables */
    2251 SCIP_CALL( fillKernels(scip, vars, binintvars,
    2252 bw_contkernelvars, bw_contnonkernelvars, bw_kernelvars, bw_nonkernelvars,
    2253 bw_intkernelvars, bw_intnonkernelvars, bestcurrsol, lbvarmap, twolevel, usebestsol,
    2254 heurdata->usetransprob, heurdata->translbkernel, bw_contkernelcount,
    2255 bw_contnonkernelcount, bw_kernelcount, bw_nonkernelcount, bw_intkernelcount,
    2256 bw_intnonkernelcount, bw_ncontkernelvars, bw_ncontnonkernelvars, bw_nkernelvars, bw_nnonkernelvars,
    2257 bw_nintkernelvars, bw_nintnonkernelvars, block2index, varlabels, blklbl_offset, nvars, nbinintvars) );
    2258 }
    2259 else
    2260 {
    2261 /* filling of the kernels with the variables */
    2262 SCIP_CALL( fillKernels(scip, vars, binintvars,
    2263 bw_contkernelvars, bw_contnonkernelvars, bw_kernelvars, bw_nonkernelvars, NULL, NULL,
    2264 bestcurrsol, lbvarmap, twolevel, usebestsol, heurdata->usetransprob,
    2265 heurdata->translbkernel, bw_contkernelcount, bw_contnonkernelcount, bw_kernelcount,
    2266 bw_nonkernelcount, NULL, NULL, bw_ncontkernelvars, bw_ncontnonkernelvars, bw_nkernelvars, bw_nnonkernelvars,
    2267 NULL, NULL, block2index, varlabels, blklbl_offset, nvars, nbinintvars) );
    2268 }
    2269
    2270 /* sorting of bucket variables according to the reduced costs in non-decreasing order */
    2271 if( heurdata->redcostsort || heurdata->redcostlogsort )
    2272 {
    2273 SCIP_CALL( reducedCostSort(scip, bw_contnonkernelvars, bw_nonkernelvars, bw_intnonkernelvars,
    2274 &bw_cont_redcost, &bw_redcost, &bw_int_redcost, bw_ncontnonkernelvars, bw_nnonkernelvars,
    2275 bw_nintnonkernelvars, twolevel, nblocks) );
    2276 }
    2277
    2278 /* initialization of the buckets */
    2279 /* determine the amount of buckets needed */
    2280 /* continuous variables are not included when calculating the number of buckets, since they are easier to handle */
    2281 nusedratios = 0;
    2282 if( twolevel )
    2283 {
    2284 SCIP_Real intratio;
    2285 SCIP_Real binratio;
    2286
    2287 nbuckets = 0;
    2288 for( b = 0; b < nblocks + 1; b++ )
    2289 {
    2290 /* calculate the upper gauss bracket of the ratio of the integer (binary) kernel and non kernel variables */
    2291 if( bw_nintnonkernelvars[b] > 0 && bw_nintkernelvars[b] > 0 )
    2292 intratio = SCIPceil(scip, bw_nintnonkernelvars[b] / (SCIP_Real)bw_nintkernelvars[b]);
    2293 else
    2294 intratio = SCIPinfinity(scip);
    2295
    2296 if( bw_nnonkernelvars[b] > 0 && bw_nkernelvars[b] > 0 )
    2297 binratio = SCIPceil(scip, bw_nnonkernelvars[b] / (SCIP_Real)bw_nkernelvars[b]);
    2298 else
    2299 binratio = SCIPinfinity(scip);
    2300
    2301 if( !SCIPisInfinity(scip, intratio) )
    2302 {
    2303 nbuckets += (int)intratio;
    2304 nusedratios++;
    2305 }
    2306 if( !SCIPisInfinity(scip, binratio) )
    2307 {
    2308 nbuckets += (int)binratio;
    2309 nusedratios++;
    2310 }
    2311 }
    2312 }
    2313 else
    2314 {
    2315 /* take the rounded down average bucket ratio of all blocks*/
    2316 nbuckets = 0;
    2317 for( b = 0; b < nblocks + 1; b++ )
    2318 {
    2319 if( bw_nnonkernelvars[b] > 0 && bw_nkernelvars[b] > 0 )
    2320 {
    2321 nbuckets += (int)SCIPceil(scip, (SCIP_Real)bw_nnonkernelvars[b] / (SCIP_Real)bw_nkernelvars[b]);
    2322 nusedratios++;
    2323 }
    2324 }
    2325 }
    2326 /* taking the average ratio as final one for all blocks */
    2327 if( nusedratios > 0 )
    2328 nbuckets = (int)SCIPceil(scip, (SCIP_Real)nbuckets / (SCIP_Real)nusedratios);
    2329 else
    2330 nbuckets = 0;
    2331
    2332 /* determine the amount of iterations over the buckets/ amount of investigated buckets */
    2333 iters = MIN(nbuckets, heurdata->maxbucks) + 1;
    2334
    2335 /* create an extra array for the bucket constraints for hashmap creation in createBucketlistAndBuckets() */
    2336 SCIP_CALL( SCIPduplicateBufferArray(scip, &bucketconss, conss, nconss) );
    2337
    2338 /* create the bucketlist and initialize as much buckets as investigated later on with a subscip for every bucket */
    2339 SCIP_CALL( createBucketlistAndBuckets(scip, heurdata->usetransprob, iters - 1, &bucketlist, &success) );
    2340 if( !success )
    2341 goto TERMINATE;
    2342
    2343 /* fill every bucket with its variables, nothing to do for the first ('kernel') bucket -> k = 1 */
    2344 if( iters > 1 )
    2345 {
    2346 SCIP_CALL( fillBuckets(scip, &bucketlist,
    2347 bw_contnonkernelvars, bw_nonkernelvars, bw_intnonkernelvars,
    2348 bw_ncontnonkernelvars, bw_nnonkernelvars, bw_nintnonkernelvars,
    2349 bw_cont_redcost, bw_redcost, bw_int_redcost,
    2350 twolevel, heurdata->redcostlogsort, iters - 1, nblocks) );
    2351 }
    2352
    2353 /* build the kernelvariables out of each blocks kernel variables */
    2354 j = 0;
    2355 n = 0;
    2356 m = 0;
    2357 for( b = 0; b < nblocks + 1; b++ )
    2358 {
    2359 for( l = 0; l < bw_ncontkernelvars[b]; l++ )
    2360 contkernelvars[j++] = bw_contkernelvars[b][l];
    2361
    2362 for( l = 0; l < bw_nkernelvars[b]; l++ )
    2363 kernelvars[n++] = bw_kernelvars[b][l];
    2364
    2365 if( twolevel )
    2366 {
    2367 for( l = 0; l < bw_nintkernelvars[b]; l++ )
    2368 intkernelvars[m++] = bw_intkernelvars[b][l];
    2369 }
    2370 }
    2371 assert(j == ncontkernelvars);
    2372 assert(n == nkernelvars);
    2373 if( twolevel )
    2374 assert(m == nintkernelvars);
    2375
    2376 /* loop over all buckets, solve the small MIP defined by the bucket, adjust kernel */
    2377 mipgap = 0.0;
    2378 nodesleft = heurdata->maxnodes;
    2379 nnodes = 0;
    2380 for( k = 0; k < iters; k++ )
    2381 {
    2382 SCIP_Bool found;
    2383 SCIP_Bool infeasible;
    2384 SCIP_Bool fixed;
    2385 SCIP_Real lb;
    2386 SCIP_Real ub;
    2387 SCIP_Real timeused;
    2388 SCIP_Real totaltimelimit;
    2389 SCIP_Real subtimelimit;
    2390 SCIP_VAR *var;
    2391
    2392 bucket = &bucketlist->buckets[k];
    2393
    2394 /* do not compute the current bucket if the number of free bin/int variables exceeds some percentage */
    2395 if( SCIPisGT(scip, (SCIP_Real)(nkernelvars + nintkernelvars + bucket->nbucketvars + bucket->nintbucketvars),
    2396 heurdata->maxbuckfrac * nbinintvars) )
    2397 continue;
    2398
    2399 /* fix all integer and binary variables to zero that are neither in the kernel nor in the current bucket */
    2400 for( i = 0; i < nvars ; i++ )
    2401 {
    2402 found = FALSE;
    2403 infeasible = TRUE;
    2404 fixed = FALSE;
    2405
    2406 var = vars[i];
    2407
    2408 if( var == NULL )
    2409 SCIPdebugMsg(scip, "Variable is null!\n");
    2410
    2412 SCIPdebugMsg(scip, "Hit a cont variable");
    2413
    2414 /* search for the current variable in the kernel and in the current bucket */
    2415 SCIP_CALL( searchKernelAndBucket(bucket, contkernelvars, ncontkernelvars, kernelvars, nkernelvars,
    2416 intkernelvars, nintkernelvars, var, &found) );
    2417
    2418 if( found == TRUE )
    2419 continue;
    2420
    2421 if( var == NULL )
    2422 goto TERMINATE;
    2423
    2424 /* variable not in kernel or bucket -> deactivate by fixing to bound or zero */
    2425 assert(SCIPvarIsActive(var));
    2426
    2427 var = bucket->scip2sub[SCIPvarGetProbindex(var)];
    2428 if( var != NULL )
    2429 {
    2430 lb = SCIPvarGetLbLocal(vars[i]);
    2431 ub = SCIPvarGetUbLocal(vars[i]);
    2432
    2433 /* fix to lb if finite, else to zero if ub nonnegative, else to ub */
    2434 if( !SCIPisInfinity(scip, -lb) )
    2435 {
    2436 SCIP_CALL( SCIPfixVar(bucket->subscip, var, lb, &infeasible, &fixed) );
    2437 }
    2438 else if( ub >= 0.0 )
    2439 {
    2440 SCIP_CALL( SCIPfixVar(bucket->subscip, var, 0.0, &infeasible, &fixed) );
    2441 }
    2442 else
    2443 {
    2444 SCIP_CALL( SCIPfixVar(bucket->subscip, var, ub, &infeasible, &fixed) );
    2445 }
    2446 assert(!infeasible);
    2447 assert(fixed);
    2448 }
    2449 }
    2450
    2451 /* construct a constraint that ensures the use of the bucketvariables */
    2452 if( heurdata->addUseConss && bucket->bucketvars != NULL )
    2453 SCIP_CALL( addUseConstraint(bucket) );
    2454
    2455 /* add objective cutoff if desired */
    2456 if( heurdata->objcutoff )
    2457 {
    2459
    2460 if( !SCIPisInfinity(scip, cutoff) )
    2461 SCIP_CALL( SCIPsetObjlimit(bucket->subscip, cutoff) );
    2462 }
    2463
    2464#ifdef DKS_WRITE_PROBLEMS
    2465 if( bucket->number < 0 )
    2466 {
    2467 char name[SCIP_MAXSTRLEN];
    2468 /* write the current bucket problem */
    2469 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "subscip_bucket_%d.lp", bucket->number);
    2470 SCIP_CALL( SCIPwriteOrigProblem(bucket->subscip, name, NULL, FALSE) );
    2471 }
    2472#endif
    2473 /* update the time limit */
    2474 timeused = SCIPgetTotalTime(scip);
    2475 SCIP_CALL( SCIPgetRealParam(scip, "limits/time", &totaltimelimit) );
    2476 subtimelimit = totaltimelimit - timeused;
    2477 if( subtimelimit > 1.0 )
    2478 SCIP_CALL( SCIPsetRealParam(bucket->subscip, "limits/time", subtimelimit) );
    2479 else
    2480 goto TERMINATE;
    2481
    2482 /* update the remaining number of nodes */
    2483 nodesleft -= nnodes;
    2484
    2485 /* get the node limit which results from evenly distributing the remaining nodes */
    2486 if( nodesleft > 0 )
    2487 {
    2488 SCIP_Longint nodes_evenly_dist;
    2489 nodes_evenly_dist = (SCIP_Longint)SCIPceil(scip, ((SCIP_Real)nodesleft) / ((SCIP_Real)(iters - k)));
    2490 if( 1LL > nodes_evenly_dist )
    2491 nnodes = 1LL;
    2492 else
    2493 nnodes = nodes_evenly_dist;
    2494 }
    2495 else
    2496 {
    2497 SCIPdebugMsg(scip, "Overall node limit reached.\n");
    2498 goto TERMINATE;
    2499 }
    2500
    2501 /* set the node limit parameter for the subscip */
    2502 SCIP_CALL( SCIPsetLongintParam(bucket->subscip, "limits/nodes", nnodes) );
    2503
    2504 /* set the mipgap parameter for the subscip */
    2505 SCIP_CALL( SCIPsetRealParam(bucket->subscip, "limits/gap", mipgap) );
    2506
    2507 /* solve the current subscip */
    2508 SCIP_CALL_ABORT( SCIPsolve(bucket->subscip) );
    2509 status = SCIPgetStatus(bucket->subscip);
    2510
    2511 /* compute the nodes used by the subscip */
    2512 nnodes = SCIPgetNNodes(bucket->subscip);
    2513
    2514 if( bucket->number == 0 )
    2515 *result = SCIP_DIDNOTFIND;
    2516
    2517 /* if the node limit was reached, increase the mip gap */
    2518 /* gapcall = 1 signals node limit was reached before, -1 signals gap limit, 0 means no status was reached */
    2519 if( status == SCIP_STATUS_NODELIMIT )
    2520 {
    2521 if( gapcall != 0 )
    2522 gapfactor /= 2.0;
    2523
    2524 mipgap += (heurdata->buckmaxgap / iters) * gapfactor;
    2525 gapcall = 1;
    2526 }
    2527 else if( status == SCIP_STATUS_GAPLIMIT )
    2528 {
    2529 if( gapcall != 0 )
    2530 gapfactor /= 2.0;
    2531
    2532 mipgap -= (heurdata->buckmaxgap / iters) * gapfactor;
    2533 gapcall = -1;
    2534 }
    2535
    2536 /* check if the solution is better if one of the three cases occur:
    2537 - solution is optimal
    2538 - solution reached gaplimit
    2539 - node limit is reached and there is one solution */
    2540
    2541 if( status == SCIP_STATUS_OPTIMAL || status == SCIP_STATUS_GAPLIMIT ||
    2542 (status == SCIP_STATUS_NODELIMIT && SCIPgetNSols(bucket->subscip) > 0) )
    2543 {
    2544 SCIP_Real val;
    2545 SCIP_SOL* sol;
    2546
    2547 sol = SCIPgetBestSol(bucket->subscip);
    2548 val = SCIPgetSolOrigObj(bucket->subscip, sol);
    2549
    2550 /* if there is no solution yet or if the value of the current solution is better than the saved solution */
    2551 if( SCIPisInfinity(scip, bestlocval) || val <= bestlocval )
    2552 {
    2553 bestlocval = val;
    2554 nbestbucket = bucket->number;
    2555
    2556 if( heurdata->primalonly )
    2557 break;
    2558
    2559 /* adjust the kernel(/-variables) */
    2560 SCIP_CALL( adjustKernelVars(scip, bucket, &contkernelvars, &ncontkernelvars, (int)maxcontkernelsize,
    2561 &kernelvars, &nkernelvars, (int)maxkernelsize, &intkernelvars, &nintkernelvars, (int)maxintkernelsize,
    2562 twolevel) );
    2563 }
    2564 success = FALSE;
    2565 }
    2566 else if( status == SCIP_STATUS_NODELIMIT )
    2567 SCIPdebugMsg(scip, "Bucket reached node limit. No optimal solution available.\n");
    2568 else if( status == SCIP_STATUS_INFEASIBLE )
    2569 SCIPdebugMsg(scip, "Bucket infeasible, starting over with next one\n");
    2570 else
    2571 {
    2572 SCIPdebugMsg(scip, "Bucket solving status %d is not supported\n", status);
    2573 goto TERMINATE;
    2574 }
    2575
    2577
    2578#ifdef DKS_KERNEL_INFO
    2579 fclose(variable_info);
    2580#endif
    2581 }
    2582
    2583 /* if a solution of a bucket was found, save it to the scip */
    2584 if( nbestbucket > -1 )
    2585 {
    2586 SCIP_SOL* newsol;
    2587 SCIP_SOL* bestsol;
    2588 BUCKET* bestbucket;
    2589
    2590 /* bucket with the best solution */
    2591 bestbucket = &bucketlist->buckets[nbestbucket];
    2592
    2593 /* get the best solution */
    2594 bestsol = SCIPgetBestSol(bestbucket->subscip);
    2595 if( bestsol == NULL )
    2596 {
    2597 SCIPdebugMsg(scip, "Function SCIPgetBestSol() has returned a NULL pointer\n");
    2598 *result = SCIP_DIDNOTFIND;
    2599 goto TERMINATE;
    2600 }
    2601
    2602 SCIPdebug( SCIP_CALL( SCIPprintSol(bestbucket->subscip, bestsol, NULL, FALSE) ) );
    2603
    2604 /* extract the values of all variables in the best solution of a bucket found */
    2605 SCIP_CALL( SCIPtranslateSubSol(scip, bestbucket->subscip, bestsol, heur, bestbucket->scip2sub, &newsol) );
    2606
    2607 SCIPdebug( SCIP_CALL( SCIPprintSol(scip, newsol, NULL, FALSE) ) );
    2608 SCIPdebugMsg(scip, "Objective value %.2f\n", SCIPgetSolOrigObj(scip, newsol));
    2609 SCIPdebugMsg(scip, "Objective value of subscip %.2f\n", SCIPgetSolOrigObj(bestbucket->subscip, bestsol));
    2610
    2611 /* check the feasibilty of the new created solution, save it if so and free it */
    2612 SCIP_CALL( SCIPtrySolFree(scip, &newsol, FALSE, FALSE, TRUE, TRUE, TRUE, &success) );
    2613
    2614 if( !success )
    2615 {
    2616 SCIPdebugMsg(scip, "Solution copy failed\n");
    2617 *result = SCIP_DIDNOTFIND;
    2618 }
    2619 else
    2620 {
    2621 SCIPdebugMsg(scip, "Solution copy successfull after %f sec\n", SCIPgetSolvingTime(scip));
    2622 *result = SCIP_FOUNDSOL;
    2623 }
    2624 }
    2625 else
    2626 {
    2627 SCIPdebugMsg(scip, "no solution found\n");
    2628 *result = SCIP_DIDNOTFIND;
    2629 }
    2630
    2631 /* remember if the heuristic has not provided a solution */
    2632 if( *result != SCIP_FOUNDSOL )
    2633 heurdata->uselesscall = TRUE;
    2634
    2635TERMINATE:
    2636 if( bucketconss != NULL )
    2637 SCIPfreeBufferArray(scip, &bucketconss);
    2638
    2639 if( bw_intnonkernelcount != NULL )
    2640 SCIPfreeBufferArray(scip, &bw_intnonkernelcount);
    2641
    2642 if( bw_intkernelcount != NULL )
    2643 SCIPfreeBufferArray(scip, &bw_intkernelcount);
    2644
    2645 if( intnonkernelvars != NULL )
    2646 SCIPfreeBufferArray(scip, &intnonkernelvars);
    2647
    2648 if( intkernelvars != NULL )
    2649 SCIPfreeBufferArray(scip, &intkernelvars);
    2650
    2651 if( bw_nonkernelcount != NULL )
    2652 SCIPfreeBufferArray(scip, &bw_nonkernelcount);
    2653
    2654 if( bw_kernelcount != NULL )
    2655 SCIPfreeBufferArray(scip, &bw_kernelcount);
    2656
    2657 if( bw_contnonkernelcount != NULL )
    2658 SCIPfreeBufferArray(scip, &bw_contnonkernelcount);
    2659
    2660 if( bw_contkernelcount != NULL )
    2661 SCIPfreeBufferArray(scip, &bw_contkernelcount);
    2662
    2663 if( binintvars != NULL )
    2664 SCIPfreeBufferArray(scip, &binintvars);
    2665
    2666 if( nonkernelvars != NULL )
    2667 SCIPfreeBufferArray(scip, &nonkernelvars);
    2668
    2669 if( kernelvars != NULL )
    2670 SCIPfreeBufferArray(scip, &kernelvars);
    2671
    2672 if( contnonkernelvars != NULL )
    2673 SCIPfreeBufferArray(scip, &contnonkernelvars);
    2674
    2675 if( contkernelvars != NULL )
    2676 SCIPfreeBufferArray(scip, &contkernelvars);
    2677
    2678 if( bw_intkernelvars != NULL )
    2679 {
    2680 for( b = nblocks; b >= 0; b-- )
    2681 {
    2682 if( bw_intnonkernelvars[b] != NULL )
    2683 SCIPfreeBufferArray(scip, &(bw_intnonkernelvars[b]));
    2684 if( bw_intkernelvars[b] != NULL )
    2685 SCIPfreeBufferArray(scip, &(bw_intkernelvars[b]));
    2686 }
    2687 }
    2688
    2689 if( bw_kernelvars != NULL )
    2690 {
    2691 for( b = nblocks; b >= 0; b-- )
    2692 {
    2693 if( bw_nonkernelvars[b] != NULL )
    2694 SCIPfreeBufferArray(scip, &(bw_nonkernelvars[b]));
    2695 if( bw_kernelvars[b] != NULL )
    2696 SCIPfreeBufferArray(scip, &(bw_kernelvars[b]));
    2697 }
    2698 }
    2699
    2700 if( bw_contkernelvars != NULL )
    2701 {
    2702 for( b = nblocks; b >= 0; b-- )
    2703 {
    2704 if( bw_contnonkernelvars[b] != NULL )
    2705 SCIPfreeBufferArray(scip, &(bw_contnonkernelvars[b]));
    2706 if( bw_contkernelvars[b] != NULL )
    2707 SCIPfreeBufferArray(scip, &(bw_contkernelvars[b]));
    2708 }
    2709 }
    2710
    2711 if( bw_intnonkernelvars != NULL )
    2712 SCIPfreeBufferArray(scip, &bw_intnonkernelvars);
    2713
    2714 if( bw_intkernelvars != NULL )
    2715 SCIPfreeBufferArray(scip, &bw_intkernelvars);
    2716
    2717 if( bw_nonkernelvars != NULL )
    2718 SCIPfreeBufferArray(scip, &bw_nonkernelvars);
    2719
    2720 if( bw_kernelvars != NULL )
    2721 SCIPfreeBufferArray(scip, &bw_kernelvars);
    2722
    2723 if( bw_contnonkernelvars != NULL )
    2724 SCIPfreeBufferArray(scip, &bw_contnonkernelvars);
    2725
    2726 if( bw_contkernelvars != NULL )
    2727 SCIPfreeBufferArray(scip, &bw_contkernelvars);
    2728
    2729 if( bw_nintnonkernelvars != NULL )
    2730 SCIPfreeBufferArray(scip, &bw_nintnonkernelvars);
    2731
    2732 if( bw_nintkernelvars != NULL )
    2733 SCIPfreeBufferArray(scip, &bw_nintkernelvars);
    2734
    2735 if( bw_nnonkernelvars != NULL )
    2736 SCIPfreeBufferArray(scip, &bw_nnonkernelvars);
    2737
    2738 if( bw_nkernelvars != NULL )
    2739 SCIPfreeBufferArray(scip, &bw_nkernelvars);
    2740
    2741 if( bw_ncontnonkernelvars != NULL )
    2742 SCIPfreeBufferArray(scip, &bw_ncontnonkernelvars);
    2743
    2744 if( bw_ncontkernelvars != NULL )
    2745 SCIPfreeBufferArray(scip, &bw_ncontkernelvars);
    2746
    2747 if( block2index != NULL )
    2748 {
    2749 if( nblocklabels > 0 )
    2750 {
    2751 assert(blocklabels != NULL);
    2752 SCIPfreeBlockMemoryArray(scip, &block2index, blocklabels[nblocklabels - 1] + 1 + blklbl_offset);
    2753 }
    2754 else
    2755 SCIPfreeBlockMemoryArray(scip, &block2index, 1);
    2756 }
    2757
    2758 if( blocklabels != NULL )
    2759 SCIPfreeBufferArray(scip, &blocklabels);
    2760
    2761 if( conslabels != NULL )
    2762 SCIPfreeBufferArray(scip, &conslabels);
    2763
    2764 if( varlabels != NULL )
    2765 SCIPfreeBufferArray(scip, &varlabels);
    2766
    2767 SCIP_CALL( freeRedcostArrays(scip, &bw_cont_redcost, &bw_redcost, &bw_int_redcost, nblocks) );
    2768
    2769 if( lbvarmap != NULL )
    2770 SCIPhashmapFree(&lbvarmap);
    2771
    2772 if( bucketlist != NULL )
    2773 {
    2774 for( k = bucketlist->nbuckets - 1; k >= 1; k-- )
    2775 {
    2776 SCIP_CALL( freeBucket(scip, &bucketlist->buckets[k]) );
    2777 SCIP_CALL( freeBucketArrays(scip, &bucketlist->buckets[k], twolevel) );
    2778 }
    2779 SCIP_CALL( freeBucket(scip, &bucketlist->buckets[0]) );
    2780 }
    2781
    2782 if( bucketlist != NULL )
    2783 {
    2784 SCIP_CALL( freeBucketlist(&bucketlist, iters) );
    2785 }
    2786
    2787 SCIPdebugMsg(scip, "Leave dks heuristic\n");
    2788
    2789 return SCIP_OKAY;
    2790}
    2791
    2792
    2793/*
    2794 * primal heuristic specific interface methods
    2795 */
    2796
    2797/** creates the DKS primal heuristic and includes it in SCIP */
    2799 SCIP* scip /**< SCIP data structure */
    2800 )
    2801{
    2802 SCIP_HEURDATA* heurdata = NULL;
    2803 SCIP_HEUR* heur = NULL;
    2804
    2805 /* create dks primal heuristic data */
    2806 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    2807 assert(heurdata != NULL);
    2808 heurdata->ncalls = 0;
    2809 heurdata->uselesscall = FALSE;
    2810
    2811 /* include primal heuristic */
    2814 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecDKS, heurdata) );
    2815
    2816 assert(heur != NULL);
    2817
    2818 /* set non fundamental callbacks via setter functions */
    2819 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyDKS) );
    2820 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeDKS) );
    2821
    2822 /* add dks primal heuristic parameters */
    2823 SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxbucks",
    2824 "maximal number of buckets to be investigated",
    2825 &heurdata->maxbucks, TRUE, DEFAULT_MAXBUCKS, 1, 100, NULL, NULL) );
    2826
    2827 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/kernelsizefactor",
    2828 "factor with which the initial kernel size can grow max",
    2829 &heurdata->kernelsizefactor, TRUE, DEFAULT_KERNELSIZEFACTOR, 1.0, 10.0, NULL, NULL) );
    2830
    2831 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/addUseConss",
    2832 "should a constraint be added ensuring that bucket variables are used?",
    2833 &heurdata->addUseConss, TRUE, DEFAULT_ADDUSECONSS, NULL, NULL) );
    2834
    2835 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/linkbucksize",
    2836 "should the linking variables in the kernel influence the size of the buckets?",
    2837 &heurdata->linkbucksize, TRUE, DEFAULT_LINKBUCKSIZE, NULL, NULL) );
    2838
    2839 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/translbkernel",
    2840 "should a variable with different lower bound in transformed and original problem be in the kernel?",
    2841 &heurdata->translbkernel, TRUE, DEFAULT_TRANSLBKERNEL, NULL, NULL) );
    2842
    2843 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/lesslockskernel",
    2844 "should a variable with max one uplock and one downlock be in the kernel?",
    2845 &heurdata->lesslockskernel, TRUE, DEFAULT_LESSLOCKSKERNEL, NULL, NULL) );
    2846
    2847 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/usetransprob",
    2848 "should dks use the transformed problem?",
    2849 &heurdata->usetransprob, TRUE, DEFAULT_USETRANSPROB, NULL, NULL) );
    2850
    2851 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/buckmaxgap",
    2852 "defines the maximum mipgap a bucket can be solved to",
    2853 &heurdata->buckmaxgap, TRUE, DEFAULT_BUCKMAXGAP, 0.0, 1.0, NULL, NULL) );
    2854
    2855 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/maxlinkscore",
    2856 "defines a bound to the linkscore of the decomp",
    2857 &heurdata->maxlinkscore, TRUE, DEFAULT_MAXLINKSCORE, 0.0, 1.0, NULL, NULL) );
    2858
    2859 SCIP_CALL( SCIPaddRealParam(scip, "heuristics/" HEUR_NAME "/maxbuckfrac",
    2860 "defines a maximal share of bin/int variables for a bucket to be respected",
    2861 &heurdata->maxbuckfrac, TRUE, DEFAULT_MAXBUCKFRAC, 0.0, 1.0, NULL, NULL) );
    2862
    2863 SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/" HEUR_NAME "/maxnodes",
    2864 "maximum number of nodes to regard in all subproblems",
    2865 &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) );
    2866
    2867 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/usetwolevel",
    2868 "should a two level bucket structure be used if possible?",
    2869 &heurdata->usetwolevel, FALSE, DEFAULT_USETWOLEVEL, NULL, NULL) );
    2870
    2871 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/usedecomp",
    2872 "should a decomposition be used if given?",
    2873 &heurdata->usedecomp, FALSE, DEFAULT_USEDECOMP, NULL, NULL) );
    2874
    2875 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/usebestsol",
    2876 "should the best solution instead of the LP solution be used?",
    2877 &heurdata->usebestsol, FALSE, DEFAULT_USEBESTSOL, NULL, NULL) );
    2878
    2879 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/redcostsort",
    2880 "should the bucket variables be sorted by reduced costs in the LP solution?",
    2881 &heurdata->redcostsort, FALSE, DEFAULT_REDCOSTSORT, NULL, NULL) );
    2882
    2883 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/primalonly",
    2884 "should the heuristic terminate after the first primal solution is found?",
    2885 &heurdata->primalonly, FALSE, DEFAULT_PRIMALONLY, NULL, NULL) );
    2886
    2887 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/redcostlogsort",
    2888 "should the bucket variables be sorted logarithmically by reduced costs in the LP solution?",
    2889 &heurdata->redcostlogsort, FALSE, DEFAULT_REDCOSTLOGSORT, NULL, NULL) ) ;
    2890
    2891 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/objcutoff",
    2892 "should the next solution at least satisfy the old objective?",
    2893 &heurdata->objcutoff, FALSE, DEFAULT_OBJCUTOFF, NULL, NULL) );
    2894
    2895 SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/runbinprobsonly",
    2896 "should the heuristic be used only for binary problems or problems with integer and binary variables?",
    2897 &heurdata->runbinprobsonly, FALSE, DEFAULT_RUNBINPROBSONLY, NULL, NULL) );
    2898
    2899 return SCIP_OKAY;
    2900}
    SCIP_VAR ** b
    Definition: circlepacking.c:65
    Constraint handler for linear constraints in their most general form, .
    methods for debugging
    #define NULL
    Definition: def.h:255
    #define SCIP_MAXSTRLEN
    Definition: def.h:276
    #define SCIP_Longint
    Definition: def.h:148
    #define SCIP_INVALID
    Definition: def.h:185
    #define SCIP_Bool
    Definition: def.h:98
    #define MIN(x, y)
    Definition: def.h:231
    #define SCIP_Real
    Definition: def.h:163
    #define TRUE
    Definition: def.h:100
    #define FALSE
    Definition: def.h:101
    #define MAX(x, y)
    Definition: def.h:227
    #define SCIP_CALL_ABORT(x)
    Definition: def.h:341
    #define SCIP_LONGINT_MAX
    Definition: def.h:149
    #define SCIP_CALL(x)
    Definition: def.h:362
    #define nnodes
    Definition: gastrans.c:74
    SCIP_RETCODE SCIPcreateConsBasicLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
    SCIP_RETCODE SCIPcopyPlugins(SCIP *sourcescip, SCIP *targetscip, SCIP_Bool copyreaders, SCIP_Bool copypricers, SCIP_Bool copyconshdlrs, SCIP_Bool copyconflicthdlrs, SCIP_Bool copypresolvers, SCIP_Bool copyrelaxators, SCIP_Bool copyseparators, SCIP_Bool copycutselectors, SCIP_Bool copypropagators, SCIP_Bool copyheuristics, SCIP_Bool copyeventhdlrs, SCIP_Bool copynodeselectors, SCIP_Bool copybranchrules, SCIP_Bool copyiisfinders, SCIP_Bool copydisplays, SCIP_Bool copydialogs, SCIP_Bool copytables, SCIP_Bool copyexprhdlrs, SCIP_Bool copynlpis, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
    Definition: scip_copy.c:276
    SCIP_RETCODE SCIPcopyVars(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool global)
    Definition: scip_copy.c:1167
    SCIP_RETCODE SCIPgetConsCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_CONS *sourcecons, SCIP_CONS **targetcons, SCIP_CONSHDLR *sourceconshdlr, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *name, 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_Bool global, SCIP_Bool *valid)
    Definition: scip_copy.c:1580
    SCIP_RETCODE SCIPcopyProb(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, const char *name)
    Definition: scip_copy.c:529
    SCIP_RETCODE SCIPtranslateSubSol(SCIP *scip, SCIP *subscip, SCIP_SOL *subsol, SCIP_HEUR *heur, SCIP_VAR **subvars, SCIP_SOL **newsol)
    Definition: scip_copy.c:1397
    SCIP_RETCODE SCIPcopyParamSettings(SCIP *sourcescip, SCIP *targetscip)
    Definition: scip_copy.c:2547
    SCIP_RETCODE SCIPcopyLimits(SCIP *sourcescip, SCIP *targetscip)
    Definition: scip_copy.c:3292
    void SCIPgetDecomps(SCIP *scip, SCIP_DECOMP ***decomps, int *ndecomps, SCIP_Bool original)
    Definition: scip_dcmp.c:263
    int SCIPdecompGetNBlocks(SCIP_DECOMP *decomp)
    Definition: dcmp.c:279
    void SCIPdecompGetConsLabels(SCIP_DECOMP *decomp, SCIP_CONS **conss, int *labels, int nconss)
    Definition: dcmp.c:198
    void SCIPdecompGetVarsLabels(SCIP_DECOMP *decomp, SCIP_VAR **vars, int *labels, int nvars)
    Definition: dcmp.c:149
    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 SCIPgetNIntVars(SCIP *scip)
    Definition: scip_prob.c:2340
    const char * SCIPgetProbName(SCIP *scip)
    Definition: scip_prob.c:1242
    SCIP_RETCODE SCIPwriteOrigProblem(SCIP *scip, const char *filename, const char *extension, SCIP_Bool genericnames)
    Definition: scip_prob.c:742
    SCIP_RETCODE SCIPsetObjlimit(SCIP *scip, SCIP_Real objlimit)
    Definition: scip_prob.c:1661
    int SCIPgetNBinImplVars(SCIP *scip)
    Definition: scip_prob.c:2432
    int SCIPgetNOrigBinVars(SCIP *scip)
    Definition: scip_prob.c:2867
    SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
    Definition: scip_prob.c:2115
    int SCIPgetNOrigConss(SCIP *scip)
    Definition: scip_prob.c:3712
    SCIP_VAR ** SCIPgetOrigVars(SCIP *scip)
    Definition: scip_prob.c:2811
    int SCIPgetNOrigIntVars(SCIP *scip)
    Definition: scip_prob.c:2896
    SCIP_CONS ** SCIPgetConss(SCIP *scip)
    Definition: scip_prob.c:3666
    int SCIPgetNVars(SCIP *scip)
    Definition: scip_prob.c:2246
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    int SCIPgetNConss(SCIP *scip)
    Definition: scip_prob.c:3620
    SCIP_VAR ** SCIPgetVars(SCIP *scip)
    Definition: scip_prob.c:2201
    int SCIPgetNOrigVars(SCIP *scip)
    Definition: scip_prob.c:2838
    int SCIPgetNOrigBinImplVars(SCIP *scip)
    Definition: scip_prob.c:2952
    int SCIPgetNOrigIntImplVars(SCIP *scip)
    Definition: scip_prob.c:2979
    int SCIPgetNIntImplVars(SCIP *scip)
    Definition: scip_prob.c:2477
    SCIP_CONS ** SCIPgetOrigConss(SCIP *scip)
    Definition: scip_prob.c:3739
    SCIP_RETCODE SCIPwriteTransProblem(SCIP *scip, const char *filename, const char *extension, SCIP_Bool genericnames)
    Definition: scip_prob.c:789
    int SCIPgetNBinVars(SCIP *scip)
    Definition: scip_prob.c:2293
    void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
    Definition: misc.c:3095
    void * SCIPhashmapEntryGetImage(SCIP_HASHMAPENTRY *entry)
    Definition: misc.c:3613
    SCIP_Real SCIPhashmapGetImageReal(SCIP_HASHMAP *hashmap, void *origin)
    Definition: misc.c:3344
    SCIP_RETCODE SCIPhashmapSetImageReal(SCIP_HASHMAP *hashmap, void *origin, SCIP_Real image)
    Definition: misc.c:3434
    int SCIPhashmapGetNEntries(SCIP_HASHMAP *hashmap)
    Definition: misc.c:3584
    SCIP_HASHMAPENTRY * SCIPhashmapGetEntry(SCIP_HASHMAP *hashmap, int entryidx)
    Definition: misc.c:3592
    SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
    Definition: misc.c:3061
    void * SCIPhashmapEntryGetOrigin(SCIP_HASHMAPENTRY *entry)
    Definition: misc.c:3603
    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 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 SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
    Definition: scip_param.c:307
    SCIP_RETCODE SCIPunfixParam(SCIP *scip, const char *name)
    Definition: scip_param.c:385
    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 SCIPsetRealParam(SCIP *scip, const char *name, SCIP_Real value)
    Definition: scip_param.c:603
    SCIP_RETCODE SCIPincludeHeurDKS(SCIP *scip)
    Definition: heur_dks.c:2798
    int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
    Definition: cons.c:4778
    SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
    Definition: scip_cons.c:940
    SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
    Definition: cons.c:8648
    SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
    Definition: cons.c:8409
    SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
    Definition: cons.c:8558
    SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
    Definition: cons.c:8588
    SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
    Definition: cons.c:8578
    SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
    Definition: cons.c:8608
    SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
    Definition: cons.c:8638
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
    Definition: cons.c:8568
    SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
    Definition: cons.c:8658
    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
    const char * SCIPheurGetName(SCIP_HEUR *heur)
    Definition: heur.c:1467
    void SCIPheurSetData(SCIP_HEUR *heur, SCIP_HEURDATA *heurdata)
    Definition: heur.c:1378
    SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
    Definition: scip_lp.c:174
    SCIP_Longint SCIPgetMemExternEstim(SCIP *scip)
    Definition: scip_mem.c:126
    #define SCIPfreeBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:110
    SCIP_Longint SCIPgetMemUsed(SCIP *scip)
    Definition: scip_mem.c:100
    BMS_BLKMEM * SCIPblkmem(SCIP *scip)
    Definition: scip_mem.c:57
    #define SCIPallocClearBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:97
    #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 SCIPduplicateBufferArray(scip, ptr, source, num)
    Definition: scip_mem.h:132
    #define SCIPallocBlockMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:93
    #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
    SCIP_SOL * SCIPgetBestSol(SCIP *scip)
    Definition: scip_sol.c:2988
    SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
    Definition: scip_sol.c:2353
    int SCIPgetNSols(SCIP *scip)
    Definition: scip_sol.c:2889
    SCIP_RETCODE SCIPtrySolFree(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:4116
    SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
    Definition: scip_sol.c:1892
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1765
    SCIP_RETCODE SCIPfreeTransform(SCIP *scip)
    Definition: scip_solve.c:3438
    SCIP_RETCODE SCIPsolve(SCIP *scip)
    Definition: scip_solve.c:2611
    SCIP_Longint SCIPgetNNodes(SCIP *scip)
    SCIP_Real SCIPgetCutoffbound(SCIP *scip)
    SCIP_Real SCIPgetSolvingTime(SCIP *scip)
    Definition: scip_timing.c:378
    SCIP_Real SCIPgetTotalTime(SCIP *scip)
    Definition: scip_timing.c:351
    SCIP_Real SCIPinfinity(SCIP *scip)
    SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
    SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
    SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
    Definition: var.c:18320
    SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
    Definition: var.c:23642
    SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
    Definition: var.c:24268
    SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
    Definition: var.c:24020
    SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
    Definition: var.c:23453
    SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
    Definition: var.c:24142
    int SCIPvarGetProbindex(SCIP_VAR *var)
    Definition: var.c:23662
    SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
    Definition: var.c:24664
    SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
    Definition: var.c:24234
    SCIP_Real SCIPgetVarRedcost(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:2608
    SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
    Definition: var.c:24120
    SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
    Definition: scip_var.c:10318
    void SCIPsortRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
    void SCIPsortInt(int *intarray, int len)
    int SCIPsnprintf(char *t, int len, const char *s,...)
    Definition: misc.c:10827
    static SCIP_RETCODE fillBuckets(SCIP *scip, BUCKETLIST **bucketlist, SCIP_VAR ***bw_contnonkernelvars, SCIP_VAR ***bw_nonkernelvars, SCIP_VAR ***bw_intnonkernelvars, int *bw_ncontnonkernelvars, int *bw_nnonkernelvars, int *bw_nintnonkernelvars, SCIP_Real **bw_cont_redcost, SCIP_Real **bw_redcost, SCIP_Real **bw_int_redcost, SCIP_Bool twolevel, SCIP_Bool redcostlogsort, int nbuckets, int nblocks)
    Definition: heur_dks.c:702
    static SCIP_RETCODE searchKernelAndBucket(BUCKET *bucket, SCIP_VAR **contkernelvars, int ncontkernelvars, SCIP_VAR **kernelvars, int nkernelvars, SCIP_VAR **intkernelvars, int nintkernelvars, SCIP_VAR *var, SCIP_Bool *found)
    Definition: heur_dks.c:1304
    static SCIP_RETCODE fillKernels(SCIP *scip, SCIP_VAR **vars, SCIP_VAR **binintvars, SCIP_VAR ***bw_contkernelvars, SCIP_VAR ***bw_contnonkernelvars, SCIP_VAR ***bw_kernelvars, SCIP_VAR ***bw_nonkernelvars, SCIP_VAR ***bw_intkernelvars, SCIP_VAR ***bw_intnonkernelvars, SCIP_SOL *bestcurrsol, SCIP_HASHMAP *lbvarmap, SCIP_Bool twolevel, SCIP_Bool usebestsol, SCIP_Bool usetransprob, SCIP_Bool usetranslb, int *bw_contkernelcount, int *bw_contnonkernelcount, int *bw_kernelcount, int *bw_nonkernelcount, int *bw_intkernelcount, int *bw_intnonkernelcount, int *bw_ncontkernelvars, int *bw_ncontnonkernelvars, int *bw_nkernelvars, int *bw_nnonkernelvars, int *bw_nintkernelvars, int *bw_nintnonkernelvars, int *block2index, int *varlabels, int blklbl_offset, int nvars, int nbinintvars)
    Definition: heur_dks.c:369
    #define DEFAULT_OBJCUTOFF
    Definition: heur_dks.c:106
    static SCIP_DECL_HEUREXEC(heurExecDKS)
    Definition: heur_dks.c:1771
    #define DEFAULT_LINKBUCKSIZE
    Definition: heur_dks.c:92
    #define DEFAULT_MAXNODES
    Definition: heur_dks.c:99
    #define DEFAULT_BUCKMAXGAP
    Definition: heur_dks.c:96
    #define DEFAULT_ADDUSECONSS
    Definition: heur_dks.c:91
    static SCIP_RETCODE reducedCostSort(SCIP *scip, SCIP_VAR ***bw_contnonkernelvars, SCIP_VAR ***bw_nonkernelvars, SCIP_VAR ***bw_intnonkernelvars, SCIP_Real ***bw_cont_redcost, SCIP_Real ***bw_redcost, SCIP_Real ***bw_int_redcost, int *bw_ncontnonkernelvars, int *bw_nnonkernelvars, int *bw_nintnonkernelvars, SCIP_Bool twolevel, int nblocks)
    Definition: heur_dks.c:547
    #define HEUR_TIMING
    Definition: heur_dks.c:86
    #define DEFAULT_KERNELSIZEFACTOR
    Definition: heur_dks.c:90
    #define DEFAULT_TRANSLBKERNEL
    Definition: heur_dks.c:93
    #define HEUR_FREQOFS
    Definition: heur_dks.c:84
    #define HEUR_DESC
    Definition: heur_dks.c:80
    static SCIP_RETCODE createBucketlistAndBuckets(SCIP *scip, SCIP_Bool usetransprob, int nbuckets, BUCKETLIST **bucketlist, SCIP_Bool *success)
    Definition: heur_dks.c:1265
    static SCIP_RETCODE freeBucketArrays(SCIP *scip, BUCKET *bucket, SCIP_Bool twolevel)
    Definition: heur_dks.c:947
    #define DEFAULT_REDCOSTLOGSORT
    Definition: heur_dks.c:105
    static SCIP_RETCODE initBucket(BUCKETLIST *bucketlist)
    Definition: heur_dks.c:965
    #define HEUR_DISPCHAR
    Definition: heur_dks.c:81
    #define HEUR_MAXDEPTH
    Definition: heur_dks.c:85
    #define HEUR_PRIORITY
    Definition: heur_dks.c:82
    #define DEFAULT_MAXLINKSCORE
    Definition: heur_dks.c:97
    #define DEFAULT_USETWOLEVEL
    Definition: heur_dks.c:100
    struct Bucket BUCKET
    #define HEUR_NAME
    Definition: heur_dks.c:79
    static SCIP_DECL_HEURFREE(heurFreeDKS)
    Definition: heur_dks.c:1753
    static SCIP_RETCODE getLinkingScoreAndBlocklabels(int *blocklabels, int *varlabels, int *conslabels, SCIP_Real *linkscore, int *nblocklabels, int nblocks, int nvars, int nconss)
    Definition: heur_dks.c:174
    static SCIP_RETCODE adjustKernelVars(SCIP *scip, BUCKET *bucket, SCIP_VAR ***contkernelvars, int *ncontkernelvars, int maxcontkernelsize, SCIP_VAR ***kernelvars, int *nkernelvars, int maxkernelsize, SCIP_VAR ***intkernelvars, int *nintkernelvars, int maxintkernelsize, SCIP_Bool twolevel)
    Definition: heur_dks.c:1388
    #define DEFAULT_MAXBUCKFRAC
    Definition: heur_dks.c:98
    static SCIP_RETCODE freeBucket(SCIP *scip, BUCKET *bucket)
    Definition: heur_dks.c:996
    static SCIP_RETCODE freeRedcostArrays(SCIP *scip, SCIP_Real ***bw_cont_redcost, SCIP_Real ***bw_redcost, SCIP_Real ***bw_int_redcost, int nblocks)
    Definition: heur_dks.c:616
    static SCIP_RETCODE bucketCreateSubscip(BUCKET *bucket, SCIP_Bool usetransprob, SCIP_Bool *success)
    Definition: heur_dks.c:1070
    #define DEFAULT_USEBESTSOL
    Definition: heur_dks.c:102
    #define DEFAULT_REDCOSTSORT
    Definition: heur_dks.c:103
    static SCIP_DECL_HEURCOPY(heurCopyDKS)
    Definition: heur_dks.c:1738
    static SCIP_RETCODE countKernelVariables(SCIP *scip, SCIP_VAR **vars, SCIP_SOL *bestcurrsol, SCIP_HASHMAP *lbvarmap, SCIP_Bool twolevel, SCIP_Bool usebestsol, SCIP_Bool usetransprob, SCIP_Bool usetranslb, int *bw_ncontkernelvars, int *bw_ncontnonkernelvars, int *bw_nkernelvars, int *bw_nnonkernelvars, int *bw_nintkernelvars, int *bw_nintnonkernelvars, int *ncontkernelvars, int *ncontnonkernelvars, int *nkernelvars, int *nnonkernelvars, int *nintkernelvars, int *nintnonkernelvars, int *block2index, int *varlabels, int blklbl_offset, int nvars)
    Definition: heur_dks.c:240
    #define DEFAULT_PRIMALONLY
    Definition: heur_dks.c:104
    static SCIP_RETCODE freeBucketlist(BUCKETLIST **bucketlist, int nbuckets)
    Definition: heur_dks.c:1046
    static SCIP_RETCODE addUseConstraint(BUCKET *bucket)
    Definition: heur_dks.c:1640
    static SCIP_RETCODE initBucketlist(SCIP *scip, BUCKETLIST **bucketlist, int nbuckets)
    Definition: heur_dks.c:1018
    #define HEUR_FREQ
    Definition: heur_dks.c:83
    #define DEFAULT_USEDECOMP
    Definition: heur_dks.c:101
    #define DEFAULT_LESSLOCKSKERNEL
    Definition: heur_dks.c:94
    #define DEFAULT_MAXBUCKS
    Definition: heur_dks.c:89
    #define HEUR_USESSUBSCIP
    Definition: heur_dks.c:87
    #define DEFAULT_RUNBINPROBSONLY
    Definition: heur_dks.c:107
    static SCIP_Bool isInCurrentLogBucket(SCIP *scip, SCIP_Real base, SCIP_Real redcost, SCIP_Real redcostmin, int currentindex, int nbuckets)
    Definition: heur_dks.c:665
    #define DEFAULT_USETRANSPROB
    Definition: heur_dks.c:95
    dks primal heuristic
    methods commonly used by primal heuristics
    memory allocation routines
    public methods for managing constraints
    public methods for managing events
    wrapper functions to map file i/o to standard or zlib file i/o
    public methods for primal heuristics
    public methods for LP management
    public methods for message output
    #define SCIPdebug(x)
    Definition: pub_message.h:93
    #define SCIPdebugMessage
    Definition: pub_message.h:96
    public data structures and miscellaneous methods
    methods for selecting (weighted) k-medians
    public methods for primal CIP solutions
    public methods for branch and bound tree
    public methods for problem variables
    public methods for branching rule plugins and branching
    public methods for constraint handler plugins and constraints
    public methods for problem copies
    public methods for decompositions
    public methods for event handler plugins and event handlers
    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 node selector plugins
    public methods for numerical tolerances
    public methods for SCIP parameter handling
    public methods for global and local (sub)problems
    public methods for random numbers
    public methods for solutions
    public solving methods
    public methods for querying solving statistics
    public methods for statistics table plugins
    public methods for timing
    public methods for the branch-and-bound tree
    public methods for SCIP variables
    default SCIP plugins
    internal methods for storing primal CIP solutions
    int ncontbucketvars
    Definition: heur_dks.c:125
    SCIP_VAR ** bucketvars
    Definition: heur_dks.c:123
    BUCKETLIST * bucketlist
    Definition: heur_dks.c:119
    SCIP_VAR ** scip2sub
    Definition: heur_dks.c:130
    SCIP * subscip
    Definition: heur_dks.c:120
    SCIP_VAR ** sub2scip
    Definition: heur_dks.c:129
    SCIP_VAR ** intbucketvars
    Definition: heur_dks.c:124
    int number
    Definition: heur_dks.c:121
    int nbucketvars
    Definition: heur_dks.c:126
    SCIP_Bool twolevel
    Definition: heur_dks.c:128
    int nintbucketvars
    Definition: heur_dks.c:127
    SCIP_VAR ** contbucketvars
    Definition: heur_dks.c:122
    int nbuckets
    Definition: heur_dks.c:138
    BUCKET * buckets
    Definition: heur_dks.c:137
    SCIP * scip
    Definition: heur_dks.c:136
    #define SCIP_DECOMP_LINKVAR
    Definition: type_dcmp.h:44
    #define SCIP_DECOMP_LINKCONS
    Definition: type_dcmp.h:45
    struct SCIP_HeurData SCIP_HEURDATA
    Definition: type_heur.h:77
    @ SCIP_LPSOLSTAT_OPTIMAL
    Definition: type_lp.h:44
    @ SCIP_VERBLEVEL_FULL
    Definition: type_message.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_OPTIMAL
    Definition: type_stat.h:43
    @ SCIP_STATUS_GAPLIMIT
    Definition: type_stat.h:56
    @ SCIP_STATUS_INFEASIBLE
    Definition: type_stat.h:44
    @ SCIP_STATUS_NODELIMIT
    Definition: type_stat.h:49
    enum SCIP_Status SCIP_STATUS
    Definition: type_stat.h:64
    @ SCIP_VARTYPE_INTEGER
    Definition: type_var.h:65
    @ SCIP_VARTYPE_CONTINUOUS
    Definition: type_var.h:71
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64