SCIP

    Solving Constraint Integer Programs

    reader_csol.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 reader_csol.c
    26 * @brief file reader and writer for vertex coloring solutions
    27 * @author Gerald Gamrath
    28 *
    29 * This file implements the reader and writer for coloring solution files.
    30 *
    31 * These files have the following structure:@n The first line contains the name of the problem, the
    32 * number of colors used in the solution, and - optional - the name of the algorithm that computed
    33 * this solution. The second line lists the colors of the nodes, separated by spaces. It is sorted
    34 * increasingly by the node indices. The numbers for the colors start with 0.
    35 */
    36
    37/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
    38
    39#include <ctype.h>
    40#include <stdlib.h>
    41
    42#include "reader_csol.h"
    43#include "reader_col.h"
    44#include "probdata_coloring.h"
    45
    46
    47#define READER_NAME "csolreader"
    48#define READER_DESC "file reader which reads and writes csol-files"
    49#define READER_EXTENSION "csol"
    50
    51#define COL_MAX_LINELEN 65535
    52
    53
    54
    55/*
    56 * Local methods
    57 */
    58
    59/** get next number from string s */
    60static
    62 char** s /**< pointer to the pointer of the current position in the string */
    63 )
    64{
    65 long tmp;
    66 /* skip whitespaces */
    67 while ( isspace((unsigned char)**s) )
    68 ++(*s);
    69 /* read number */
    70 tmp = atol(*s);
    71 /* skip whitespaces */
    72 while ( (**s != 0) && (!isspace((unsigned char)**s)) )
    73 ++(*s);
    74 return tmp;
    75}
    76
    77
    78/* put your local methods here, and declare them static */
    79
    80/** copy method for reader plugins (called when SCIP copies plugins) */
    81static
    82SCIP_DECL_READERCOPY(readerCopyCsol)
    83{ /*lint --e{715}*/
    84 assert(scip != NULL);
    85 assert(reader != NULL);
    86
    88
    89 return SCIP_OKAY;
    90}
    91
    92/** problem reading method of reader */
    93static
    94SCIP_DECL_READERREAD(readerReadCsol)
    95{
    96 SCIP_FILE* fp; /* file-reader */
    97 char buf[COL_MAX_LINELEN]; /* maximal length of line */
    98 char* char_p;
    99 char* solprobname;
    100 const char* probname;
    101
    102 SCIP_Bool correctinstance;
    103 TCLIQUE_GRAPH* graph;
    104 SCIP_VAR* var;
    105 SCIP_CONS** constraints;
    106
    107 int** sets;
    108 int* setlengths;
    109 int nsets;
    110 int setindex;
    111
    112 int i;
    113 int j;
    114 int k;
    115 int color;
    116 int node;
    117
    118 assert(reader != NULL);
    119 assert(scip != NULL);
    120 assert(result != NULL);
    121 assert(filename != NULL);
    122
    124
    125 *result = SCIP_SUCCESS;
    126
    128 {
    129 SCIPerrorMessage("Please read in problem before reading the solution!\n");
    130 return SCIP_OKAY;
    131 }
    132
    133 if (NULL == (fp = SCIPfopen(filename, "r")))
    134 {
    135 SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
    136 perror(filename);
    137 return SCIP_NOFILE;
    138 }
    139
    140 /* Read out the name of the problem belonging to this solution*/
    141 if( SCIPfgets(buf, (int) sizeof(buf), fp) == NULL )
    142 return SCIP_READERROR;
    143
    144 i = 1;
    145 while ( !isspace((unsigned char)buf[i]) )
    146 {
    147 i++;
    148 }
    149 SCIP_CALL( SCIPallocBufferArray(scip, &solprobname, i+2) );
    150 (void) SCIPstrncpy(solprobname, buf, i);
    151
    152 printf("Reading solution for %s...\n", solprobname);
    153
    154 /* get the name of the current problem */
    155 probname = SCIPgetProbName(scip);
    156
    157 /* check whether the solution belongs to the current problem */
    158 correctinstance = TRUE;
    159 for ( j = 0; j <= i; j++ )
    160 {
    161 if ( solprobname[j] != probname[j] )
    162 {
    163 correctinstance = FALSE;
    164 }
    165 }
    166 if ( !correctinstance )
    167 {
    168 SCIPerrorMessage("The selected solution file doesn't belong to the current problem!\n");
    169 return SCIP_OKAY;
    170 }
    171
    172 /* get the graph of the current problem */
    173 graph = COLORprobGetGraph(scip);
    174 assert(graph != NULL);
    175
    176 /* read out number of colors */
    177 char_p = &buf[i];
    178 nsets = (int) getNextNumber(&char_p);
    179 assert(nsets > 0);
    180
    181 /* allocate memory for the stable sets */
    182 SCIP_CALL( SCIPallocBufferArray(scip, &sets, nsets) );
    183 SCIP_CALL( SCIPallocBufferArray(scip, &setlengths, nsets) );
    184 for ( i = 0; i < nsets; i++ )
    185 {
    186 int size;
    187
    189 SCIP_CALL( SCIPallocBufferArray(scip, &(sets[i]), size) ); /*lint !e866*/
    190 setlengths[i] = 0;
    191 }
    192
    193 /* read out the colors for the nodes */
    194 SCIPfgets(buf, (int) sizeof(buf), fp); /*lint !e534*/
    195 char_p = &buf[0];
    196 for ( i = 0; i < COLORprobGetOriginalNNodes(scip); i++ )
    197 {
    198 color = (int) getNextNumber(&char_p);
    199 sets[color][setlengths[color]] = i;
    200 sets[color][setlengths[color]+1] = -1;
    201 setlengths[color]++;
    202 }
    203
    204 /* the given coloring is a coloring for the original graph, now transform it into a coloring for the transformed graph */
    205 for ( i = 0; i < nsets; i++ )
    206 {
    207 j = 0;
    208 k = 0;
    209 while ( sets[i][j] != -1 )
    210 {
    211 node = COLORprobGetNewNodeForOriginalNode(scip, sets[i][j]);
    212 if ( node == -1 )
    213 {
    214 j++;
    215 }
    216 else
    217 {
    218 sets[i][k] = node;
    219 setlengths[i] = k+1;
    220 k++;
    221 j++;
    222 }
    223 }
    224 while ( k < j )
    225 {
    226 sets[i][k] = -1;
    227 k++;
    228 }
    229 }
    230
    231 printf("testing validity...\n");
    232 /* check solution */
    233 for ( i = 0; i < nsets; i++ )
    234 {
    235 for ( j = 0; j < setlengths[i]; j++ )
    236 {
    237 for ( k = j+1; k < setlengths[i]; k++ )
    238 {
    239 if ( tcliqueIsEdge(graph, sets[i][j], sets[i][k]) )
    240 {
    241 SCIPerrorMessage("The solution is not valid!\n");
    242 return SCIP_OKAY;
    243 }
    244 }
    245 }
    246 }
    247 printf("valid!\n");
    248
    249 /* get the node-constraits */
    250 constraints = COLORprobGetConstraints(scip);
    251 assert(constraints != NULL);
    252 /* try to add nodes to the stable sets */
    253 for ( i = 0; i < nsets; i++ )
    254 {
    255 for ( node = 0; node < COLORprobGetNNodes(scip); node++ )
    256 {
    257 for ( j = 0; j < setlengths[i]; j++ )
    258 {
    259 if ( sets[i][j] == node )
    260 {
    261 break;
    262 }
    263 if ( tcliqueIsEdge(graph, sets[i][j], node) )
    264 {
    265 break;
    266 }
    267 }
    268 if ( j == setlengths[i] )
    269 {
    270 sets[i][setlengths[i]] = node;
    271 sets[i][setlengths[i]+1] = -1;
    272 setlengths[i]++;
    273 }
    274 }
    275 }
    276
    277 /* sort the sets and add them to the problem, creating one variable for each set */
    278 for ( i = 0; i < nsets; i++ )
    279 {
    280 SCIPsortDownInt(sets[i], setlengths[i]);
    281 SCIP_CALL( COLORprobAddNewStableSet(scip, sets[i], setlengths[i], &setindex) );
    282 assert(setindex == i);
    283
    284 SCIP_CALL( SCIPcreateVar(scip, &var, NULL, 0.0, 1.0, 1.0, SCIP_VARTYPE_BINARY,
    285 TRUE, FALSE, NULL, NULL, NULL, NULL, (SCIP_VARDATA*)(size_t)setindex) ); /*lint !e571*/
    286
    287 SCIP_CALL( COLORprobAddVarForStableSet(scip, setindex, var) );
    288 SCIP_CALL( SCIPaddVar(scip, var) );
    289 SCIP_CALL( SCIPchgVarUbLazy(scip, var, 1.0) );
    290
    291 /* add variable to node constraints of nodes in the set */
    292 for ( j = 0; j < setlengths[i]; j++ )
    293 {
    294 SCIP_CALL( SCIPaddCoefSetppc(scip, constraints[sets[i][j]], var) );
    295 }
    296
    297 }
    298
    299
    300 /* free memory for the stable sets */
    301 for ( i = nsets-1; i >= 0; i-- )
    302 {
    303 SCIPfreeBufferArray(scip, &(sets[i]));
    304 }
    305 SCIPfreeBufferArray(scip, &setlengths);
    307 SCIPfreeBufferArray(scip, &solprobname);
    308
    309 return SCIP_OKAY;
    310}
    311
    312
    313
    314
    315/*
    316 * Callback methods of reader
    317 */
    318
    319/** problem writing method of reader */
    320static
    321SCIP_DECL_READERWRITE(readerWriteCsol)
    322{
    323 SCIP_SOL* sol;
    324 SCIP_Bool colorpossible;
    325 TCLIQUE_GRAPH* oldgraph;
    326 int** sets;
    327 int* nsetelements;
    328 int nsets;
    329 int nnodes;
    330 int i;
    331 int j;
    332 int actcolor;
    333 int node;
    334 int* originalnodes;
    335 int* deletednodes;
    336 int* firstedge;
    337 int* lastedge;
    338 int* colors;
    339
    340 *result = SCIP_DIDNOTRUN;
    341
    342 /* get the data of the original graph, the preprocessing information and the array stable sets in the preprocessed graph */
    345 assert(originalnodes != NULL);
    346 deletednodes = COLORprobGetDeletedNodes(scip);
    347 assert(deletednodes != NULL);
    349 COLORprobGetStableSets(scip, &sets, &nsetelements, &nsets);
    350 assert(sets != NULL && nsetelements != NULL);
    351
    352 /* get the solution */
    353 sol = SCIPgetBestSol(scip);
    354
    355 /* create array for the colors of the nodes and initialize it with -1 */
    357 for ( i = 0; i < nnodes; i++ )
    358 {
    359 colors[i] = -1;
    360 }
    361
    362 /* for all stable sets in the solution, color all nodes, that are in the set and not yet colored with the same, new color */
    363 actcolor = 0;
    364 for ( i = 0; i < nsets; i++ )
    365 {
    367 {
    368 assert(SCIPgetSolVal( scip, sol, COLORprobGetVarForStableSet(scip, i)) == 1);
    369 for ( j = 0; j < nsetelements[i]; j++ )
    370 {
    371 if ( colors[originalnodes[sets[i][j]]] == -1 )
    372 {
    373 colors[originalnodes[sets[i][j]]] = actcolor;
    374 }
    375 }
    376 actcolor++;
    377 }
    378 }
    379
    380 /* set i to the index of the last node deleted during preprocessing */
    382 while ( deletednodes[i] == -1 )
    383 {
    384 i--;
    385 }
    386
    387 /*compute colors for nodes deleted during preprocessing */
    388 while ( i >= 0 )
    389 {
    390 node = deletednodes[i];
    391 j = 0;
    392 while ( colors[node] == -1 )
    393 {
    394 colorpossible = TRUE;
    395 firstedge = tcliqueGetFirstAdjedge(oldgraph, node);
    396 lastedge = tcliqueGetLastAdjedge(oldgraph, node);
    397 while ( firstedge <= lastedge )
    398 {
    399 if ( colors[*firstedge] == j )
    400 {
    401 colorpossible = FALSE;
    402 break;
    403 }
    404 firstedge++;
    405 }
    406 if ( colorpossible == TRUE )
    407 {
    408 colors[node] = j;
    409 }
    410 else
    411 {
    412 j++;
    413 }
    414 }
    415 i--;
    416 }
    417
    418 SCIPinfoMessage(scip, file, "%s %d generated by ColumnGenerationColoring\n", name, actcolor);
    419 for ( i = 0; i < nnodes; i++ )
    420 {
    421 SCIPinfoMessage(scip, file, "%d ", colors[i]);
    422 }
    423
    424 SCIPfreeBufferArray(scip, &colors);
    425
    426 *result = SCIP_SUCCESS;
    427
    428 return SCIP_OKAY;
    429}/*lint !e715*/
    430
    431
    432/*
    433 * reader specific interface methods
    434 */
    435
    436/** includes the csol file reader in SCIP */
    438 SCIP* scip /**< SCIP data structure */
    439 )
    440{
    441 SCIP_READERDATA* readerdata;
    442 SCIP_READER* reader;
    443
    444 /* create csol reader data */
    445 readerdata = NULL;
    446
    447 /* include csol reader */
    449 readerdata) );
    450
    451 SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyCsol) );
    452 SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadCsol) );
    453 SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteCsol) );
    454
    455 return SCIP_OKAY;
    456}
    #define NULL
    Definition: def.h:257
    #define SCIP_Bool
    Definition: def.h:100
    #define SCIP_STRINGEQ(name, reference, retcode)
    Definition: def.h:454
    #define TRUE
    Definition: def.h:102
    #define FALSE
    Definition: def.h:103
    #define SCIP_CALL(x)
    Definition: def.h:364
    SCIP_FILE * SCIPfopen(const char *path, const char *mode)
    Definition: fileio.c:153
    char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
    Definition: fileio.c:200
    #define nnodes
    Definition: gastrans.c:74
    SCIP_RETCODE SCIPaddCoefSetppc(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
    Definition: cons_setppc.c:9664
    SCIP_STAGE SCIPgetStage(SCIP *scip)
    Definition: scip_general.c:444
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    const char * SCIPgetProbName(SCIP *scip)
    Definition: scip_prob.c:1242
    void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
    Definition: scip_message.c:208
    #define SCIPallocBufferArray(scip, ptr, num)
    Definition: scip_mem.h:124
    #define SCIPfreeBufferArray(scip, ptr)
    Definition: scip_mem.h:136
    SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
    Definition: scip_reader.c:109
    SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
    Definition: scip_reader.c:147
    const char * SCIPreaderGetName(SCIP_READER *reader)
    Definition: reader.c:700
    SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
    Definition: scip_reader.c:195
    SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
    Definition: scip_reader.c:219
    SCIP_SOL * SCIPgetBestSol(SCIP *scip)
    Definition: scip_sol.c:2986
    SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
    Definition: scip_sol.c:1763
    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 SCIPsortDownInt(int *intarray, int len)
    int SCIPstrncpy(char *t, const char *s, int size)
    Definition: misc.c:10897
    int COLORprobGetNewNodeForOriginalNode(SCIP *scip, int node)
    TCLIQUE_GRAPH * COLORprobGetOriginalGraph(SCIP *scip)
    SCIP_CONS ** COLORprobGetConstraints(SCIP *scip)
    SCIP_RETCODE COLORprobAddNewStableSet(SCIP *scip, int *stablesetnodes, int nstablesetnodes, int *setindex)
    int * COLORprobGetOriginalNodesForNewNodes(SCIP *scip)
    int COLORprobGetNNodes(SCIP *scip)
    int COLORprobGetOriginalNNodes(SCIP *scip)
    SCIP_VAR * COLORprobGetVarForStableSet(SCIP *scip, int setindex)
    void COLORprobGetStableSets(SCIP *scip, int ***stablesets, int **nelements, int *nstablesets)
    TCLIQUE_GRAPH * COLORprobGetGraph(SCIP *scip)
    SCIP_RETCODE COLORprobAddVarForStableSet(SCIP *scip, int setindex, SCIP_VAR *var)
    int * COLORprobGetDeletedNodes(SCIP *scip)
    problem data for vertex coloring algorithm
    struct SCIP_File SCIP_FILE
    Definition: pub_fileio.h:43
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    file reader for vertex coloring instances
    static SCIP_DECL_READERWRITE(readerWriteCsol)
    Definition: reader_csol.c:321
    static SCIP_DECL_READERCOPY(readerCopyCsol)
    Definition: reader_csol.c:82
    #define READER_DESC
    Definition: reader_csol.c:48
    #define COL_MAX_LINELEN
    Definition: reader_csol.c:51
    #define READER_EXTENSION
    Definition: reader_csol.c:49
    SCIP_RETCODE SCIPincludeReaderCsol(SCIP *scip)
    Definition: reader_csol.c:437
    #define READER_NAME
    Definition: reader_csol.c:47
    static SCIP_DECL_READERREAD(readerReadCsol)
    Definition: reader_csol.c:94
    static long getNextNumber(char **s)
    Definition: reader_csol.c:61
    file reader and writer for vertex coloring solutions
    int * tcliqueGetLastAdjedge(TCLIQUE_GRAPH *tcliquegraph, int node)
    int * tcliqueGetFirstAdjedge(TCLIQUE_GRAPH *tcliquegraph, int node)
    struct TCLIQUE_Graph TCLIQUE_GRAPH
    Definition: tclique.h:49
    struct SCIP_ReaderData SCIP_READERDATA
    Definition: type_reader.h:54
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    @ SCIP_NOFILE
    Definition: type_retcode.h:47
    @ SCIP_READERROR
    Definition: type_retcode.h:45
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    @ SCIP_INVALIDCALL
    Definition: type_retcode.h:51
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_STAGE_INIT
    Definition: type_set.h:44
    struct SCIP_VarData SCIP_VARDATA
    Definition: type_var.h:167
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64