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-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 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
    47using namespace tsp;
    48using namespace scip;
    49using namespace std;
    50
    51#define NINT(x) (floor(x+0.5))
    52
    53/** get token */
    54string getToken(char*& str)
    55{
    56 string token;
    57
    58 // skip spaces and ':'
    59 while( *str != '\0' && ( isspace((unsigned char)*str) || *str == ':') )
    60 ++str;
    61
    62 // collect token
    63 while( *str != '\0' && *str != ':' && ! isspace((unsigned char)*str) )
    64 {
    65 token += *str;
    66 ++str;
    67 }
    68
    69 // skip spaces and ':'
    70 while( *str != '\0' && ( isspace((unsigned char)*str) || *str == ':') )
    71 ++str;
    72
    73 return token;
    74}
    75
    76/** parses the node list */
    77SCIP_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 */
    134SCIP_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;
    152
    153 return SCIP_OKAY;
    154}
    155
    156/** method asserting, that the file has had the correct format and everything was set correctly */
    157bool 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) */
    198SCIP_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 */
    211SCIP_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,
    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 */
    546SCIP_DECL_READERWRITE(ReaderTSP::scip_write)
    547{ /*lint --e{715}*/
    548 *result = SCIP_DIDNOTRUN;
    549
    550 return SCIP_OKAY;
    551}
    C++ constraint handler for TSP subtour elimination constraints.
    SCIP_Bool create_graph(int n, int m, GRAPH **gr)
    void release_graph(GRAPH **gr)
    generator for global cuts in undirected graphs
    C++ problem data for TSP.
    SCIP_DECL_READERREAD(ReaderTSP::scip_read)
    Definition: ReaderTSP.cpp:211
    #define NINT(x)
    Definition: ReaderTSP.cpp:51
    SCIP_DECL_READERWRITE(ReaderTSP::scip_write)
    Definition: ReaderTSP.cpp:546
    SCIP_DECL_READERFREE(ReaderTSP::scip_free)
    Definition: ReaderTSP.cpp:198
    string getToken(char *&str)
    Definition: ReaderTSP.cpp:54
    C++ file reader for TSP data files.
    SCIP_VAR ** y
    Definition: circlepacking.c:64
    SCIP_VAR ** x
    Definition: circlepacking.c:63
    Constraint handler for linear constraints in their most general form, .
    #define NULL
    Definition: def.h:248
    #define SCIP_MAXSTRLEN
    Definition: def.h:269
    #define ABS(x)
    Definition: def.h:216
    #define TRUE
    Definition: def.h:93
    #define FALSE
    Definition: def.h:94
    #define MAX(x, y)
    Definition: def.h:220
    #define SCIP_CALL(x)
    Definition: def.h:355
    SCIP_FILE * SCIPfopen(const char *path, const char *mode)
    Definition: fileio.c:153
    int SCIPfeof(SCIP_FILE *stream)
    Definition: fileio.c:227
    int SCIPfclose(SCIP_FILE *fp)
    Definition: fileio.c:232
    char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
    Definition: fileio.c:200
    #define nnodes
    Definition: gastrans.c:74
    SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
    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)
    SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_prob.c:1907
    SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
    Definition: scip_prob.c:3274
    SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
    Definition: scip_cons.c:1173
    SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
    Definition: scip_var.c:1887
    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 SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
    Definition: scip_var.c:1853
    SCIP_Bool SCIPstrToIntValue(const char *str, int *value, char **endptr)
    Definition: misc.c:10924
    SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
    Definition: misc.c:10955
    Definition: pqueue.h:38
    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)
    SCIP_RETCODE SCIPcreateObjProb(SCIP *scip, const char *name, scip::ObjProbData *objprobdata, SCIP_Bool deleteobject)
    C++ wrapper classes for SCIP.
    wrapper functions to map file i/o to standard or zlib file i/o
    struct SCIP_File SCIP_FILE
    Definition: pub_fileio.h:43
    #define SCIPerrorMessage
    Definition: pub_message.h:64
    struct GraphEdge * back
    Definition: GomoryHuTree.h:70
    GRAPHNODE * adjac
    Definition: GomoryHuTree.h:72
    SCIP_VAR * var
    Definition: GomoryHuTree.h:74
    double length
    Definition: GomoryHuTree.h:67
    struct GraphEdge * next
    Definition: GomoryHuTree.h:69
    struct GraphEdge * first_edge
    Definition: GomoryHuTree.h:53
    double y
    Definition: GomoryHuTree.h:46
    double x
    Definition: GomoryHuTree.h:45
    GRAPHNODE * nodes
    Definition: GomoryHuTree.h:86
    int nnodes
    Definition: GomoryHuTree.h:82
    GRAPHEDGE * edges
    Definition: GomoryHuTree.h:87
    @ SCIP_DIDNOTRUN
    Definition: type_result.h:42
    @ SCIP_SUCCESS
    Definition: type_result.h:58
    @ SCIP_READERROR
    Definition: type_retcode.h:45
    @ SCIP_INVALIDDATA
    Definition: type_retcode.h:52
    @ SCIP_NOMEMORY
    Definition: type_retcode.h:44
    @ SCIP_OKAY
    Definition: type_retcode.h:42
    enum SCIP_Retcode SCIP_RETCODE
    Definition: type_retcode.h:63
    @ SCIP_VARTYPE_BINARY
    Definition: type_var.h:64