Refactoring

master
Alinson S. Xavier 11 years ago
parent f2b788665f
commit e2c6dafb33

@ -2,7 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include "lp.h" #include "lp.h"
#include "branch_and_cut.h" #include "branch-and-cut.h"
#include "util.h" #include "util.h"
#include "gtsp.h" #include "gtsp.h"
@ -58,8 +58,11 @@ int BNC_init_lp(struct BNC *bnc)
rval = bnc->problem_init_lp(bnc->lp, bnc->problem_data); rval = bnc->problem_init_lp(bnc->lp, bnc->problem_data);
abort_if(rval, "problem_init_lp failed"); abort_if(rval, "problem_init_lp failed");
rval = LP_write(bnc->lp, "subtour.lp"); if(strlen(LP_FILENAME) > 0)
abort_if(rval, "LP_write failed"); {
rval = LP_write(bnc->lp, LP_FILENAME);
abort_if(rval, "LP_write failed");
}
CLEANUP: CLEANUP:
return rval; return rval;

@ -78,8 +78,6 @@ int graph_build(
int b = edges[2 * i + 1]; int b = edges[2 * i + 1];
n = &graph->nodes[a]; n = &graph->nodes[a];
n->adj[n->degree].neighbor_index = b;
n->adj[n->degree].edge_index = i;
n->adj[n->degree].neighbor = &graph->nodes[b]; n->adj[n->degree].neighbor = &graph->nodes[b];
n->adj[n->degree].edge = &graph->edges[i]; n->adj[n->degree].edge = &graph->edges[i];
n->degree++; n->degree++;
@ -87,8 +85,6 @@ int graph_build(
if (!is_directed) if (!is_directed)
{ {
n = &graph->nodes[b]; n = &graph->nodes[b];
n->adj[n->degree].neighbor_index = a;
n->adj[n->degree].edge_index = i;
n->adj[n->degree].neighbor = &graph->nodes[a]; n->adj[n->degree].neighbor = &graph->nodes[a];
n->adj[n->degree].edge = &graph->edges[i]; n->adj[n->degree].edge = &graph->edges[i];
n->degree++; n->degree++;

@ -5,9 +5,6 @@
struct Adjacency struct Adjacency
{ {
int edge_index;
int neighbor_index;
struct Edge *edge; struct Edge *edge;
struct Node *neighbor; struct Node *neighbor;
}; };

@ -67,7 +67,7 @@ static int add_comb_cut(
nz++; nz++;
} }
#if LOG_LEVEL >= LOG_LEVEL_DEBUG #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
log_verbose("Generated cut:\n"); log_verbose("Generated cut:\n");
if (OPTIMAL_X) if (OPTIMAL_X)
{ {
@ -341,49 +341,6 @@ static int shrink_clusters(
return rval; return rval;
} }
static int write_shrunken_graph(
double *shrunken_x,
struct Graph *shrunken_graph,
int const cluster_count)
{
int rval = 0;
FILE *file = 0;
file = fopen("gtsp-shrunken.in", "w");
abort_if(!file, "could not open file");
fprintf(file, "%d %d\n", (*shrunken_graph).node_count, cluster_count);
for (int i = 0; i < (*shrunken_graph).node_count; i++)
fprintf(file, "%.2lf %.2lf %d\n", (*shrunken_graph).x_coordinates[i],
(*shrunken_graph).y_coordinates[i], i);
fclose(file);
file = fopen("gtsp-shrunken.out", "w");
abort_if(!file, "could not open file");
int positive_edge_count = 0;
for (int i = 0; i < (*shrunken_graph).edge_count; i++)
if (shrunken_x[i] > EPSILON)
positive_edge_count++;
fprintf(file, "%d %d\n", (*shrunken_graph).node_count,
(*shrunken_graph).edge_count);
fprintf(file, "%d\n", positive_edge_count);
for (int i = 0; i < (*shrunken_graph).edge_count; i++)
if (shrunken_x[i] > EPSILON)
fprintf(file, "%d %d %.4lf\n",
(*shrunken_graph).edges[i].from->index,
(*shrunken_graph).edges[i].to->index, shrunken_x[i]);
fclose(file);
CLEANUP:
return rval;
}
int GTSP_find_comb_cuts(struct LP *lp, struct GTSP *data) int GTSP_find_comb_cuts(struct LP *lp, struct GTSP *data)
{ {
int rval = 0; int rval = 0;
@ -415,13 +372,6 @@ int GTSP_find_comb_cuts(struct LP *lp, struct GTSP *data)
rval = shrink_clusters(data, x, &shrunken_graph, shrunken_x); rval = shrink_clusters(data, x, &shrunken_graph, shrunken_x);
abort_if(rval, "shrink_clusters failed"); abort_if(rval, "shrink_clusters failed");
#if LOG_LEVEL >= LOG_LEVEL_DEBUG
rval = write_shrunken_graph(shrunken_x, &shrunken_graph, cluster_count);
abort_if(rval, "write_shrunken_graph failed");
#else
UNUSED(write_shrunken_graph);
#endif
teeth = (int *) malloc(cluster_count * sizeof(int)); teeth = (int *) malloc(cluster_count * sizeof(int));
components = (int *) malloc(cluster_count * sizeof(int)); components = (int *) malloc(cluster_count * sizeof(int));
component_sizes = (int *) malloc(cluster_count * sizeof(int)); component_sizes = (int *) malloc(cluster_count * sizeof(int));

@ -187,8 +187,11 @@ int GTSP_find_exact_subtour_cuts(struct LP *lp, struct GTSP *data)
abort_if(rval, "LP_get_x failed"); abort_if(rval, "LP_get_x failed");
#if LOG_LEVEL >= LOG_LEVEL_DEBUG #if LOG_LEVEL >= LOG_LEVEL_DEBUG
rval = GTSP_write_solution(data, "gtsp-frac.out", x); if(strlen(FRAC_SOLUTION_FILENAME) > 0)
abort_if(rval, "GTSP_write_solution failed"); {
rval = GTSP_write_solution(data, FRAC_SOLUTION_FILENAME, x);
abort_if(rval, "GTSP_write_solution failed");
}
#endif #endif
struct Graph digraph; struct Graph digraph;

@ -8,9 +8,7 @@
#include "gtsp-comb.h" #include "gtsp-comb.h"
int large_neighborhood_search( int large_neighborhood_search(
struct Tour *tour, struct Tour *tour, struct GTSP *data, int *tour_cost);
struct GTSP *data,
int *tour_cost);
int build_edge_map(struct GTSP *gtsp, int *edge_map); int build_edge_map(struct GTSP *gtsp, int *edge_map);
@ -274,7 +272,8 @@ int GTSP_write_problem(struct GTSP *data, char *filename)
const struct Graph *graph = data->graph; const struct Graph *graph = data->graph;
fprintf(file, "%d %d\n", graph->node_count, data->cluster_count); fprintf(file, "%d %d %d\n", graph->node_count, data->cluster_count,
graph->edge_count);
for (int i = 0; i < graph->node_count; i++) for (int i = 0; i < graph->node_count; i++)
{ {
@ -287,15 +286,28 @@ int GTSP_write_problem(struct GTSP *data, char *filename)
return rval; return rval;
} }
int GTSP_print_solution(struct GTSP *data, double *x)
{
struct Edge *edges = data->graph->edges;
int edge_count = data->graph->edge_count;
for (int i = 0; i < edge_count; i++)
if (x[i] > EPSILON)
log_info(" %-3d %-3d %8.4lf\n", edges[i].from->index,
edges[i].to->index, x[i]);
return 0;
}
int GTSP_write_solution(struct GTSP *data, char *filename, double *x) int GTSP_write_solution(struct GTSP *data, char *filename, double *x)
{ {
int rval = 0; int rval = 0;
struct Edge *edges = data->graph->edges; struct Edge *edges = data->graph->edges;
int node_count = data->graph->node_count;
int edge_count = data->graph->edge_count; int edge_count = data->graph->edge_count;
FILE *file; FILE *file;
file = fopen(filename, "w"); file = fopen(filename, "w");
abort_if(!file, "could not open file"); abort_if(!file, "could not open file");
@ -304,8 +316,6 @@ int GTSP_write_solution(struct GTSP *data, char *filename, double *x)
if (x[i] > EPSILON) if (x[i] > EPSILON)
positive_edge_count++; positive_edge_count++;
fprintf(file, "%d %d\n", node_count, edge_count);
fprintf(file, "%d\n", positive_edge_count); fprintf(file, "%d\n", positive_edge_count);
for (int i = 0; i < edge_count; i++) for (int i = 0; i < edge_count; i++)
@ -478,18 +488,17 @@ int GTSP_solution_found(struct BNC *bnc, struct GTSP *data, double *x)
int rval = 0; int rval = 0;
int tour_cost; int tour_cost;
char filename[100];
double *best_val = &bnc->best_obj_val; double *best_val = &bnc->best_obj_val;
struct Tour *tour; struct Tour *tour;
tour = (struct Tour *) malloc(data->cluster_count * sizeof(struct Tour)); tour = (struct Tour *) malloc(data->cluster_count * sizeof(struct Tour));
sprintf(filename, "tmp/gtsp-m%d-n%d-s%d.out", data->cluster_count, if (strlen(SOLUTION_FILENAME) > 0)
data->graph->node_count, SEED); {
log_info("Writing solution to file %s\n", SOLUTION_FILENAME);
log_info("Writting solution to file %s\n", filename); rval = GTSP_write_solution(data, SOLUTION_FILENAME, x);
rval = GTSP_write_solution(data, filename, x); abort_if(rval, "GTSP_write_solution failed");
abort_if(rval, "GTSP_write_solution failed"); }
rval = build_tour_from_x(data, tour, x); rval = build_tour_from_x(data, tour, x);
abort_if(rval, "build_tour_from_x failed"); abort_if(rval, "build_tour_from_x failed");
@ -747,9 +756,7 @@ int two_opt(struct Tour *tour, struct GTSP *data)
} }
int large_neighborhood_search( int large_neighborhood_search(
struct Tour *tour, struct Tour *tour, struct GTSP *data, int *tour_cost)
struct GTSP *data,
int *tour_cost)
{ {
int rval = 0; int rval = 0;

@ -3,7 +3,7 @@
#include "lp.h" #include "lp.h"
#include "graph.h" #include "graph.h"
#include "branch_and_cut.h" #include "branch-and-cut.h"
struct Tour struct Tour
{ {
@ -60,6 +60,10 @@ int list_length(struct Tour * tour, struct GTSP* data);
void print_list(struct Tour * tour, struct GTSP* data); void print_list(struct Tour * tour, struct GTSP* data);
int GTSP_print_solution(struct GTSP *data, double *x);
int build_tour_from_x(struct GTSP *data, struct Tour *tour, double *x); int build_tour_from_x(struct GTSP *data, struct Tour *tour, double *x);
int GTSP_solution_found(struct BNC *bnc, struct GTSP *data, double *x); int GTSP_solution_found(struct BNC *bnc, struct GTSP *data, double *x);

@ -384,11 +384,16 @@ int LP_get_num_cols(struct LP *lp)
int LP_write(struct LP *lp, const char *fname) int LP_write(struct LP *lp, const char *fname)
{ {
int rval = 0; int rval = 0;
char nambuf[MAX_NAME_LENGTH]; char nambuf[MAX_NAME_LENGTH];
FILE *f = fopen(fname, "w");
abort_iff(!f, "could not open file %s", fname);
fclose(f);
strncpy(nambuf, fname, MAX_NAME_LENGTH); strncpy(nambuf, fname, MAX_NAME_LENGTH);
nambuf[MAX_NAME_LENGTH - 1] = '\0'; nambuf[MAX_NAME_LENGTH - 1] = '\0';
log_info("Writing LP to file %s...\n", fname);
rval = CPXwriteprob(lp->cplex_env, lp->cplex_lp, nambuf, "RLP"); rval = CPXwriteprob(lp->cplex_env, lp->cplex_lp, nambuf, "RLP");
abort_if(rval, "CPXwriteprob failed"); abort_if(rval, "CPXwriteprob failed");

@ -30,6 +30,12 @@ double INITIAL_TIME = 0;
int BNC_NODE_COUNT = 0; int BNC_NODE_COUNT = 0;
char LP_FILENAME[100] = {0};
char SOLUTION_FILENAME[100] = {0};
char FRAC_SOLUTION_FILENAME[100] = {0};
char WRITE_GRAPH_FILENAME[100] = {0};
char STATS_FILENAME[100] = {0};
static int input_node_count = -1; static int input_node_count = -1;
static int input_cluster_count = -1; static int input_cluster_count = -1;
static int grid_size = 100; static int grid_size = 100;
@ -39,24 +45,36 @@ static const struct option options_tab[] = {{"help", no_argument, 0, 'h'},
{"clusters", required_argument, 0, 'm'}, {"clusters", required_argument, 0, 'm'},
{"grid-size", required_argument, 0, 'g'}, {"grid-size", required_argument, 0, 'g'},
{"optimal", required_argument, 0, 'x'}, {"optimal", required_argument, 0, 'x'},
{"seed", required_argument, 0, 's'}, {"seed", required_argument, 0, 's'}, {"out", required_argument, 0, 'o'},
{"stats", required_argument, 0, 't'}, {"lp", required_argument, 0, 'l'},
{"write-graph", required_argument, 0, 'w'},
{(char *) 0, (int) 0, (int *) 0, (int) 0}}; {(char *) 0, (int) 0, (int *) 0, (int) 0}};
static char input_x_filename[1000] = {0}; static char input_x_filename[1000] = {0};
static void print_usage(int argc, char **argv) static void print_usage(char **argv)
{ {
printf("Usage: %s [OPTION]...\n", argv[0]); printf("Usage: %s [OPTION]...\n", argv[0]);
printf("Solves the Generalized Traveling Salesman problem for the input graph.\n\n"); printf("Solves the Generalized Traveling Salesman problem for the input graph.\n\n");
printf("Parameters:\n"); printf("Parameters:\n");
printf("%4s %-13s %s\n", "-n", "--nodes", "number of nodes"); printf("%4s %-20s %s\n", "-n", "--nodes=NUM", "number of nodes");
printf("%4s %-13s %s\n", "-m", "--clusters", "number of clusters"); printf("%4s %-20s %s\n", "-m", "--clusters=NUM", "number of clusters");
printf("%4s %-13s %s\n", "-s", "--seed", "random seed"); printf("%4s %-20s %s\n", "-s", "--seed=NUM", "random seed");
printf("%4s %-13s %s\n", "-g", "--grid-size", printf("%4s %-20s %s\n", "-g", "--grid-size=NUM",
"size of the box used for generating random points"); "size of the box used for generating random points");
printf("%4s %-13s %s\n", "-x", "--optimal", printf("%4s %-20s %s\n", "-x", "--optimal=FILE",
"file containg valid solution (used to assert validity of cuts)"); "file containg optimal solution (used to assert validity of cuts)");
printf("%4s %-20s %s\n", "-o", "--out=FILE",
"write optimal solution to this file");
printf("%4s %-20s %s\n", "-f", "--frac=FILE",
"write current fractional solution to this file");
printf("%4s %-20s %s\n", "-l", "--lp=FILE",
"write initial LP to this file");
printf("%4s %-20s %s\n", "-w", "--write-graph=FILE",
"write the randomly generated input graph to this file");
printf("%4s %-20s %s\n", "-t", "--stats=FILE",
"write statistics to this file (append if file exists)");
} }
static int parse_args(int argc, char **argv) static int parse_args(int argc, char **argv)
@ -69,7 +87,8 @@ static int parse_args(int argc, char **argv)
{ {
int c = 0; int c = 0;
int option_index = 0; int option_index = 0;
c = getopt_long(argc, argv, "n:m:g:x:s:h:", options_tab, &option_index); c = getopt_long(argc, argv, "n:m:g:x:s:h:o:t:l:w:", options_tab,
&option_index);
if (c < 0) break; if (c < 0) break;
@ -91,12 +110,28 @@ static int parse_args(int argc, char **argv)
strcpy(input_x_filename, optarg); strcpy(input_x_filename, optarg);
break; break;
case 'o':
strcpy(SOLUTION_FILENAME, optarg);
break;
case 's': case 's':
SEED = (unsigned) atoi(optarg); SEED = (unsigned) atoi(optarg);
break; break;
case 't':
strcpy(STATS_FILENAME, optarg);
break;
case 'l':
strcpy(LP_FILENAME, optarg);
break;
case 'w':
strcpy(WRITE_GRAPH_FILENAME, optarg);
break;
case 'h': case 'h':
print_usage(argc, argv); print_usage(argv);
exit(0); exit(0);
case ':': case ':':
@ -175,16 +210,12 @@ int main(int argc, char **argv)
grid_size, &data); grid_size, &data);
abort_if(rval, "GTSP_create_random_problem failed"); abort_if(rval, "GTSP_create_random_problem failed");
char filename[100]; if (strlen(WRITE_GRAPH_FILENAME) > 0)
sprintf(filename, "input/%s.in", instance_name); {
log_info("Writing random instance to file %s\n", filename); log_info("Writing random instance to file %s\n", WRITE_GRAPH_FILENAME);
rval = GTSP_write_problem(&data, filename); rval = GTSP_write_problem(&data, WRITE_GRAPH_FILENAME);
abort_if(rval, "GTSP_write_problem failed"); abort_if(rval, "GTSP_write_problem failed");
}
#if LOG_LEVEL >= LOG_LEVEL_DEBUG
log_info("Writing random instance to file gtsp.in\n");
rval = GTSP_write_problem(&data, "gtsp.in");
#endif
int init_val = 0; int init_val = 0;
@ -212,7 +243,6 @@ int main(int argc, char **argv)
if (strlen(input_x_filename) == 0) if (strlen(input_x_filename) == 0)
{ {
sprintf(input_x_filename, "optimal/%s.out", instance_name); sprintf(input_x_filename, "optimal/%s.out", instance_name);
FILE *file = fopen(input_x_filename, "r"); FILE *file = fopen(input_x_filename, "r");
if (!file) if (!file)
@ -241,19 +271,12 @@ int main(int argc, char **argv)
rval = BNC_init_lp(&bnc); rval = BNC_init_lp(&bnc);
abort_if(rval, "BNC_init_lp failed"); abort_if(rval, "BNC_init_lp failed");
// log_info("Writing LP to file gtsp.lp...\n");
// rval = LP_write(bnc.lp, "gtsp.lp");
// abort_if(rval, "LP_write failed");
log_info("Starting branch-and-cut solver...\n"); log_info("Starting branch-and-cut solver...\n");
rval = BNC_solve(&bnc); rval = BNC_solve(&bnc);
abort_if(rval, "BNC_solve_node failed"); abort_if(rval, "BNC_solve_node failed");
abort_if(!bnc.best_x, "problem has no feasible solution"); abort_if(!bnc.best_x, "problem has no feasible solution");
log_info("Optimal integral solution:\n");
log_info(" obj value = %.2lf **\n", bnc.best_obj_val);
if (OPTIMAL_X) if (OPTIMAL_X)
{ {
abort_iff(bnc.best_obj_val - EPSILON > opt_val, abort_iff(bnc.best_obj_val - EPSILON > opt_val,
@ -263,60 +286,69 @@ int main(int argc, char **argv)
TOTAL_TIME = get_user_time() - initial_time; TOTAL_TIME = get_user_time() - initial_time;
log_info("Branch-and-bound nodes: %d\n", BNC_NODE_COUNT); if (strlen(STATS_FILENAME) > 0)
log_info("LP optimize calls: %d\n", LP_SOLVE_COUNT); {
log_info("LP solving time: %.2lf\n", LP_SOLVE_TIME); log_info("Writing statistics to file %s...\n", STATS_FILENAME);
log_info("LP cut pool management time: %.2lf\n", CUT_POOL_TIME); FILE *file = fopen(STATS_FILENAME, "a");
abort_if(!file, "could not open stats.tab");
// Write statistics to a file
FILE *file = fopen("stats.tab", "a");
abort_if(!file, "could not open stats.tab");
struct stat st; struct stat st;
stat("stats.tab", &st); stat(STATS_FILENAME, &st);
if (st.st_size == 0) if (st.st_size == 0)
{ {
fprintf(file, "%-20s ", "instance"); fprintf(file, "%-20s ", "instance");
fprintf(file, "%-8s ", "time"); fprintf(file, "%-8s ", "time");
fprintf(file, "%-8s ", "subt-t"); fprintf(file, "%-8s ", "subt-t");
fprintf(file, "%-8s ", "combs-t"); fprintf(file, "%-8s ", "combs-t");
fprintf(file, "%-8s ", "pool-t"); fprintf(file, "%-8s ", "pool-t");
fprintf(file, "%-8s ", "pool-m"); fprintf(file, "%-8s ", "pool-m");
fprintf(file, "%-8s ", "lp-count"); fprintf(file, "%-8s ", "lp-count");
fprintf(file, "%-8s ", "lp-time"); fprintf(file, "%-8s ", "lp-time");
fprintf(file, "%-8s ", "lp-rows"); fprintf(file, "%-8s ", "lp-rows");
fprintf(file, "%-8s ", "lp-cols"); fprintf(file, "%-8s ", "lp-cols");
fprintf(file, "%-8s ", "init-v"); fprintf(file, "%-8s ", "init-v");
fprintf(file, "%-8s ", "opt-v"); fprintf(file, "%-8s ", "opt-v");
fprintf(file, "%-8s ", "root-v"); fprintf(file, "%-8s ", "root-v");
fprintf(file, "%-8s ", "nodes"); fprintf(file, "%-8s ", "nodes");
fprintf(file, "%-8s ", "subt-cc"); fprintf(file, "%-8s ", "subt-cc");
fprintf(file, "%-8s ", "subt-nc"); fprintf(file, "%-8s ", "subt-nc");
fprintf(file, "%-8s ", "subt-nn"); fprintf(file, "%-8s ", "subt-nn");
fprintf(file, "%-8s ", "combs"); fprintf(file, "%-8s ", "combs");
fprintf(file, "\n");
}
fprintf(file, "%-20s ", instance_name);
fprintf(file, "%-8.2lf ", TOTAL_TIME);
fprintf(file, "%-8.2lf ", SUBTOUR_TIME);
fprintf(file, "%-8.2lf ", COMBS_TIME);
fprintf(file, "%-8.2lf ", CUT_POOL_TIME);
fprintf(file, "%-8ld ", CUT_POOL_MAX_MEMORY / 1024 / 1024);
fprintf(file, "%-8d ", LP_SOLVE_COUNT);
fprintf(file, "%-8.2lf ", LP_SOLVE_TIME);
fprintf(file, "%-8d ", LP_MAX_ROWS);
fprintf(file, "%-8d ", LP_MAX_COLS);
fprintf(file, "%-8d ", init_val);
fprintf(file, "%-8.0lf ", bnc.best_obj_val);
fprintf(file, "%-8.0lf ", ROOT_VALUE);
fprintf(file, "%-8d ", BNC_NODE_COUNT);
fprintf(file, "%-8d ", SUBTOUR_COUNT);
fprintf(file, "%-8d ", COMBS_COUNT);
fprintf(file, "\n"); fprintf(file, "\n");
fclose(file);
}
if(strlen(SOLUTION_FILENAME) == 0)
{
log_info("Optimal solution:\n");
rval = GTSP_print_solution(&data, bnc.best_x);
abort_if(rval, "GTSP_print_solution failed");
} }
fprintf(file, "%-20s ", instance_name); log_info("Optimal solution value:\n");
fprintf(file, "%-8.2lf ", TOTAL_TIME); log_info(" %.4lf\n", bnc.best_obj_val);
fprintf(file, "%-8.2lf ", SUBTOUR_TIME);
fprintf(file, "%-8.2lf ", COMBS_TIME);
fprintf(file, "%-8.2lf ", CUT_POOL_TIME);
fprintf(file, "%-8ld ", CUT_POOL_MAX_MEMORY / 1024 / 1024);
fprintf(file, "%-8d ", LP_SOLVE_COUNT);
fprintf(file, "%-8.2lf ", LP_SOLVE_TIME);
fprintf(file, "%-8d ", LP_MAX_ROWS);
fprintf(file, "%-8d ", LP_MAX_COLS);
fprintf(file, "%-8d ", init_val);
fprintf(file, "%-8.0lf ", bnc.best_obj_val);
fprintf(file, "%-8.0lf ", ROOT_VALUE);
fprintf(file, "%-8d ", BNC_NODE_COUNT);
fprintf(file, "%-8d ", SUBTOUR_COUNT);
fprintf(file, "%-8d ", COMBS_COUNT);
fprintf(file, "\n");
fclose(file);
CLEANUP: CLEANUP:
if (OPTIMAL_X) free(OPTIMAL_X); if (OPTIMAL_X) free(OPTIMAL_X);

@ -24,4 +24,8 @@ extern double ROOT_VALUE;
extern int SUBTOUR_COUNT; extern int SUBTOUR_COUNT;
extern int COMBS_COUNT; extern int COMBS_COUNT;
extern char LP_FILENAME[100];
extern char SOLUTION_FILENAME[100];
extern char FRAC_SOLUTION_FILENAME[100];
#endif #endif

@ -41,11 +41,11 @@
#endif #endif
#define abort_if(cond, msg) if(cond) { \ #define abort_if(cond, msg) if(cond) { \
fprintf(stderr, "%28s:%d " msg "\n", __FILE__, __LINE__); \ fprintf(stderr, msg " (%s:%d)\n", __FILE__, __LINE__); \
rval = 1; goto CLEANUP; } rval = 1; goto CLEANUP; }
#define abort_iff(cond, msg, ...) if(cond) { \ #define abort_iff(cond, msg, ...) if(cond) { \
fprintf(stderr, "%28s:%d " msg "\n", __FILE__, __LINE__, __VA_ARGS__); \ fprintf(stderr, msg " (%s:%d)\n", __VA_ARGS__, __FILE__, __LINE__); \
rval = 1; goto CLEANUP; } rval = 1; goto CLEANUP; }
#define UNUSED(x) (void)(x) #define UNUSED(x) (void)(x)