Scippy

SCIP

Solving Constraint Integer Programs

reader_cyc.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-2024 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_cyc.c
26  * @brief file reader for cycle clustering instances
27  * @author Leon Eifler
28  *
29  * This file implements the reader for the cycle clustering problem. The data is read from a matrix, entries separated
30  * by whitespace. The first line in the file has to be of the form "# p nstates ncluster",
31  * where nstates is the size of the matrix and ncluster is the number of clusters that should be used.
32  * The file has to have the ending ".cyc" to be recognized by the reader.
33  */
34 
35 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
36 #include "reader_cyc.h"
37 
38 #include <assert.h>
39 #include <string.h>
40 #include <ctype.h>
41 #include "probdata_cyc.h"
42 
43 #define READER_NAME "cycreader"
44 #define READER_DESC "file reader for a .cyc-file with a transition matrix for a cycle clustering problem"
45 #define READER_EXTENSION "cyc"
46 
47 #define COL_MAX_LINELEN 10000
48 
49 
50 /*
51  * Local methods
52  */
53 
54 /** get next number from string s */
55 static
57  char** s /**< pointer to the pointer of the current position in the string */
58  )
59 {
60  SCIP_Real tmp;
61 
62  /* skip whitespaces */
63  while( isspace(**s) )
64  ++(*s);
65  /* read number */
66  tmp = atof(*s);
67  /* skip whitespaces */
68  while( (**s != 0) && (!isspace(**s)) )
69  ++(*s);
70 
71  return tmp;
72 }
73 
74 /** read LP in Cyc File Format.
75  * That means first line is "p edges nbins ncluster".
76  * Then a matrix with whitespace-separated entries of size nbins x nbins
77 */
78 static
80  SCIP* scip, /**< SCIP data structure */
81  const char* filename /**< name of the input file */
82  )
83 {
84  SCIP_FILE* fp; /* file-reader */
85  char buf[COL_MAX_LINELEN]; /* maximal length of line */
86  char* char_p; /* current char */
87  SCIP_Real** cmatrix; /* transition matrix */
88  int nbins; /* number of states */
89  int ncluster; /* number of clusters */
90  int i;
91  int col;
92 
93  assert(scip != NULL);
94  assert(filename != NULL);
95 
96  if( NULL == (fp = SCIPfopen(filename, "r")) )
97  {
98  SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
99  perror(filename);
100  return SCIP_NOFILE;
101  }
102 
103  /* Get problem name from filename and save it */
104  if( SCIPfgets(buf, (int) sizeof(buf), fp) == NULL )
105  return SCIP_READERROR;
106 
107  while( !SCIPfeof(fp) && (buf[0] != '#' || buf[2] != 'p') )
108  {
109  SCIPfgets(buf, (int) sizeof(buf), fp); /*lint !e534*/
110  }
111 
112  /* no graph information in file! */
113  if( SCIPfeof(fp) )
114  {
115  SCIPerrorMessage("Error! Could not find line starting with 'p'.\n");
116  return SCIP_READERROR;
117  }
118  char_p = &buf[3];
119 
120  /* read out number of nodes and edges, the pointer char_p will be changed */
121  nbins = (int) getNextNumber(&char_p);
122  ncluster = (int) getNextNumber(&char_p);
123 
124  if( nbins <= 0 )
125  {
126  SCIPerrorMessage("Number of bins must be positive!\n");
127  return SCIP_READERROR;
128  }
129 
130  if( ncluster <= 0 || nbins <= ncluster )
131  {
132  SCIPerrorMessage("Number of cluster must be positive and smaller than number of bins!\n");
133  return SCIP_READERROR;
134  }
135 
136  /* create cmatrix */
137  SCIP_CALL( SCIPallocMemoryArray(scip, &cmatrix, nbins) );
138  for( i = 0; i < nbins; i++ )
139  {
140  SCIP_CALL( SCIPallocMemoryArray(scip, &(cmatrix[i]), nbins) ); /*lint !e866*/
141  }
142 
143  /* fill array the cmatrix */
144  i = 0;
145  while( !SCIPfeof(fp) && i < nbins )
146  {
147  SCIPfgets(buf, (int) sizeof(buf), fp); /*lint !e534*/
148  char_p = &buf[0];
149  for( col = 0; col < nbins; ++col )
150  {
151  cmatrix[i][col] = (SCIP_Real) getNextNumber(&char_p);
152  }
153 
154  if( i >= nbins )
155  {
156  SCIPerrorMessage( "more lines than expected: expected %d many, but got already %d'th (non-duplicate) edge",
157  nbins, i+1 );
158 
159  return SCIP_READERROR;
160  }
161 
162  i++;
163  }
164 
165  /* create problem data */
166  SCIP_CALL( SCIPcreateProbCyc(scip, filename, nbins, ncluster, cmatrix) );
167 
168  SCIPinfoMessage(scip, NULL, "Original problem: \n");
169 
170  for( i = nbins - 1; i >= 0; i-- )
171  {
172  SCIPfreeMemoryArray(scip, &(cmatrix[i]));
173  }
174 
175  SCIPfreeMemoryArray(scip, &cmatrix);
176 
177  SCIPfclose(fp);
178 
179  return SCIP_OKAY;
180 }
181 
182 /*
183  * Callback methods of reader
184  */
185 
186 /** copy method for reader plugins (called when SCIP copies plugins) */
187 static
188 SCIP_DECL_READERCOPY(readerCopyCyc)
189 {
190  assert(scip != NULL);
191  assert(reader != NULL);
192  assert(strcmp( SCIPreaderGetName(reader), READER_NAME) == 0);
193 
194  return SCIP_OKAY;
195 }
196 
197 /** problem reading method of reader */
198 static
199 SCIP_DECL_READERREAD(readerReadCyc)
200 {
201  assert(reader != NULL);
202  assert(strcmp( SCIPreaderGetName(reader), READER_NAME) == 0);
203  assert(scip != NULL);
204  assert(result != NULL);
205 
206  SCIP_CALL( readCyc( scip, filename) );
207 
208  *result = SCIP_SUCCESS;
209 
210  return SCIP_OKAY;
211 }
212 
213 /*
214  * cyc file reader specific interface methods
215  */
216 
217 /** includes the cyc file reader in SCIP */
219  SCIP* scip /**< SCIP data structure */
220  )
221 {
222  SCIP_READERDATA* readerdata;
223  SCIP_READER* reader;
224 
225  /* create cyc reader data */
226  readerdata = NULL;
227 
228  /* include cyc reader */
230  readerdata) );
231 
232  SCIP_CALL( SCIPsetReaderCopy( scip, reader, readerCopyCyc) );
233  SCIP_CALL( SCIPsetReaderRead( scip, reader, readerReadCyc ) );
234 
235  SCIP_CALL( SCIPaddRealParam(scip,"cycleclustering/scale_coherence",
236  "factor to scale the cohrence in the target function", NULL, FALSE, 0.001, 0.0, 1.0, NULL, NULL ) );
237  SCIP_CALL( SCIPaddCharParam(scip, "cycleclustering/model",
238  "the model variant", NULL, FALSE, 's', "seqt", NULL, NULL) );
239  SCIP_CALL( SCIPaddBoolParam(scip, "cycleclustering/usecutselection",
240  "true if cut selection should be used in cyc-separators", NULL, FALSE, TRUE, NULL, NULL) );
241  SCIP_CALL( SCIPaddRealParam(scip, "cycleclustering/goodscorefac", "used for cut-selection in cycle-clustering",
242  NULL, FALSE, 0.8, 0.0, 1.0, NULL, NULL) );
243  SCIP_CALL( SCIPaddRealParam(scip, "cycleclustering/badscorefac", "used for cut-selection in cycle-clustering",
244  NULL, FALSE, 0.0, 0.0, 1.0, NULL, NULL) );
245  SCIP_CALL( SCIPaddRealParam(scip, "cycleclustering/goodmaxparall", "used for cut-selection in cycle-clustering",
246  NULL, FALSE, 0.1, 0.0, 1.0, NULL, NULL) );
247  SCIP_CALL( SCIPaddRealParam(scip, "cycleclustering/maxparall", "used for cut-selection in cycle-clustering",
248  NULL, FALSE, 0.5, 0.0, 1.0, NULL, NULL) );
249  SCIP_CALL( SCIPaddRealParam(scip, "cycleclustering/dircutoffdist", "used for cut-selection in cycle-clustering",
250  NULL, FALSE, 0.5, 0.0, 1.0, NULL, NULL) );
251  SCIP_CALL( SCIPaddRealParam(scip, "cycleclustering/efficacyweight", "used for cut-selection in cycle-clustering",
252  NULL, FALSE, 0.4, 0.0, 1.0, NULL, NULL) );
253  SCIP_CALL( SCIPaddRealParam(scip, "cycleclustering/objparalweight", "used for cut-selection in cycle-clustering",
254  NULL, FALSE, 0.1, 0.0, 1.0, NULL, NULL) );
255  SCIP_CALL( SCIPaddRealParam(scip, "cycleclustering/intsuppweight", "used for cut-selection in cycle-clustering",
256  NULL, FALSE, 0.3, 0.0, 1.0, NULL, NULL) );
257 
258  return SCIP_OKAY;
259 }
SCIP_RETCODE SCIPcreateProbCyc(SCIP *scip, const char *name, int nbins, int ncluster, SCIP_Real **cmatrix)
#define NULL
Definition: def.h:267
SCIP_RETCODE SCIPincludeReaderCyc(SCIP *scip)
Definition: reader_cyc.c:218
#define READER_DESC
Definition: reader_cyc.c:44
#define SCIPfreeMemoryArray(scip, ptr)
Definition: scip_mem.h:80
static SCIP_DECL_READERCOPY(readerCopyCyc)
Definition: reader_cyc.c:188
#define SCIPallocMemoryArray(scip, ptr, num)
Definition: scip_mem.h:64
const char * SCIPreaderGetName(SCIP_READER *reader)
Definition: reader.c:557
static SCIP_Real getNextNumber(char **s)
Definition: reader_cyc.c:56
#define FALSE
Definition: def.h:94
#define TRUE
Definition: def.h:93
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
#define READER_EXTENSION
Definition: reader_cyc.c:45
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:153
#define SCIPerrorMessage
Definition: pub_message.h:64
int SCIPfeof(SCIP_FILE *stream)
Definition: fileio.c:227
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:43
char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
Definition: fileio.c:200
static SCIP_RETCODE readCyc(SCIP *scip, const char *filename)
Definition: reader_cyc.c:79
#define SCIP_CALL(x)
Definition: def.h:380
struct SCIP_ReaderData SCIP_READERDATA
Definition: type_reader.h:53
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
problem data for cycle clustering problem
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:147
static SCIP_DECL_READERREAD(readerReadCyc)
Definition: reader_cyc.c:199
#define COL_MAX_LINELEN
Definition: reader_cyc.c:47
SCIP_RETCODE SCIPaddCharParam(SCIP *scip, const char *name, const char *desc, char *valueptr, SCIP_Bool isadvanced, char defaultvalue, const char *allowedvalues, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:167
file reader for cycle clustering instances
#define SCIP_Real
Definition: def.h:173
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:195
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:232
#define READER_NAME
Definition: reader_cyc.c:43
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 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