Scippy

    SCIP

    Solving Constraint Integer Programs

    heur_init.c
    Go to the documentation of this file.
    1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    2/* */
    3/* This file is part of the program and library */
    4/* SCIP --- Solving Constraint Integer Programs */
    5/* */
    6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
    7/* */
    8/* Licensed under the Apache License, Version 2.0 (the "License"); */
    9/* you may not use this file except in compliance with the License. */
    10/* You may obtain a copy of the License at */
    11/* */
    12/* http://www.apache.org/licenses/LICENSE-2.0 */
    13/* */
    14/* Unless required by applicable law or agreed to in writing, software */
    15/* distributed under the License is distributed on an "AS IS" BASIS, */
    16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
    17/* See the License for the specific language governing permissions and */
    18/* limitations under the License. */
    19/* */
    20/* You should have received a copy of the Apache-2.0 license */
    21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
    22/* */
    23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    24
    25/**@file heur_init.c
    26 * @brief initial primal heuristic for the vertex coloring problem
    27 * @author Gerald Gamrath
    28 *
    29 * This file implements a heuristic which computes a starting solution for the coloring problem. It
    30 * therefore computes maximal stable sets and creates one variable for each set, which is added to the
    31 * LP.
    32 *
    33 * The heuristic is called only one time: before solving the root node.
    34 *
    35 * It checks whether a solution-file was read in and a starting solution already exists. If this
    36 * is not the case, an initial possible coloring is computed by a greedy method. After that, a
    37 * tabu-search is called, which tries to reduce the number of colors needed. The tabu-search algorithm
    38 * follows the description in
    39 *
    40 * "A Survey of Local Search Methods for Graph Coloring"@n
    41 * by P. Galinier and A. Hertz@n
    42 * Computers & Operations Research, 33 (2006)
    43 *
    44 * The tabu-search works as follows: given the graph and a number of colors it tries to color the
    45 * nodes of the graph with at most the given number of colors. It starts with a random coloring. In
    46 * each iteration, it counts the number of violated edges, that is, edges for which both incident
    47 * nodes have the same color. It now switches one node to another color in each iteration, taking
    48 * the node and color, that cause the greatest reduction of the number of violated edges, or if no
    49 * such combination exists, the node and color that cause the smallest increase of that number. The
    50 * former color of the node is forbidden for a couple of iterations in order to give the possibility
    51 * to leave a local minimum.
    52 *
    53 * As long as the tabu-search finds a solution with the given number of colors, this number is reduced
    54 * by 1 and the tabu-search is called another time. If no coloring was found after a given number
    55 * of iterations, the tabu-search is stopped and variables for all sets of the last feasible coloring
    56 * are created and added to the LP (after possible extension to maximal stable sets).
    57 *
    58 * The variables of these sets result in a feasible starting solution of the coloring problem.
    59 *
    60 * The tabu-search can be deactivated by setting the parameter <heuristics/initcol/usetabu> to
    61 * FALSE. The number of iterations after which the tabu-search stops if no solution was yet found
    62 * can be changed by the param <heuristics/initcol/maxiter>. A great effect is also obtained by
    63 * changing the parameters <heuristics/initcol/tabubase> and <heuristics/initcol/tabugamma>, which
    64 * determine the number of iterations for which the former color of a node is forbidden; more
    65 * precisely, this number is <tabubase> + ncritical * <tabugamma>, where ncritical is the number
    66 * of nodes, which are incident to violated edges. Finally, the level of output and the frequency of
    67 * status lines can be changed by <heuristics/initcol/output> and <heuristics/initcol/dispfreq>.
    68 */
    69
    70/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    71
    72#include <assert.h>
    73#include <string.h>
    74
    75#include "heur_init.h"
    76#include "pricer_coloring.h"
    77#include "probdata_coloring.h"
    78#include "reader_col.h"
    79#include "scip/cons_setppc.h"
    80#include "cons_storeGraph.h"
    81#include "tclique/tclique.h"
    82
    83#define HEUR_NAME "initcol"
    84#define HEUR_DESC "initial primal heuristic for coloring"
    85#define HEUR_DISPCHAR 't'
    86#define HEUR_PRIORITY 1
    87#define HEUR_FREQ 1
    88#define HEUR_FREQOFS 0
    89#define HEUR_MAXDEPTH 0
    90#define HEUR_TIMING SCIP_HEURTIMING_BEFORENODE
    91#define HEUR_USESSUBSCIP FALSE /**< does the heuristic use a secondary SCIP instance? */
    92
    93
    94/* default values for parameters */
    95#define DEFAULT_USETABU TRUE
    96#define DEFAULT_MAXITER 100000
    97#define DEFAULT_TABUBASE 50
    98#define DEFAULT_TABUGAMMA 0.9
    99#define DEFAULT_OUTPUT 1
    100#define DEFAULT_DISPFREQ 10000
    101
    102
    103
    104/*
    105 * Data structures
    106 */
    107
    108/** primal heuristic data */
    109struct SCIP_HeurData
    110{
    111 SCIP_Bool usetabu; /**< should the tabu search heuristic be used in order to improve the greedy-solution? */
    112 int maxiter; /**< maximal number of iterations to be performed in each tabu-run */
    113 int tabubase; /**< constant part of the tabu-duration */
    114 SCIP_Real tabugamma; /**< factor for the linear part of the tabu-duration */
    115 int output; /**< verbosity level for the output of the tabu search, 0: no output, 1: normal, 2: high */
    116 int dispfreq; /**< frequency for displaying status information, only active with output verbosity level 2 */
    117};
    118
    119
    120
    121
    122/*
    123 * Local methods
    124 */
    125
    126
    127
    128/** checks whether one of the nodes has no color respectively has color -1 in the given array */
    129static
    131 int nnodes, /**< the graph that should be colored */
    132 int* colors /**< array of ints representing the colors */
    133 )
    134{
    135 int i;
    136
    137 assert(colors != NULL);
    138
    139 for( i = 0; i < nnodes; i++)
    140 {
    141 /* node not yet colored */
    142 if(colors[i] == -1)
    143 {
    144 return TRUE;
    145 }
    146 }
    147 return FALSE;
    148}
    149
    150
    151/** computes a stable set with a greedy-method and colors its nodes */
    152static
    154 SCIP* scip, /**< SCIP data structure */
    155 TCLIQUE_GRAPH* graph, /**< pointer to graph data structure */
    156 int* colors, /**< array of ints representing the different colors, -1 means uncolored */
    157 int nextcolor /**< color in which the stable set will be colored */
    158 )
    159{
    160 SCIP_Bool indNode;
    161 int nnodes;
    162 int i;
    163 int j;
    164 int* degrees;
    165 int* sortednodes;
    166 int* values;
    167 int* stablesetnodes;
    168 int nstablesetnodes;
    169
    170 assert(graph != NULL);
    171 assert(colors != NULL);
    172
    173 /* get number of nodes */
    174 nnodes = tcliqueGetNNodes(graph);
    175
    176 /* get the degrees and weights for the nodes in the graph */
    177 degrees = tcliqueGetDegrees(graph);
    178 SCIP_CALL( SCIPallocBufferArray(scip, &stablesetnodes, nnodes) );
    180 SCIP_CALL( SCIPallocBufferArray(scip, &sortednodes, nnodes) );
    181
    182 /* set values to the nodes which are used for sorting them */
    183 /* value = degree of the node + number of nodes if the node is yet uncolored,
    184 therefore the yet colored nodes have lower values than the not yet colored nodes */
    185 for( i = 0; i < nnodes; i++ )
    186 {
    187 sortednodes[i] = i;
    188 values[i] = degrees[i] + ( colors[i] == -1 ? nnodes : 0);
    189 }
    190
    191 /* sort the nodes w.r.t. the computed values */
    192 SCIPsortDownIntInt(values, sortednodes, nnodes);
    193
    194 /* insert first node */
    195 stablesetnodes[0] = sortednodes[0];
    196 nstablesetnodes = 1;
    197 for( i = 1; i < nnodes; i++)
    198 {
    199 if( colors[sortednodes[i]] != -1 )
    200 {
    201 break;
    202 }
    203 indNode = TRUE;
    204 for( j = 0; j < nstablesetnodes; j++ )
    205 {
    206 if( tcliqueIsEdge(graph, sortednodes[i], stablesetnodes[j]) )
    207 {
    208 indNode = FALSE;
    209 break;
    210 }
    211 }
    212 if( indNode == TRUE )
    213 {
    214 stablesetnodes[nstablesetnodes] = sortednodes[i];
    215 nstablesetnodes++;
    216 }
    217
    218 }
    219 for( i = 0; i < nstablesetnodes; i++ )
    220 {
    221 assert(colors[stablesetnodes[i]] == -1);
    222 colors[stablesetnodes[i]] = nextcolor;
    223 }
    224 SCIPfreeBufferArray(scip, &stablesetnodes);
    225 SCIPfreeBufferArray(scip, &sortednodes);
    226 SCIPfreeBufferArray(scip, &values);
    227
    228 return SCIP_OKAY;
    229}
    230
    231
    232static
    233/** computes the initial coloring with a greedy method */
    235 SCIP* scip, /**< SCIP data structure */
    236 TCLIQUE_GRAPH* graph, /**< pointer to graph data structure */
    237 int* colors, /**< array of ints representing the different colors */
    238 int* ncolors /**< number of colors needed */
    239 )
    240{
    241 int nnodes;
    242 int i;
    243 int color;
    244
    245 assert(scip != NULL);
    246 assert(graph != NULL);
    247 assert(colors != NULL);
    248
    250 assert(nnodes > 0);
    251
    252 for( i = 0; i < nnodes; i++ )
    253 {
    254 colors[i] = -1;
    255 }
    256
    257 color = 0;
    258 /* create stable sets until all Nodes are covered */
    259 while( hasUncoloredNode(nnodes, colors) )
    260 {
    261 SCIP_CALL( greedyStableSet(scip, graph, colors, color) );
    262 color++;
    263 }
    264 *ncolors = color;
    265
    266 return SCIP_OKAY;
    267
    268}
    269
    270
    271#ifndef NDEBUG
    272/** computes the number of violated edges, that means the number of edges (i,j) where i and j have the same color */
    273static
    275 TCLIQUE_GRAPH* graph, /**< the graph */
    276 int* colors /**< colors of the nodes */
    277 )
    278{
    279 int nnodes;
    280 int i;
    281 int* j;
    282 int cnt;
    283
    284 assert(graph != NULL);
    285 assert(colors != NULL);
    286
    287 /* get the number of nodes */
    288 nnodes = tcliqueGetNNodes(graph);
    289 cnt = 0;
    290
    291 /* count the number of violated edges, only consider edges (i,j) with i > j since the graph is undirected bu */
    292 for( i = 0; i < nnodes; i++ )
    293 {
    294 for( j = tcliqueGetFirstAdjedge(graph,i); j <= tcliqueGetLastAdjedge(graph,i) && *j < i; j++ )
    295 {
    296 if( colors[i] == colors[*j] )
    297 cnt++;
    298 }
    299 }
    300 return cnt;
    301}
    302#endif
    303
    304
    305/** runs tabu coloring heuristic, gets a graph and a number of colors
    306 * and tries to color the graph with at most that many colors;
    307 * starts with a random coloring and switches one node to another color in each iteration,
    308 * forbidding the old color for a couple of iterations
    309 */
    310static
    312 TCLIQUE_GRAPH* graph, /**< the graph, that should be colored */
    313 int seed, /**< seed for the first random coloring */
    314 int maxcolors, /**< number of colors, which are allowed */
    315 int* colors, /**< output: the computed coloring */
    316 SCIP_HEURDATA* heurdata, /**< data of the heuristic */
    317 SCIP_Bool* success /**< pointer to store if something went wrong */
    318 )
    319{
    320 int nnodes;
    321 int** tabu;
    322 int** adj;
    323 int obj;
    324 int bestobj;
    325 int i;
    326 int j;
    327 int node1;
    328 int node2;
    329 int color1;
    330 int color2;
    331 int* firstedge;
    332 int* lastedge;
    333 SCIP_Bool restrictive;
    334 int iter;
    335 int minnode;
    336 int mincolor;
    337 int minvalue;
    338 int ncritical;
    339 SCIP_Bool aspiration;
    340 int d;
    341 int oldcolor;
    342
    343 assert(graph != NULL);
    344 assert(heurdata != NULL);
    345 assert(success != NULL);
    346
    347 if( heurdata->output >= 1 )
    348 printf("Running tabu coloring with maxcolors = %d...\n", maxcolors);
    349
    350 /* get size */
    351 nnodes = tcliqueGetNNodes(graph);
    352
    353 srand( seed ); /*lint !e732*/
    354
    355 /* init random coloring, optionally keeping colors from a previous coloring */
    356 for( i = 0; i < nnodes; i++ )
    357 {
    358 if( colors[i] < 0 || colors[i] >= maxcolors )
    359 {
    360 int rnd = rand();
    361 colors[i] = rnd % maxcolors;
    362 }
    363 assert( 0 <= colors[i] && colors[i] < maxcolors );
    364 }
    365
    366 /* init matrices */
    367 SCIP_CALL( SCIPallocMemoryArray(scip, &tabu, nnodes) ); /* stores iteration at which tabu node/color pair will
    368 * expire to be tabu
    369 */
    370 SCIP_CALL( SCIPallocMemoryArray(scip, &adj, nnodes) ); /* stores number of adjacent nodes using specified color */
    371
    372 for( i = 0; i < nnodes; i++ )
    373 {
    374 SCIP_CALL( SCIPallocMemoryArray(scip, &(tabu[i]), maxcolors) ); /*lint !e866*/
    375 SCIP_CALL( SCIPallocMemoryArray(scip, &(adj[i]), maxcolors) ); /*lint !e866*/
    376 for( j = 0; j < maxcolors; j++ )
    377 {
    378 tabu[i][j] = 0;
    379 adj[i][j] = 0;
    380 }
    381 }
    382
    383 /* objective */
    384 obj = 0;
    385
    386 /* init adj-matrix and objective */
    387 for( node1 = 0; node1 < nnodes; node1++ )
    388 {
    389 color1 = colors[node1];
    390 firstedge = tcliqueGetFirstAdjedge(graph, node1);
    391 lastedge = tcliqueGetLastAdjedge(graph, node1);
    392 while( firstedge <= lastedge )
    393 {
    394 node2 = *firstedge;
    395 color2 = colors[node2];
    396 assert( 0 <= color2 && color2 < maxcolors );
    397 (adj[node1][color2])++;
    398 if( color1 == color2 )
    399 obj++;
    400 firstedge++;
    401 }
    402 }
    403 assert( obj % 2 == 0 );
    404 obj = obj / 2;
    405 assert( obj == getNViolatedEdges(graph, colors) );
    406
    407 bestobj = obj;
    408 restrictive = FALSE;
    409 iter = 0;
    410 if( obj > 0 )
    411 {
    412 /* perform predefined number of iterations */
    413 for( iter = 1; iter <= heurdata->maxiter; iter++ )
    414 {
    415 /* find best 1-move among those with critical vertex */
    416 minnode = -1;
    417 mincolor = -1;
    418 minvalue = nnodes * nnodes;
    419 ncritical = 0;
    420 for( node1 = 0; node1 < nnodes; node1++ )
    421 {
    422 aspiration = FALSE;
    423 color1 = colors[node1];
    424 assert( 0 <= color1 && color1 < maxcolors );
    425
    426 /* if node is critical (has incident violated edges) */
    427 if( adj[node1][color1] > 0 )
    428 {
    429 ncritical++;
    430 /* check all colors */
    431 for( j = 0; j < maxcolors; j++ )
    432 {
    433 /* if color is new */
    434 if( j != color1 )
    435 {
    436 /* change in the number of violated edges: */
    437 d = adj[node1][j] - adj[node1][color1];
    438
    439 /* 'aspiration criterion': stop if we get feasible solution */
    440 if( obj + d == 0 )
    441 {
    442 if( heurdata->output >= 1 )
    443 printf(" Feasible solution found after %d iterations!\n\n", iter);
    444 minnode = node1;
    445 mincolor = j;
    446 minvalue = d;
    447 aspiration = TRUE;
    448 break;
    449 }
    450
    451 /* if not tabu and better value */
    452 if( tabu[node1][j] < iter && d < minvalue )
    453 {
    454 minnode = node1;
    455 mincolor = j;
    456 minvalue = d;
    457 }
    458 }
    459 }
    460 }
    461 if( aspiration )
    462 break;
    463 }
    464
    465 /* if no candidate could be found - tabu list is too restrictive: just skip current iteration */
    466 if( minnode == -1 )
    467 {
    468 restrictive = TRUE;
    469 continue;
    470 }
    471 assert( minnode != -1 );
    472 assert( mincolor >= 0 );
    473
    474 /* perform changes */
    475 assert( colors[minnode] != mincolor );
    476 oldcolor = colors[minnode];
    477 colors[minnode] = mincolor;
    478 obj += minvalue;
    479 assert( obj == getNViolatedEdges(graph, colors) );
    480 if( obj < bestobj )
    481 bestobj = obj;
    482
    483 if( heurdata->output == 2 && (iter) % (heurdata->dispfreq) == 0 )
    484 {
    485 printf("Iter: %d obj: %d critical: %d node: %d color: %d delta: %d\n", iter, obj, ncritical, minnode,
    486 mincolor, minvalue);
    487 }
    488
    489 /* terminate if valid coloring has been found */
    490 if( obj == 0 )
    491 break;
    492
    493 /* update tabu list */
    494 assert( tabu[minnode][oldcolor] < iter );
    495 tabu[minnode][oldcolor] = iter + (heurdata->tabubase) + (int) (((double) ncritical) * (heurdata->tabugamma));
    496
    497 /* update adj matrix */
    498 for( firstedge = tcliqueGetFirstAdjedge(graph, minnode); firstedge <= tcliqueGetLastAdjedge(graph, minnode); firstedge++ )
    499 {
    500 (adj[*firstedge][mincolor])++;
    501 (adj[*firstedge][oldcolor])--;
    502 }
    503 }
    504 }
    505 if( heurdata->output == 2 )
    506 {
    507 printf("Best objective: %d\n ", bestobj);
    508 if( restrictive )
    509 {
    510 printf("\nTabu list is probably too restrictive.\n");
    511 }
    512 printf("\n");
    513 }
    514 if( heurdata->output >= 1 && bestobj != 0 )
    515 {
    516 printf(" No feasible solution found after %d iterations!\n\n", iter-1);
    517 }
    518
    519 for( i = 0; i < nnodes; i++ )
    520 {
    521 SCIPfreeMemoryArray(scip, &(adj[i]));
    522 SCIPfreeMemoryArray(scip, &(tabu[i]));
    523 }
    526
    527 /* check whether valid coloring has been found */
    528 *success = (obj == 0);
    529
    530 return SCIP_OKAY;
    531}
    532
    533
    534/*
    535 * Callback methods of primal heuristic
    536 */
    537
    538/** copy method for primal heuristic plugins (called when SCIP copies plugins) */
    539static
    541{ /*lint --e{715}*/
    542 assert(scip != NULL);
    543 assert(heur != NULL);
    544 assert(strcmp(SCIPheurGetName(heur), HEUR_NAME) == 0);
    545
    546 return SCIP_OKAY;
    547}
    548
    549/** destructor of primal heuristic to free user data (called when SCIP is exiting) */
    550/**! [SnippetHeurFreeInit] */
    551static
    553{
    554 SCIP_HEURDATA* heurdata;
    555
    556 /* free heuristic rule data */
    557 heurdata = SCIPheurGetData(heur);
    558 SCIPfreeBlockMemory(scip, &heurdata);
    559 SCIPheurSetData(heur, NULL);
    560
    561 return SCIP_OKAY;
    562}
    563/**! [SnippetHeurFreeInit] */
    564
    565
    566/** execution method of primal heuristic */
    567static
    569{
    570 int i;
    571 int j;
    572 int k;
    573 int nnodes;
    574 SCIP_SOL* sol;
    575 SCIP_Bool stored;
    576 SCIP_Bool success;
    577 SCIP_Bool indnode;
    578 int* colors;
    579 int* bestcolors;
    580 int ncolors;
    581 int nstablesetnodes;
    582 int setnumber;
    583 SCIP_VAR* var;
    584 SCIP_CONS** constraints;
    585 TCLIQUE_GRAPH* graph;
    586 SCIP_HEURDATA* heurdata;
    587 SCIP_Bool onlybest;
    588 int maxvarsround;
    589
    590 heurdata = SCIPheurGetData(heur);
    591 assert(heurdata != NULL);
    592
    593 *result = SCIP_DIDNOTFIND;
    595 graph = COLORprobGetGraph(scip);
    596
    597 /* create stable sets if no solution was read */
    598 if( COLORprobGetNStableSets(scip) == 0 )
    599 {
    600 /* get memory for arrays */
    602 SCIP_CALL( SCIPallocBufferArray(scip, &bestcolors, nnodes) );
    603
    604 /* get the node-constraits */
    605 constraints = COLORprobGetConstraints(scip);
    606 assert(constraints != NULL);
    607
    608 /* compute an initial coloring with a greedy method */
    609 SCIP_CALL( greedyInitialColoring(scip, graph, bestcolors, &ncolors) );
    610
    611 if( heurdata->usetabu )
    612 {
    613 /* try to find better colorings with tabu search method */
    614 success = TRUE;
    615 while( success )
    616 {
    617 ncolors--;
    618
    619 /* initialize with colors from previous iteration; the last color is randomized */
    620 SCIP_CALL( runTabuCol(graph, 0, ncolors, colors, heurdata, &success) );
    621
    622 if( success )
    623 {
    624 for( i = 0; i < nnodes; i++ )
    625 bestcolors[i] = colors[i];
    626 }
    627 }
    628 }
    629
    630 /* create vars for the computed coloring */
    631 for( i = 0; i <= ncolors; i++ )
    632 {
    633 /* save nodes with color i in the array colors and the number of such nodes in nstablesetnodes */
    634 nstablesetnodes = 0;
    635 for( j = 0; j < nnodes; j++ )
    636 {
    637 if( bestcolors[j] == i )
    638 {
    639 colors[nstablesetnodes] = j;
    640 nstablesetnodes++;
    641 }
    642 }
    643
    644 /* try to add more nodes to the stable set without violating the stability */
    645 for( j = 0; j < nnodes; j++ )
    646 {
    647 indnode = TRUE;
    648 for( k = 0; k < nstablesetnodes; k++ )
    649 {
    650 if( j == colors[k] || tcliqueIsEdge(graph, j, colors[k]) )
    651 {
    652 indnode = FALSE;
    653 break;
    654 }
    655 }
    656
    657 if( indnode == TRUE )
    658 {
    659 colors[nstablesetnodes] = j;
    660 nstablesetnodes++;
    661 }
    662 }
    663
    664 /* create variable for the stable set and add it to SCIP */
    665 SCIPsortDownInt(colors, nstablesetnodes);
    666 SCIP_CALL( COLORprobAddNewStableSet(scip, colors, nstablesetnodes, &setnumber) );
    667 assert(setnumber != -1);
    668
    669 /* create variable for the stable set and add it to SCIP */
    670 SCIP_CALL( SCIPcreateVar(scip, &var, NULL, 0.0, 1.0, 1.0, SCIP_VARTYPE_BINARY,
    671 TRUE, TRUE, NULL, NULL, NULL, NULL, (SCIP_VARDATA*)(size_t)setnumber) ); /*lint !e571*/
    672
    673 SCIP_CALL( COLORprobAddVarForStableSet(scip, setnumber, var) );
    674 SCIP_CALL( SCIPaddVar(scip, var) );
    675 SCIP_CALL( SCIPchgVarUbLazy(scip, var, 1.0) );
    676
    677 for( j = 0; j < nstablesetnodes; j++ )
    678 {
    679 /* add variable to node constraints of nodes in the set */
    680 SCIP_CALL( SCIPaddCoefSetppc(scip, constraints[colors[j]], var) );
    681 }
    682 }
    683
    684 SCIPfreeBufferArray(scip, &bestcolors);
    685 SCIPfreeBufferArray(scip, &colors);
    686
    687 }
    688
    689 /* create solution consisting of all yet created stable sets, i.e., all sets of the solution given by the solution
    690 * file or created by the greedy and tabu search */
    691 SCIP_CALL( SCIPcreateSol(scip, &sol, NULL) );
    692 assert(sol != NULL);
    693 for( i = 0; i < COLORprobGetNStableSets(scip); i++ )
    694 {
    696 }
    697 SCIP_CALL( SCIPtrySolFree(scip, &sol, TRUE, FALSE, FALSE, FALSE, FALSE, &stored) );
    698 assert(stored);
    699
    700 /* set maximal number of variables to be priced in each round */
    701 SCIP_CALL( SCIPgetBoolParam(scip, "pricers/coloring/onlybest", &onlybest) );
    702 if( onlybest )
    704 else
    705 maxvarsround = 1;
    706 SCIP_CALL( SCIPsetIntParam(scip, "pricers/coloring/maxvarsround", maxvarsround) );
    707
    708 *result = SCIP_FOUNDSOL;
    709
    710 return SCIP_OKAY;
    711}/*lint !e715*/
    712
    713/*
    714 * primal heuristic specific interface methods
    715 */
    716
    717/** creates the init primal heuristic and includes it in SCIP */
    719 SCIP* scip /**< SCIP data structure */
    720 )
    721{
    722 SCIP_HEURDATA* heurdata;
    723 SCIP_HEUR* heur;
    724
    725 /* create init primal heuristic data */
    726 SCIP_CALL( SCIPallocBlockMemory(scip, &heurdata) );
    727
    728 heur = NULL;
    729 /* include primal heuristic */
    731 HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecInit, heurdata) );
    732 assert(heur != NULL);
    733
    734 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyInit) );
    735 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeInit) );
    736
    737 /* add parameters */
    739 "heuristics/initcol/usetabu",
    740 "should the tabu search heuristic be used in order to improve the greedy-solution?",
    741 &heurdata->usetabu, FALSE, DEFAULT_USETABU, NULL, NULL) );
    742
    744 "heuristics/initcol/maxiter",
    745 "maximal number of iterations to be performed in each tabu-run",
    746 &heurdata->maxiter, TRUE, DEFAULT_MAXITER, 0, INT_MAX, NULL, NULL) );
    747
    749 "heuristics/initcol/tabubase",
    750 "constant part of the tabu-duration",
    751 &heurdata->tabubase, TRUE, DEFAULT_TABUBASE, 0, INT_MAX, NULL, NULL) );
    752
    754 "heuristics/initcol/tabugamma",
    755 "factor for the linear part of the tabu-duration",
    756 &heurdata->tabugamma, TRUE, DEFAULT_TABUGAMMA, -100.0, 100.0, NULL, NULL) );
    757
    759 "heuristics/initcol/output",
    760 "verbosity level for the output of the tabu search, 0: no output, 1: normal, 2: high",
    761 &heurdata->output, FALSE, DEFAULT_OUTPUT, 0, 2, NULL, NULL) );
    762
    764 "heuristics/initcol/dispfreq",
    765 "frequency for displaying status information, only active with output verbosity level 2",
    766 &heurdata->dispfreq, TRUE, DEFAULT_DISPFREQ, 0, INT_MAX, NULL, NULL) );
    767
    768
    769 return SCIP_OKAY;
    770}
    Constraint handler for the set partitioning / packing / covering constraints .
    constraint handler for storing the graph at each node of the tree
    #define NULL
    Definition: def.h:248
    #define SCIP_Bool
    Definition: def.h:91
    #define SCIP_Real
    Definition: def.h:156
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define SCIP_CALL(x)
    Definition: def.h:355
    #define nnodes
    Definition: gastrans.c:74
    SCIP_RETCODE SCIPaddCoefSetppc(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
    Definition: cons_setppc.c:9573
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
    Definition: scip_param.c:250
    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 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 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 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
    #define SCIPallocMemoryArray(scip, ptr, num)
    Definition: scip_mem.h:64
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    #define SCIPfreeMemoryArray(scip, ptr)
    Definition: scip_mem.h:80
    #define SCIPfreeBlockMemory(scip, ptr)
    Definition: scip_mem.h:108
    #define SCIPallocBlockMemory(scip, ptr)
    Definition: scip_mem.h:89
    SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
    Definition: scip_sol.c:516
    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:4109
    SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
    Definition: scip_sol.c:1571
    SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
    Definition: scip_var.c:120
    SCIP_RETCODE SCIPchgVarUbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazyub)
    Definition: scip_var.c:6362
    void SCIPsortDownIntInt(int *intarray1, int *intarray2, int len)
    void SCIPsortDownInt(int *intarray, int len)
    static SCIP_RETCODE greedyStableSet(SCIP *scip, TCLIQUE_GRAPH *graph, int *colors, int nextcolor)
    Definition: heur_init.c:153
    static SCIP_RETCODE runTabuCol(TCLIQUE_GRAPH *graph, int seed, int maxcolors, int *colors, SCIP_HEURDATA *heurdata, SCIP_Bool *success)
    Definition: heur_init.c:311
    #define DEFAULT_TABUGAMMA
    Definition: heur_init.c:98
    SCIP_RETCODE SCIPincludeHeurInit(SCIP *scip)
    Definition: heur_init.c:718
    #define HEUR_TIMING
    Definition: heur_init.c:90
    static SCIP_DECL_HEURCOPY(heurCopyInit)
    Definition: heur_init.c:540
    #define HEUR_FREQOFS
    Definition: heur_init.c:88
    #define HEUR_DESC
    Definition: heur_init.c:84
    #define DEFAULT_TABUBASE
    Definition: heur_init.c:97
    #define HEUR_DISPCHAR
    Definition: heur_init.c:85
    #define HEUR_MAXDEPTH
    Definition: heur_init.c:89
    #define HEUR_PRIORITY
    Definition: heur_init.c:86
    #define DEFAULT_OUTPUT
    Definition: heur_init.c:99
    static SCIP_DECL_HEUREXEC(heurExecInit)
    Definition: heur_init.c:568
    #define HEUR_NAME
    Definition: heur_init.c:83
    static SCIP_RETCODE greedyInitialColoring(SCIP *scip, TCLIQUE_GRAPH *graph, int *colors, int *ncolors)
    Definition: heur_init.c:234
    static SCIP_Bool hasUncoloredNode(int nnodes, int *colors)
    Definition: heur_init.c:130
    #define DEFAULT_DISPFREQ
    Definition: heur_init.c:100
    static int getNViolatedEdges(TCLIQUE_GRAPH *graph, int *colors)
    Definition: heur_init.c:274
    static SCIP_DECL_HEURFREE(heurFreeInit)
    Definition: heur_init.c:552
    #define HEUR_FREQ
    Definition: heur_init.c:87
    #define DEFAULT_USETABU
    Definition: heur_init.c:95
    #define HEUR_USESSUBSCIP
    Definition: heur_init.c:91
    #define DEFAULT_MAXITER
    Definition: heur_init.c:96
    initial primal heuristic for the vertex coloring problem
    variable pricer for the vertex coloring problem
    SCIP_CONS ** COLORprobGetConstraints(SCIP *scip)
    SCIP_RETCODE COLORprobAddNewStableSet(SCIP *scip, int *stablesetnodes, int nstablesetnodes, int *setindex)
    int COLORprobGetNNodes(SCIP *scip)
    SCIP_VAR * COLORprobGetVarForStableSet(SCIP *scip, int setindex)
    TCLIQUE_GRAPH * COLORprobGetGraph(SCIP *scip)
    SCIP_RETCODE COLORprobAddVarForStableSet(SCIP *scip, int setindex, SCIP_VAR *var)
    int COLORprobGetNStableSets(SCIP *scip)
    problem data for vertex coloring algorithm
    file reader for vertex coloring instances
    tclique user interface
    int * tcliqueGetLastAdjedge(TCLIQUE_GRAPH *tcliquegraph, int node)
    int * tcliqueGetDegrees(TCLIQUE_GRAPH *tcliquegraph)
    int * tcliqueGetFirstAdjedge(TCLIQUE_GRAPH *tcliquegraph, int node)
    struct TCLIQUE_Graph TCLIQUE_GRAPH
    Definition: tclique.h:49
    struct SCIP_HeurData SCIP_HEURDATA
    Definition: type_heur.h:77
    @ 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
    struct SCIP_VarData SCIP_VARDATA
    Definition: type_var.h:167
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64