Scippy

SCIP

Solving Constraint Integer Programs

ReaderTSP.cpp
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 ReaderTSP.cpp
26  * @brief C++ file reader for TSP data files
27  * @author Timo Berthold
28  */
29 
30 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
31 
32 #include <iostream>
33 #include <string>
34 #include <sstream>
35 
36 #include "objscip/objscip.h"
37 
38 #include "scip/cons_linear.h"
39 #include "scip/pub_fileio.h"
40 #include <math.h>
41 
42 #include "ReaderTSP.h"
43 #include "ProbDataTSP.h"
44 #include "ConshdlrSubtour.h"
45 #include "GomoryHuTree.h"
46 
47 using namespace tsp;
48 using namespace scip;
49 using namespace std;
50 
51 #define NINT(x) (floor(x+0.5))
52 
53 /** get token */
54 string getToken(char*& str)
55 {
56  string token;
57 
58  // skip spaces and ':'
59  while( *str != '\0' && ( isspace(*str) || *str == ':') )
60  ++str;
61 
62  // collect token
63  while( *str != '\0' && *str != ':' && ! isspace(*str) )
64  {
65  token += *str;
66  ++str;
67  }
68 
69  // skip spaces and ':'
70  while( *str != '\0' && ( isspace(*str) || *str == ':') )
71  ++str;
72 
73  return token;
74 }
75 
76 /** parses the node list */
77 SCIP_RETCODE ReaderTSP::getNodesFromFile(
78  SCIP_FILE* file, /**< file containing the data to extract */
79  double* x_coords, /**< double array to be filled with the x-coordinates of the nodes */
80  double* y_coords, /**< same for y-coordinates */
81  GRAPH* graph /**< the graph which is to be generated by the nodes */
82  )
83 {
84  char str[SCIP_MAXSTRLEN];
85  int i = 0;
86  int nodenumber;
87  GRAPHNODE* node = &(graph->nodes[0]);
88 
89  // extract every node out of the filestream
90  while ( i < graph->nnodes && ! SCIPfeof(file) )
91  {
92  // read next line
93  (void) SCIPfgets(str, SCIP_MAXSTRLEN, file);
94  char* s = str;
95 
96  if ( ! SCIPstrToIntValue(str, &nodenumber, &s) )
97  {
98  SCIPerrorMessage("Could not read node number:\n%s\n", str);
99  return SCIP_INVALIDDATA;
100  }
101 
102  if ( ! SCIPstrToRealValue(s, &x_coords[i], &s) )
103  {
104  SCIPerrorMessage("Could not read x coordinate:\n%s\n", str);
105  return SCIP_INVALIDDATA;
106  }
107 
108  if ( ! SCIPstrToRealValue(s, &y_coords[i], &s) )
109  {
110  SCIPerrorMessage("Could not read x coordinate:\n%s\n", str);
111  return SCIP_INVALIDDATA;
112  }
113 
114  // assign everything
115  node->id = i;
116  if( nodenumber-1 != i)
117  {
118  cout << "warning: nodenumber <" << nodenumber << "> does not match its index in node list <" << i+1
119  << ">. Node will get number " << i+1 << " when naming variables and constraints!" << endl;
120  return SCIP_INVALIDDATA;
121  }
122  node->x = x_coords[i];
123  node->y = y_coords[i];
124  node->first_edge = NULL;
125  node++;
126  i++;
127  }
128  assert( i == graph->nnodes );
129 
130  return SCIP_OKAY;
131 } /*lint !e1762*/
132 
133 /** adds a variable to both halfedges and captures it for usage in the graph */
134 SCIP_RETCODE ReaderTSP::addVarToEdges(
135  SCIP* scip, /**< SCIP data structure */
136  GRAPHEDGE* edge, /**< an edge of the graph */
137  SCIP_VAR* var /**< variable corresponding to that edge */
138  )
139 {
140  assert(scip != NULL);
141  assert(edge != NULL);
142  assert(var != NULL);
143 
144  /* add variable to forward edge and capture it for usage in graph */
145  edge->var = var;
146  SCIP_CALL( SCIPcaptureVar(scip, edge->var) );
147 
148  /* two parallel halfedges have the same variable,
149  * add variable to backward edge and capture it for usage in graph */
150  edge->back->var = edge->var;
151  SCIP_CALL( SCIPcaptureVar(scip, edge->back->var) );
152 
153  return SCIP_OKAY;
154 }
155 
156 /** method asserting, that the file has had the correct format and everything was set correctly */
157 bool ReaderTSP::checkValid(
158  GRAPH* graph, /**< the constructed graph, schould not be NULL */
159  const std::string& name, /**< the name of the file */
160  const std::string& type, /**< the type of the problem, should be "TSP" */
161  const std::string& edgeweighttype, /**< type of the edgeweights, should be "EUC_2D", "MAX_2D", "MAN_2D",
162  * "ATT", or "GEO" */
163  int nnodes /**< dimension of the problem, should at least be one */
164  )
165 {
166  // if something seems to be strange, it will be reported, that file was not valid
167  if( nnodes < 1 )
168  {
169  cout << "parse error in file <" << name << "> dimension should be greater than 0"<< endl ;
170  return false;
171  }
172 
173  if (type != "TSP" )
174  {
175  cout << "parse error in file <" << name << "> type should be TSP" << endl;
176  return false;
177  }
178 
179  if ( !( edgeweighttype == "EUC_2D" || edgeweighttype == "MAX_2D" || edgeweighttype == "MAN_2D"
180  || edgeweighttype == "GEO" || edgeweighttype == "ATT") )
181  {
182  cout << "parse error in file <" << name << "> unknown weight type, should be EUC_2D, MAX_2D, MAN_2D, ATT, or GEO" << endl;
183  return false;
184  }
185 
186  if( graph == NULL)
187  {
188  cout << "error while reading file <" << name << ">, graph is uninitialized. ";
189  cout << "Probably NODE_COORD_SECTION is missing" << endl;
190  return false;
191  }
192 
193  return true;
194 } /*lint !e1762*/
195 
196 
197 /** destructor of file reader to free user data (called when SCIP is exiting) */
198 SCIP_DECL_READERFREE(ReaderTSP::scip_free)
199 { /*lint --e{715}*/
200  return SCIP_OKAY;
201 }
202 
203 /** problem reading method of reader
204  *
205  * possible return values for *result:
206  * - SCIP_SUCCESS : the reader read the file correctly and created an appropritate problem
207  * - SCIP_DIDNOTRUN : the reader is not responsible for given input file
208  *
209  * If the reader detected an error in the input file, it should return with RETCODE SCIP_READERR or SCIP_NOFILE.
210  */
211 SCIP_DECL_READERREAD(ReaderTSP::scip_read)
212 { /*lint --e{715}*/
213  SCIP_RETCODE retcode;
214 
215  GRAPH* graph = NULL;
216  GRAPHNODE* node;
217  GRAPHNODE* nodestart; // the two incident nodes of an edge
218  GRAPHNODE* nodeend;
219  GRAPHEDGE* edgeforw; // two converse halfedges
220  GRAPHEDGE* edgebackw;
221  GRAPHEDGE* edge;
222 
223  double* x_coords = NULL; // arrays of coordinates of the nodes
224  double* y_coords = NULL;
225 
226 #ifdef SCIP_DEBUG
227  double** weights = NULL;
228 #endif
229 
230  double x; // concrete coordinates
231  double y;
232 
233  int nnodes = 0;
234  int nedges = 0;
235  int i;
236  int j;
237 
238  string name = "MY_OWN_LITTLE_TSP";
239  string token;
240  string type = "TSP";
241  string edgeweighttype = "EUC_2D";
242 
243  retcode = SCIP_OKAY;
244  *result = SCIP_DIDNOTRUN;
245 
246  // open the file
247  SCIP_FILE* file = SCIPfopen(filename, "r");
248  if( !file )
249  return SCIP_READERROR;
250 
251  // read the first lines of information
252  char str[SCIP_MAXSTRLEN];
253  (void) SCIPfgets(str, SCIP_MAXSTRLEN, file);
254 
255  // get first token
256  char* s = str;
257  token = getToken(s);
258 
259  while( ! SCIPfeof(file) )
260  {
261  if( token == "NAME" )
262  name = getToken(s);
263  else if( token == "TYPE" )
264  type = getToken(s);
265  else if( token == "DIMENSION" )
266  {
267  if ( ! SCIPstrToIntValue(s, &nnodes, &s) )
268  {
269  SCIPerrorMessage("Could not read number of nodes:\n%s\n", s);
270  return SCIP_INVALIDDATA;
271  }
272  nedges = nnodes * (nnodes-1);
273  }
274  else if( token == "EDGE_WEIGHT_TYPE" )
275  edgeweighttype = getToken(s);
276  else if( token == "NODE_COORD_SECTION" || token == "DISPLAY_DATA_SECTION" )
277  {
278  // there should be some nodes to construct a graph
279  if( nnodes < 1 )
280  {
281  retcode = SCIP_READERROR;
282  break;
283  }
284  // the graph is created and filled with nodes
285  else if( create_graph(nnodes, nedges, &graph) )
286  {
287  assert(x_coords == NULL);
288  assert(y_coords == NULL);
289 
290  x_coords = new double[nnodes];
291  y_coords = new double[nnodes];
292  SCIP_CALL( getNodesFromFile(file, x_coords, y_coords, graph) );
293  }
294  else
295  {
296  retcode = SCIP_NOMEMORY;
297  break;
298  }
299  }
300  else if( token == "COMMENT:" || token == "COMMENT" || token == "DISPLAY_DATA_TYPE" || token == "DISPLAY_DATA_TYPE:" )
301  {
302  // do nothing
303  }
304  else if( token == "EOF" )
305  break;
306  else if( token == "" )
307  ;
308  else
309  {
310  cout << "parse error in file <" << name << "> unknown keyword <" << token << ">" << endl;
311  return SCIP_READERROR;
312  }
313  (void) SCIPfgets(str, SCIP_MAXSTRLEN, file);
314  s = str;
315  token = getToken(s);
316  }// finished parsing the input
317 
318  SCIPfclose(file);
319 
320  // check whether the input data was valid
321  if( ! checkValid(graph, name, type, edgeweighttype, nnodes) )
322  retcode = SCIP_READERROR;
323 
324  assert(graph != NULL);
325 
326  if( retcode == SCIP_OKAY )
327  {
328  edgeforw = &( graph->edges[0] ); /*lint !e613*/
329  edgebackw= &( graph->edges[nedges/2] ); /*lint !e613*/
330 
331 #ifdef SCIP_DEBUG
332  weights = new double* [nnodes];
333  for( i = 0; i < nnodes; ++i )
334  weights[i] = new double[nnodes];
335 #endif
336 
337  // construct all edges in a complete digraph
338  for( i = 0; i < nnodes; i++ )
339  {
340  nodestart = &graph->nodes[i]; /*lint !e613*/
341  for( j = i+1; j < nnodes; j++ )
342  {
343  nodeend = &graph->nodes[j]; /*lint !e613*/
344 
345  // construct two 'parallel' halfedges
346  edgeforw->adjac = nodeend;
347  edgebackw->adjac = nodestart;
348  edgeforw->back = edgebackw;
349  edgebackw->back = edgeforw;
350 
351  // calculate the Euclidean / Manhattan / Maximum distance of the two nodes
352  x = x_coords[(*nodestart).id] - x_coords[(*nodeend).id]; /*lint !e613*/
353  y = y_coords[(*nodestart).id] - y_coords[(*nodeend).id]; /*lint !e613*/
354  if( edgeweighttype == "EUC_2D")
355  edgeforw->length = sqrt( x*x + y*y );
356  else if( edgeweighttype == "MAX_2D")
357  edgeforw->length = MAX( ABS(x), ABS(y) );
358  else if( edgeweighttype == "MAN_2D")
359  edgeforw->length = ABS(x) + ABS(y);
360  else if( edgeweighttype == "ATT")
361  edgeforw->length = ceil( sqrt( (x*x+y*y)/10.0 ) );
362  else if( edgeweighttype == "GEO")
363  {
364  const double pi = 3.141592653589793;
365  double rads[4];
366  double coords[4];
367  double degs[4];
368  double mins[4];
369  double euler[3];
370  int k;
371 
372  coords[0] = x_coords[(*nodestart).id]; /*lint !e613*/
373  coords[1] = y_coords[(*nodestart).id]; /*lint !e613*/
374  coords[2] = x_coords[(*nodeend).id]; /*lint !e613*/
375  coords[3] = y_coords[(*nodeend).id]; /*lint !e613*/
376 
377  for( k = 0; k < 4; k++ )
378  {
379  degs[k] = coords[k] >= 0 ? floor(coords[k]) : ceil(coords[k]);
380  mins[k] = coords[k] - degs[k];
381  rads[k] = pi*(degs[k]+5.0*mins[k]/3.0)/180.0;
382  }
383 
384  euler[0] = cos(rads[1]-rads[3]);
385  euler[1] = cos(rads[0]-rads[2]);
386  euler[2] = cos(rads[0]+rads[2]);
387  edgeforw->length = floor(6378.388 * acos(0.5*((1.0+euler[0])*euler[1]-(1.0-euler[0])*euler[2]))+1.0);
388  }
389 
390  // in TSP community, it is common practice to round lengths to next integer
391  if( round_lengths_ )
392  edgeforw->length = NINT(edgeforw->length);
393 
394  edgebackw->length = edgeforw->length;
395 #ifdef SCIP_DEBUG
396  weights[i][j] = edgeforw->length;
397  weights[j][i] = edgebackw->length;
398 #endif
399 
400  // insert one of the halfedges into the edge list of the node
401  if (nodestart->first_edge == NULL)
402  {
403  nodestart->first_edge = edgeforw;
404  nodestart->first_edge->next = NULL;
405  }
406  else
407  {
408  edgeforw->next = nodestart->first_edge;
409  nodestart->first_edge = edgeforw;
410  }
411 
412  // dito
413  if (nodeend->first_edge == NULL)
414  {
415  nodeend->first_edge = edgebackw;
416  nodeend->first_edge->next = NULL;
417  }
418  else
419  {
420  edgebackw->next = nodeend->first_edge;
421  nodeend->first_edge = edgebackw;
422  }
423 
424  edgeforw++;
425  edgebackw++;
426  }
427  }
428  }
429 
430  delete[] y_coords;
431  delete[] x_coords;
432 
433  if( retcode != SCIP_OKAY )
434  {
435 #ifdef SCIP_DEBUG
436  if( weights != NULL )
437  {
438  for( i = 0; i < nnodes; i++ )
439  {
440  delete[] weights[i];
441  }
442  delete[] weights;
443  }
444 #endif
445  return retcode;
446  }
447 
448 #ifdef SCIP_DEBUG
449  printf("Matrix:\n");
450  for( i = 0; i < nnodes; i++ )
451  {
452  for( j = 0; j < nnodes; j++ )
453  printf(" %4.0f ",weights[i][j]);
454  printf("\n");
455  delete[] weights[i];
456  }
457  delete[] weights;
458 #endif
459 
460  // create the problem's data structure
461  SCIP_CALL( SCIPcreateObjProb(scip, name.c_str(), new ProbDataTSP(graph), TRUE) );
462 
463  // add variables to problem and link them for parallel halfedges
464  for( i = 0; i < nedges/2; i++ )
465  {
466  SCIP_VAR* var;
467 
468  stringstream varname;
469  edge = &graph->edges[i]; /*lint !e613*/
470 
471 /**! [SnippetTSPVariableCreation] */
472 
473  // the variable is named after the two nodes connected by the edge it represents
474  varname << "x_e_" << edge->back->adjac->id+1 << "-" << edge->adjac->id+1;
475  SCIP_CALL( SCIPcreateVar(scip, &var, varname.str().c_str(), 0.0, 1.0, edge->length,
477 
478  /* add variable to SCIP and to the graph */
479  SCIP_CALL( SCIPaddVar(scip, var) );
480  SCIP_CALL( addVarToEdges(scip, edge, var) );
481 
482  /* release variable for the reader. */
483  SCIP_CALL( SCIPreleaseVar(scip, &var) );
484 
485 /**! [SnippetTSPVariableCreation] */
486 
487  }
488 
489  /* add all n node degree constraints */
490  if( nnodes >= 2 )
491  {
492  for( i = 0, node = &(graph->nodes[0]); i < nnodes; i++, node++ ) /*lint !e613*/
493  {
494 /**! [SnippetTSPDegreeConstraintCreation] */
495  SCIP_CONS* cons;
496  stringstream consname;
497  consname << "deg_con_v" << node->id+1;
498 
499  // a new degree constraint is created, named after a node
500  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, consname.str().c_str(), 0, NULL, NULL, 2.0, 2.0,
502 
503  edge = node->first_edge;
504  // sum up the values of all adjacent edges
505  while( edge != NULL )
506  {
507  SCIP_CALL( SCIPaddCoefLinear(scip, cons, edge->var, 1.0) );
508  edge = edge->next;
509  }
510 
511  // add the constraint to SCIP
512  SCIP_CALL( SCIPaddCons(scip, cons) );
513  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
514 /**! [SnippetTSPDegreeConstraintCreation] */
515  }
516  }
517 
518 /**! [SnippetTSPNosubtourConstraintCreation] */
519 
520  /* last, we need a constraint forbidding subtours */
521  SCIP_CONS* cons;
522  SCIP_CALL( SCIPcreateConsSubtour(scip, &cons, "subtour", graph,
523  FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE ) );
524  SCIP_CALL( SCIPaddCons(scip, cons) );
525  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
526 
527 /**! [SnippetTSPNosubtourConstraintCreation] */
528 
529  release_graph(&graph);
530  *result = SCIP_SUCCESS;
531 
532  return SCIP_OKAY;
533 }
534 
535 /** problem writing method of reader; NOTE: if the parameter "genericnames" is TRUE, then
536  * SCIP already set all variable and constraint names to generic names; therefore, this
537  * method should always use SCIPvarGetName() and SCIPconsGetName();
538  *
539  * possible return values for *result:
540  * - SCIP_SUCCESS : the reader read the file correctly and created an appropritate problem
541  * - SCIP_DIDNOTRUN : the reader is not responsible for given input file
542  *
543  * If the reader detected an error in the writing to the file stream, it should return
544  * with RETCODE SCIP_WRITEERROR.
545  */
546 SCIP_DECL_READERWRITE(ReaderTSP::scip_write)
547 { /*lint --e{715}*/
548  *result = SCIP_DIDNOTRUN;
549 
550  return SCIP_OKAY;
551 }
struct GraphEdge * next
Definition: GomoryHuTree.h:69
#define NULL
Definition: def.h:267
int nnodes
Definition: GomoryHuTree.h:82
GRAPHNODE * nodes
Definition: GomoryHuTree.h:86
double length
Definition: GomoryHuTree.h:67
#define SCIP_MAXSTRLEN
Definition: def.h:288
SCIP_Bool create_graph(int n, int m, GRAPH **gr)
SCIP_DECL_READERFREE(ReaderTSP::scip_free)
Definition: ReaderTSP.cpp:198
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1247
#define FALSE
Definition: def.h:94
#define TRUE
Definition: def.h:93
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
SCIP_DECL_READERWRITE(ReaderTSP::scip_write)
Definition: ReaderTSP.cpp:546
generator for global cuts in undirected graphs
SCIP_Bool SCIPstrToIntValue(const char *str, int *value, char **endptr)
Definition: misc.c:10946
SCIP_VAR ** x
Definition: circlepacking.c:63
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:153
SCIP_VAR * var
Definition: GomoryHuTree.h:74
SCIP_RETCODE SCIPcreateConsSubtour(SCIP *scip, SCIP_CONS **cons, const char *name, GRAPH *graph, 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)
#define SCIPerrorMessage
Definition: pub_message.h:64
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2770
Definition: pqueue.h:37
GRAPHNODE * adjac
Definition: GomoryHuTree.h:72
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
struct GraphEdge * back
Definition: GomoryHuTree.h:70
struct GraphEdge * first_edge
Definition: GomoryHuTree.h:53
GRAPHEDGE * edges
Definition: GomoryHuTree.h:87
C++ wrapper classes for SCIP.
#define SCIP_CALL(x)
Definition: def.h:380
wrapper functions to map file i/o to standard or zlib file i/o
C++ problem data for TSP.
C++ constraint handler for TSP subtour elimination constraints.
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:10977
#define NINT(x)
Definition: ReaderTSP.cpp: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
Constraint handler for linear constraints in their most general form, .
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, 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)
C++ file reader for TSP data files.
#define MAX(x, y)
Definition: def.h:239
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1668
double x
Definition: GomoryHuTree.h:45
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1174
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1213
SCIP_RETCODE SCIPcreateObjProb(SCIP *scip, const char *name, scip::ObjProbData *objprobdata, SCIP_Bool deleteobject)
SCIP_VAR ** y
Definition: circlepacking.c:64
string getToken(char *&str)
Definition: ReaderTSP.cpp:54
SCIP_DECL_READERREAD(ReaderTSP::scip_read)
Definition: ReaderTSP.cpp:211
double y
Definition: GomoryHuTree.h:46
void release_graph(GRAPH **gr)
#define nnodes
Definition: gastrans.c:74
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:232
#define ABS(x)
Definition: def.h:235