45 #if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER) 63 #define VERBOSE MSG_WARN 65 #define VERBOSE MSG_INFO 75 #define MAX_PATH_LEN PATH_MAX 76 #elif defined(_MAX_PATH) 77 #define MAX_PATH_LEN _MAX_PATH 78 #elif defined(_POSIX_PATH_MAX) 79 #define MAX_PATH_LEN _POSIX_PATH_MAX 81 #define MAX_PATH_LEN 1024 88 #define MAX_LINE_LEN 1024 89 #define MAX_KEYWORD_LEN 64 90 #define MAX_STRING_LEN 256 91 #define MAX_ARGUMENTS 8 100 #define KEY_SECTION 0001 104 #define KEY_COMMENT_NAME 1001 105 #define KEY_COMMENT_DATE 1002 106 #define KEY_COMMENT_CREATOR 1003 107 #define KEY_COMMENT_PROBLEM 1004 108 #define KEY_COMMENT_REMARK 1005 110 #define KEY_GRAPH_NODES 2001 111 #define KEY_GRAPH_EDGES 2002 112 #define KEY_GRAPH_E 2003 113 #define KEY_GRAPH_A 2004 114 #define KEY_GRAPH_AA 2005 115 #define KEY_GRAPH_OBSTACLES 2006 116 #define KEY_GRAPH_HOPLIMIT 2007 118 #define KEY_TERMINALS_END 3001 119 #define KEY_TERMINALS_TERMINALS 3002 120 #define KEY_TERMINALS_T 3003 121 #define KEY_TERMINALS_TP 3004 122 #define KEY_TERMINALS_ROOT 3005 123 #define KEY_TERMINALS_ROOTP 3006 124 #define KEY_TERMINALS_TG 3007 125 #define KEY_TERMINALS_GROUPS 3008 126 #define KEY_TERMINALS_TR 3009 127 #define KEY_TERMINALS_TF 3010 128 #define KEY_TERMINALS_TL 3011 129 #define KEY_TERMINALS_TB 3012 130 #define KEY_TERMINALS_RB 3013 132 #define KEY_COORDINATES_DD 4001 133 #define KEY_COORDINATES_DDD 4002 134 #define KEY_COORDINATES_DDDD 4003 135 #define KEY_COORDINATES_DDDDD 4004 136 #define KEY_COORDINATES_DDDDDD 4005 137 #define KEY_COORDINATES_DDDDDDD 4006 138 #define KEY_COORDINATES_DDDDDDDD 4007 140 #define KEY_COORDINATES_END 4011 141 #define KEY_COORDINATES_GRID 4012 143 #define KEY_SOLUTION_VALUE 4021 144 #define KEY_SOLUTION_DATE 4022 145 #define KEY_SOLUTION_TIME 4023 146 #define KEY_SOLUTION_STEINER 4024 147 #define KEY_SOLUTION_S 4025 149 #define KEY_PRESOLVE_DATE 5001 150 #define KEY_PRESOLVE_FIXED 5002 151 #define KEY_PRESOLVE_LOWER 5003 152 #define KEY_PRESOLVE_UPPER 5004 153 #define KEY_PRESOLVE_TIME 5005 154 #define KEY_PRESOLVE_EA 5006 155 #define KEY_PRESOLVE_EC 5007 156 #define KEY_PRESOLVE_ED 5008 157 #define KEY_PRESOLVE_ES 5009 160 #define KEY_NODEWEIGHTS_NW 6000 161 #define KEY_NODEWEIGHTS_END 6001 163 #define KEY_MAXDEGS_MD 8000 165 #define KEY_OBSTACLES_RR 9000 166 #define KEY_OBSTACLES_END 9001 168 #define KEY_HOPCONS_LIM 10000 169 #define KEY_HOPCONS_FACTOR 10001 171 #define KEY_TREE_S 11000 173 #define KEY_BUDGET_B 12000 185 {
"budget.end",
KEY_END, NULL },
189 {
"comment.end",
KEY_END, NULL },
208 {
"graph.end",
KEY_END, NULL },
216 {
"maximumdegrees.end",
KEY_END, NULL },
229 {
"presolve.end",
KEY_END, NULL },
233 {
"presolve.orgnodes",
KEY_EOF,
"n" },
238 {
"solution.end",
KEY_END, NULL },
269 #define FLAG_OPTIONAL 1 270 #define FLAG_REQUIRED 2 272 #define SECTION_MISSING 0 273 #define SECTION_EXISTEND 1 324 for( t = s; *s !=
'\0'; s++ )
325 *s = (
char)tolower(*s);
343 if( nterms != graph->
terms )
389 const char* intro[] = {
"Fatal Error",
"Error ",
"Warning ",
392 const char* header =
"*** %s File \"%s\" line %05d: ";
394 assert(type <
sizeof(intro) /
sizeof(
char*));
395 assert(curf !=
NULL);
397 assert(curf->
line >= 0);
400 va_start(params, msg);
404 (void)fprintf(stderr, header, intro[type], curf->
filename, curf->
line);
405 (void)vfprintf(stderr, msg, params);
406 (void)fputc(
'\n', stderr);
422 assert(elem !=
NULL);
423 assert(((
const struct key*)elem)->
keyword !=
NULL);
425 return(strcmp((
const char*)key, ((
const struct key*)elem)->
keyword));
439 assert(section !=
NULL);
440 assert(((
const struct section*)section)->name !=
NULL);
442 return(strcmp((
const char*)key, ((
const struct section*)section)->name));
458 const char* err_missmatch_v =
"Wrong Syntax";
459 const char* msg_hello_ss =
"get_arguments(\"%s\", \"%s\")";
461 int missmatch =
FALSE;
465 assert(format !=
NULL);
467 assert(para !=
NULL);
473 while((*s !=
'\0') && (*format !=
'\0') && !missmatch)
482 while((*s !=
'\0') && !isdigit(*s) && (*s !=
'.') && (*s !=
'-') )
490 assert(isdigit(*s) || (*s ==
'.') || (*s ==
'-'));
497 while(isdigit(*s) || (*s ==
'.') || (*s ==
'-'))
503 else if( decimal_spaces != -1 )
504 para->
n = para->
n + pow(10.0, (
double) -(++decimal_spaces)) * (*s -
'0');
506 para->
n = para->
n * 10 + (*s -
'0');
510 para->
n = (-1) * para->
n;
517 while((*s !=
'\0') && (*s !=
'\"'))
567 unsigned char main_file
570 const char* err_cantopen_s =
"%s.";
571 const char* err_noheader_v =
"Wrong file header.";
572 const char* err_nomagic_d =
"Wrong Magic-Number %d.";
573 const char* err_wrongtype_ss =
"Wrong file type. Found %s, expected %s.";
574 const char* msg_version_dd =
"Format Version %d.%d.";
582 assert(curf !=
NULL);
596 (void)sprintf(fillname_gr,
"%s.%s",
600 if ((curf->
fp = fopen(fillname_gr,
"r")) !=
NULL)
602 (void)sprintf(curf->
filename,
"%s", fillname_gr);
609 (void) sprintf(fillname_stp,
"%s.%s", curf->
filename,
"stp");
611 if ((curf->
fp = fopen(fillname_stp,
"r")) ==
NULL)
616 (void)sprintf(curf->
filename,
"%s", fillname_stp);
623 if (!main_file && (curf->
fp = fopen(curf->
filename,
"r")) ==
NULL)
628 else if (fscanf(curf->
fp,
"%8x %3s File, STP Format Version %2d.%2d \n",
629 &magic, type, &version_major, &version_minor) != 4)
662 const char* pathname,
663 const char* basename,
668 const char* err_missing_v =
"Section name missing";
669 const char* err_badsect_s =
"Unknown section name [%s]";
670 const char* err_required_s =
"Can't access required file [%s]";
679 assert(pathname !=
NULL);
680 assert(basename !=
NULL);
681 assert(curf !=
NULL);
682 assert(save !=
NULL);
690 if( (tokens = sscanf(s,
"%63s %63s %s", sectname, dummy, inclname)) < 1 )
696 if( strcmp(
strlower(sectname),
"comments") == 0 )
710 if( tokens == 1 || (tokens == 2 && strcmp(
strlower(sectname),
"tree") == 0) )
718 (void)sprintf(temp.
filename,
"%s%s%c%s",
720 (*inclname ==
'\0') ? basename : inclname,
723 #if defined(_MSC_VER) 737 temp.
section = §ion_table[0];
763 double*** coordinates,
772 if( *coordinates ==
NULL )
775 assert(termcount !=
NULL);
776 assert(grid_dim !=
NULL);
777 assert(*termcount == 0);
785 for( i = 0; i < dim; i++ )
789 for( i = 0; i < dim; i++ )
790 (*coordinates)[i][*termcount] = (double)para[i + 1].n;
809 length = (int) strlen(str_number);
813 for( i = 0; i < length; i++ )
815 if( str_number[length - i - 1] !=
'0' )
820 for( i = 0; i < length; i++ )
827 order = length - ints - trail_zeroes - 1;
836 double** coordinates,
837 int*** scaled_coords,
849 assert(coordinates !=
NULL);
851 assert(grid_dim > 1);
855 for( i = 0; i < grid_dim; i++ )
856 for( j = 0; j <
nnodes; j++ )
860 if( max_order < tmp )
866 *scale_order = max_order;
867 scale_factor = (int) pow(10.0, (
double) max_order);
869 for( i = 0; i < grid_dim; i++ )
872 for( j = 0; j <
nnodes; j++ )
874 (*scaled_coords)[i][j] = (int) (coordinates[i][j] * scale_factor);
892 const char* err_unknown_s =
"Unknown keyword [%s]";
893 const char* err_include_v =
"Include in included file";
894 const char* err_missing_s =
"Required section %s missing";
895 const char* msg_newsect_s =
"Processing Section %s";
896 const char* msg_keyword_sd =
"Found Keyword \"%s\", code = %d";
897 const char* err_badedge_ddd =
"Bad edge %d-%d (%d nodes)";
898 const char* err_badroot_dd =
"Bad root %d (%d nodes)";
899 const char* err_baddeg_dd =
"More degree constraints (%d) than nodes (%d)";
901 const char* msg_finish_dddd =
"Nodes: %d Edges: %d Terminals: %d Source=%d\n";
904 const char* endofline =
"#;\n\r";
905 const char* separator =
" \t:=";
918 int stop_input =
FALSE;
923 double** coordinates =
NULL;
940 int obstacle_counter = 0;
941 int** scaled_coordinates =
NULL;
942 int** obstacle_coords =
NULL;
949 printf(
"input checker is active \n\n");
952 assert(file != NULL);
956 for( i = 1; i < (int)(
sizeof(section_table) /
sizeof(section_table[0])); i++ )
961 (void)strcpy(pathname, file);
965 if( (s = strrchr(pathname,
DIRSEP[0])) == NULL )
969 (void)strcpy(basename, pathname);
977 (void)strcpy(basename, s);
983 if ((s = strrchr(basename,
EXTSEP)) != NULL)
988 curf.
section = §ion_table[0];
999 while((curf.
fp != NULL) && !stop_input)
1003 if ((s = fgets(buffer, (
int)
sizeof(buffer), curf.
fp)) == NULL)
1007 (void)fclose(curf.
fp);
1032 if ((t = strpbrk(s, endofline)) != NULL)
1044 i = (int)strlen(keyword);
1050 keyword[i] = (
char)tolower(*s);
1056 while((*s !=
'\0') && (strchr(separator, *s) != NULL))
1059 if( strcmp(keyword,
"comments") == 0 )
1060 keyword[i - 1] =
'\0';
1064 p = (
struct key*)bsearch(keyword, keyword_table,
1065 sizeof(keyword_table) /
sizeof(
struct key),
1066 sizeof(struct key), key_cmp);
1072 char newformat[5] =
"";
1080 strcpy(newformat,
"nn");
1082 strcpy(newformat,
"nnnn");
1084 if( p->
format == NULL || !
get_arguments(&curf, (
const char*)( newformat[0] !=
'\0' ? newformat : p->
format ), s, para) )
1093 if (save.
fp == NULL)
1105 curf.
section = §ion_table[0];
1117 for(i = 0; (unsigned)i <
sizeof(section_table) /
sizeof(
struct section); i++)
1132 (void)printf(
"Problem: [%s]\n", para[0].s);
1134 if( strcmp(para[0].s,
"SPG") == 0 )
1136 else if( strcmp(para[0].s,
"PCSPG") == 0
1137 || strcmp(para[0].s,
"Prize-Collecting Steiner Problem in Graphs") == 0 )
1139 else if( strcmp(para[0].s,
"RPCST") == 0
1140 || strcmp(para[0].s,
"Rooted Prize-Collecting Steiner Problem in Graphs") == 0 )
1142 else if( strcmp(para[0].s,
"NWSPG") == 0 )
1144 else if( strcmp(para[0].s,
"DCST") == 0 )
1146 else if( strcmp(para[0].s,
"RSMT") == 0 )
1148 else if( strcmp(para[0].s,
"OARSMT") == 0 )
1150 else if( strcmp(para[0].s,
"Maximum Node Weight Connected Subgraph") == 0
1151 || strcmp(para[0].s,
"MWCS") == 0 )
1153 else if( strcmp(para[0].s,
"Rooted Maximum Node Weight Connected Subgraph") == 0
1154 || strcmp(para[0].s,
"RMWCS") == 0 )
1156 else if( strcmp(para[0].s,
"HCDST") == 0 )
1158 else if( strcmp(para[0].s,
"SAP") == 0 )
1160 else if( strcmp(para[0].s,
"GSTP") == 0 )
1165 (void)printf(
"Comment: [%s]\n", para[0].s);
1167 if( strcmp(para[0].s,
"Transformed") == 0 )
1171 assert(para != NULL);
1172 nodes = (int)para[0].n;
1175 nobstacles = (int)para[0].n;
1176 if( nobstacles > 0 )
1180 hoplimit = (int)para[0].n;
1184 edges = (int)para[0].n;
1189 if( (
int)para[0].
n > nodes || (int)para[1].n > nodes )
1192 (
int)para[0].n, (
int)para[1].n, nodes);
1207 for( i = 0; i < nodes; i++ )
1221 if( edgecount > edges )
1230 tail = (int)para[0].n - 1;
1231 head = (int)para[1].n - 1;
1234 if( g->
tail[i] == tail )
1239 g->
cost[i] = (double)para[2].n;
1242 else if( stp_type ==
STP_SAP )
1244 graph_edge_add(scip, g, (
int)para[0].n - 1, (
int)para[1].n - 1, (
double)para[2].n, (
double)para[3].n);
1248 graph_edge_add(scip, g, (
int)para[0].n - 1, (
int)para[1].n - 1, 0.0, 0.0);
1256 : (
double)para[3].
n);
1261 assert((
int)para[0].n >= 0);
1263 if( degcount < nodes )
1270 g->
maxdeg[degcount++] = (int)para[0].n;
1281 assert(para[0].n >= 0.0);
1286 nodeweight = (double) para[0].n;
1288 assert(presol != NULL);
1293 if( g->
prize == NULL )
1296 assert(nwcount < nodes);
1297 g->
prize[nwcount++] = nodeweight;
1301 curf.
section = §ion_table[0];
1303 assert(nwcount == nodes);
1311 assert(nobstacles > 0);
1312 if( obstacle_coords == NULL )
1314 assert(obstacle_counter == 0);
1316 for( i = 0; i < 4; i++ )
1319 for( i = 0; i < 4; i++ )
1320 obstacle_coords[i][obstacle_counter] = (
int)para[i].
n;
1324 curf.
section = §ion_table[0];
1326 if( obstacle_counter != nobstacles )
1328 message(
MSG_FATAL, &curf,
"obstacle number does not match coordinates \n");
1332 if( scaled_coordinates == NULL )
1341 message(
MSG_FATAL, &curf,
"Obstacle avoiding RSMT problems are currently not supported in this format \n");
1345 if( obstacle_coords != NULL )
1346 for( i = 3; i >= 0; i-- )
1351 if( transformed == 0 )
1355 assert(nodes == termcount);
1360 assert(nodes == termcount);
1365 assert(nodes == termcount);
1381 #ifdef STP_RPC_FIXEDPROPER 1388 curf.
section = §ion_table[0];
1391 terms = (int)para[0].n;
1396 assert(terms == nodes);
1399 if( g->
prize == NULL )
1405 tgroups = (int)para[0].n;
1406 for( i = 0; i < tgroups; i++ )
1414 if ((
int)para[0].n <= nodes)
1416 g->
source = (int)para[0].n - 1;
1422 (
int)para[0].n, nodes);
1430 g->
source = (int)para[0].n - 1;
1434 if( g->
prize == NULL )
1443 assert(g->
prize != NULL);
1444 g->
prize[(int)para[0].n - 1] = (
double)para[1].
n;
1445 if(
SCIPisGT(scip, (
double)para[1].n, 0.0) )
1446 presol->
fixed -= (
double)para[1].
n;
1455 if( g->
prize == NULL )
1469 assert(tgroups > 0);
1474 vertex = (int)para[0].n - 1;
1476 assert(vertex >= 0);
1488 if( g->
prize == NULL )
1494 g->
prize[(int)para[0].n - 1] = (
double)para[1].
n;
1500 assert(g->
prize != NULL);
1502 presol->
fixed -= (double)para[1].n;
1509 assert(g->
prize != NULL);
1512 assert(terms == nodes );
1516 g->
costbudget[(int)para[0].n - 1] = (
double)para[2].
n;
1517 g->
prize[(int)para[0].n - 1] = (
double)para[1].
n;
1519 if(
SCIPisGT(scip, (
double)para[1].
n, 0.0) )
1520 presol->
fixed -= (
double)para[1].
n;
1526 assert(g->
prize != NULL);
1529 assert(terms == nodes );
1532 assert((
double)para[2].n == 0.0);
1536 presol->
fixed -= (double)para[1].n;
1570 assert(grid_dim > 1);
1572 curf.
section = §ion_table[0];
1573 if( termcount != nodes )
1583 if( coordinates != NULL )
1584 for( i = 0; i < grid_dim; i++ )
1600 presol->
fixed += (double)para[0].n;
1603 (void)printf(
"Found presolve information %s\n",
1608 presol->
lower = (double)para[0].n;
1612 presol->
upper = (double)para[0].n;
1616 presol->
time = (int)para[0].n;
1638 if( save.
fp != NULL )
1639 (void)fclose(save.
fp);
1644 if( curf.
fp != NULL )
1645 (void)fclose(curf.
fp);
1655 const int*
const grad = g->
grad;
1656 for( i = 0; i <
nnodes; i++ )
1677 (void)printf(msg_finish_dddd,
1692 if( obstacle_coords != NULL )
1694 for( i = 0; i < 4; i++ )
void graph_knot_chg(GRAPH *, int, int)
static volatile int nterms
#define KEY_COORDINATES_DDDDDDDD
#define SCIPfreeMemoryArrayNull(scip, ptr)
#define KEY_SOLUTION_TIME
SCIP_Bool graph_valid(SCIP *, const GRAPH *)
#define KEY_COORDINATES_DDDD
#define SCIPallocMemoryArray(scip, ptr, num)
#define KEY_COORDINATES_END
#define KEY_SOLUTION_STEINER
static int start_section(const char *pathname, const char *basename, CURF *curf, CURF *save, const char *s)
#define KEY_COMMENT_CREATOR
int SCIPsnprintf(char *t, int len, const char *s,...)
enum SCIP_Retcode SCIP_RETCODE
includes various files containing graph methods used for Steiner tree problems
static int get_scale_order(SCIP_Real number)
#define KEY_NODEWEIGHTS_END
char filename[MAX_PATH_LEN]
#define STP_FILE_VERSION_MAJOR
SCIP_RETCODE graph_obstgrid_create(SCIP *, GRAPH **, int **, int **, int, int, int, int)
SCIP_Bool graph_validInput(SCIP *, const GRAPH *)
#define KEY_PRESOLVE_LOWER
SCIP_RETCODE graph_pc_initPrizes(SCIP *, GRAPH *, int)
#define KEY_COMMENT_REMARK
#define KEY_PRESOLVE_FIXED
static SCIP_RETCODE init_coordinates(SCIP *scip, GRAPH *g, PARA *para, double ***coordinates, int *grid_dim, int *termcount, int dim, int nodes)
#define KEY_TERMINALS_TERMINALS
#define KEY_GRAPH_OBSTACLES
SCIP_RETCODE graph_transMw(SCIP *, GRAPH *)
SCIP_RETCODE graph_transPc(SCIP *, GRAPH *)
#define KEY_TERMINALS_END
SCIP_RETCODE graph_transNw(SCIP *, PRESOL *, GRAPH *)
#define SCIPfreeBufferArrayNull(scip, ptr)
#define KEY_COORDINATES_GRID
#define KEY_NODEWEIGHTS_NW
void graph_edge_add(SCIP *, GRAPH *, int, int, double, double)
void graph_knot_add(GRAPH *, int)
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
SCIP_RETCODE reduce_unconnectedInfeas(SCIP *, SCIP_Bool, GRAPH *, SCIP_Bool *)
SCIP_RETCODE graph_transPc2Spg(SCIP *, PRESOL *, GRAPH *)
#define KEY_TERMINALS_ROOT
#define KEY_COORDINATES_DDDDDDD
#define SCIPallocBufferArray(scip, ptr, num)
SCIP_Bool graph_hasMultiEdges(SCIP *, const GRAPH *, SCIP_Bool)
#define KEY_COORDINATES_DDD
static const struct key keyword_table[]
static int get_arguments(const CURF *curf, const char *format, const char *s, PARA *para)
static int open_file(CURF *curf, unsigned char main_file)
static int sec_cmp(const void *key, const void *section)
SCIP_RETCODE graph_grid_create(SCIP *, GRAPH **, int **, int, int, int)
static char * strlower(char *s)
SCIP_RETCODE graph_transRpc(SCIP *, GRAPH *)
SCIP_RETCODE graph_load(SCIP *scip, GRAPH **graph, const char *file, PRESOL *presol)
#define KEY_TERMINALS_GROUPS
#define KEY_PRESOLVE_DATE
SCIP_RETCODE graph_transRpc2FixedProper(SCIP *, PRESOL *, GRAPH *)
#define KEY_OBSTACLES_END
#define KEY_SOLUTION_VALUE
#define KEY_COORDINATES_DD
#define KEY_PRESOLVE_UPPER
#define KEY_PRESOLVE_TIME
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static int key_cmp(const void *key, const void *elem)
static SCIP_RETCODE scale_coords(double **coordinates, int ***scaled_coords, int *scale_order, int nnodes, int grid_dim)
#define KEY_COMMENT_PROBLEM
#define KEY_SOLUTION_DATE
static struct section section_table[]
#define KEY_HOPCONS_FACTOR
static void message(unsigned int type, const CURF *curf, const char *msg,...)
int graph_get_nNodes(const GRAPH *)
static SCIP_RETCODE check_inputgraph(SCIP *scip, int nterms, GRAPH *graph)
#define KEY_COORDINATES_DDDDDD
SCIP_RETCODE graph_init(SCIP *, GRAPH **, int, int, int)
void graph_transGstpClean(PRESOL *, GRAPH *)
SCIP_Bool graph_typeIsSpgLike(const GRAPH *)
SCIP_RETCODE graph_transRmw(SCIP *, GRAPH *)
includes various reduction methods for Steiner tree problems
#define KEY_TERMINALS_ROOTP
#define KEY_COORDINATES_DDDDD
#define KEY_GRAPH_HOPLIMIT
#define STP_FILE_VERSION_MINOR