Scippy

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 2002-2022 Zuse Institute Berlin */
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 <assert.h>
40 #include <string.h>
41 #include <ctype.h>
42 #include <stdlib.h>
43 
44 #include "reader_csol.h"
45 #include "reader_col.h"
46 #include "probdata_coloring.h"
47 
48 
49 #define READER_NAME "csolreader"
50 #define READER_DESC "file reader which reads and writes csol-files"
51 #define READER_EXTENSION "csol"
52 
53 #define COL_MAX_LINELEN 65535
54 
55 
56 
57 /*
58  * Local methods
59  */
60 
61 /** get next number from string s */
62 static
64  char** s /**< pointer to the pointer of the current position in the string */
65  )
66 {
67  long tmp;
68  /* skip whitespaces */
69  while ( isspace(**s) )
70  ++(*s);
71  /* read number */
72  tmp = atol(*s);
73  /* skip whitespaces */
74  while ( (**s != 0) && (!isspace(**s)) )
75  ++(*s);
76  return tmp;
77 }
78 
79 
80 /* put your local methods here, and declare them static */
81 
82 /** copy method for reader plugins (called when SCIP copies plugins) */
83 static
84 SCIP_DECL_READERCOPY(readerCopyCsol)
85 { /*lint --e{715}*/
86  assert(scip != NULL);
87  assert(reader != NULL);
88  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
89 
90  return SCIP_OKAY;
91 }
92 
93 /** problem reading method of reader */
94 static
95 SCIP_DECL_READERREAD(readerReadCsol)
96 {
97  SCIP_FILE* fp; /* file-reader */
98  char buf[COL_MAX_LINELEN]; /* maximal length of line */
99  char* char_p;
100  char* solprobname;
101  const char* probname;
102 
103  SCIP_Bool correctinstance;
104  TCLIQUE_GRAPH* graph;
105  SCIP_VAR* var;
106  SCIP_CONS** constraints;
107 
108  int** sets;
109  int* setlengths;
110  int nsets;
111  int setindex;
112 
113  int i;
114  int j;
115  int k;
116  int color;
117  int node;
118 
119  assert(reader != NULL);
120  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
121  assert(scip != NULL);
122  assert(result != NULL);
123  assert(filename != NULL);
124  *result = SCIP_SUCCESS;
125 
127  {
128  SCIPerrorMessage("Please read in problem before reading the solution!\n");
129  return SCIP_OKAY;
130  }
131 
132  if (NULL == (fp = SCIPfopen(filename, "r")))
133  {
134  SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
135  perror(filename);
136  return SCIP_NOFILE;
137  }
138 
139  /* Read out the name of the problem belonging to this solution*/
140  if( SCIPfgets(buf, (int) sizeof(buf), fp) == NULL )
141  return SCIP_READERROR;
142 
143  i = 1;
144  while ( !isspace(buf[i]) )
145  {
146  i++;
147  }
148  SCIP_CALL( SCIPallocBufferArray(scip, &solprobname, i+2) );
149  strncpy(solprobname, &buf[0], (unsigned int) i);
150  solprobname[i]= '\0';
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 
188  size = COLORprobGetOriginalNNodes(scip) + 1;
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);
306  SCIPfreeBufferArray(scip, &sets);
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 */
320 static
321 SCIP_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);
348  oldgraph = COLORprobGetOriginalGraph(scip);
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 */
356  SCIP_CALL( SCIPallocBufferArray(scip, &colors, nnodes) );
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  {
366  if ( SCIPgetSolVal(scip, sol, COLORprobGetVarForStableSet(scip, i)) > 0 )
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 }
SCIP_RETCODE SCIPaddCoefSetppc(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
Definition: cons_setppc.c:9385
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:365
int COLORprobGetOriginalNNodes(SCIP *scip)
static long getNextNumber(char **s)
Definition: reader_csol.c:63
struct TCLIQUE_Graph TCLIQUE_GRAPH
Definition: tclique.h:49
problem data for vertex coloring algorithm
const char * SCIPreaderGetName(SCIP_READER *reader)
Definition: reader.c:557
SCIP_RETCODE SCIPchgVarUbLazy(SCIP *scip, SCIP_VAR *var, SCIP_Real lazyub)
Definition: scip_var.c:5170
#define FALSE
Definition: def.h:96
struct SCIP_VarData SCIP_VARDATA
Definition: type_var.h:116
static SCIP_DECL_READERREAD(readerReadCsol)
Definition: reader_csol.c:95
SCIP_RETCODE SCIPincludeReaderCsol(SCIP *scip)
Definition: reader_csol.c:437
#define TRUE
Definition: def.h:95
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
file reader for vertex coloring instances
void COLORprobGetStableSets(SCIP *scip, int ***stablesets, int **nelements, int *nstablesets)
#define READER_NAME
Definition: reader_csol.c:49
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
int COLORprobGetNewNodeForOriginalNode(SCIP *scip, int node)
const char * SCIPgetProbName(SCIP *scip)
Definition: scip_prob.c:1075
int * COLORprobGetOriginalNodesForNewNodes(SCIP *scip)
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:153
#define READER_DESC
Definition: reader_csol.c:50
TCLIQUE_GRAPH * COLORprobGetGraph(SCIP *scip)
static SCIP_DECL_READERWRITE(readerWriteCsol)
Definition: reader_csol.c:321
#define SCIPerrorMessage
Definition: pub_message.h:64
int COLORprobGetNNodes(SCIP *scip)
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:43
char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
Definition: fileio.c:200
SCIP_RETCODE COLORprobAddVarForStableSet(SCIP *scip, int setindex, SCIP_VAR *var)
SCIP_RETCODE COLORprobAddNewStableSet(SCIP *scip, int *stablesetnodes, int nstablesetnodes, int *setindex)
TCLIQUE_GRAPH * COLORprobGetOriginalGraph(SCIP *scip)
#define NULL
Definition: lpi_spx1.cpp:164
#define SCIP_CALL(x)
Definition: def.h:393
SCIP_VAR * COLORprobGetVarForStableSet(SCIP *scip, int setindex)
static SCIP_DECL_READERCOPY(readerCopyCsol)
Definition: reader_csol.c:84
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
struct SCIP_ReaderData SCIP_READERDATA
Definition: type_reader.h:53
#define COL_MAX_LINELEN
Definition: reader_csol.c:53
#define SCIP_Bool
Definition: def.h:93
SCIP_CONS ** COLORprobGetConstraints(SCIP *scip)
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
int * tcliqueGetLastAdjedge(TCLIQUE_GRAPH *tcliquegraph, int node)
#define READER_EXTENSION
Definition: reader_csol.c:51
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:114
int * COLORprobGetDeletedNodes(SCIP *scip)
int * tcliqueGetFirstAdjedge(TCLIQUE_GRAPH *tcliquegraph, int node)
SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
Definition: scip_reader.c:219
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:147
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
Definition: scip_sol.c:2313
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1676
void SCIPsortDownInt(int *intarray, int len)
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:195
#define nnodes
Definition: gastrans.c:74
file reader and writer for vertex coloring solutions
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1361