Write statistics to file
This commit is contained in:
@@ -99,6 +99,8 @@ static int BNC_solve_node(struct BNC *bnc, int depth)
|
||||
rval = LP_get_obj_val(lp, &objval);
|
||||
abort_if(rval, "LP_get_obj_val failed\n");
|
||||
|
||||
if(depth == 1) ROOT_VALUE = objval;
|
||||
|
||||
if (ceil(objval) > *best_val + LP_EPSILON)
|
||||
{
|
||||
log_debug("Branch pruned by bound (%.2lf > %.2lf).\n", objval,
|
||||
@@ -124,6 +126,8 @@ static int BNC_solve_node(struct BNC *bnc, int depth)
|
||||
rval = LP_get_obj_val(lp, &objval);
|
||||
abort_if(rval, "LP_get_obj_val failed");
|
||||
|
||||
if(depth == 1) ROOT_VALUE = objval;
|
||||
|
||||
if (ceil(objval) > *best_val + LP_EPSILON)
|
||||
{
|
||||
log_debug("Branch pruned by bound (%.2lf > %.2lf).\n", objval,
|
||||
|
||||
@@ -54,8 +54,6 @@ int flow_mark_reachable_nodes(
|
||||
return rval;
|
||||
}
|
||||
|
||||
extern double FLOW_CPU_TIME;
|
||||
|
||||
int flow_find_max_flow(
|
||||
const struct Graph *digraph,
|
||||
const double *capacities,
|
||||
@@ -67,7 +65,6 @@ int flow_find_max_flow(
|
||||
int rval = 0;
|
||||
|
||||
FLOW_MAX_FLOW_COUNT++;
|
||||
double initial_time = get_current_time();
|
||||
|
||||
for (int i = 0; i < digraph->node_count; i++)
|
||||
digraph->nodes[i].mark = 0;
|
||||
@@ -157,8 +154,6 @@ int flow_find_max_flow(
|
||||
rval = flow_mark_reachable_nodes(digraph, residual_caps, from);
|
||||
abort_if(rval, "flow_mark_reachable_nodes failed");
|
||||
|
||||
FLOW_CPU_TIME += get_current_time() - initial_time;
|
||||
|
||||
CLEANUP:
|
||||
if (path_edges) free(path_edges);
|
||||
if (residual_caps) free(residual_caps);
|
||||
|
||||
@@ -25,8 +25,6 @@ int flow_mark_reachable_nodes(
|
||||
|
||||
int flow_main(int argc, char **argv);
|
||||
|
||||
extern int FLOW_MAX_FLOW_COUNT;
|
||||
|
||||
#include "graph.h"
|
||||
|
||||
#endif //_PROJECT_FLOW_H_
|
||||
|
||||
@@ -370,6 +370,7 @@ static int shrink_clusters(
|
||||
int find_comb_cuts(struct LP *lp, struct GTSP *data)
|
||||
{
|
||||
int rval = 0;
|
||||
double initial_time = get_current_time();
|
||||
|
||||
double *x = 0;
|
||||
double *shrunken_x = 0;
|
||||
@@ -414,9 +415,7 @@ int find_comb_cuts(struct LP *lp, struct GTSP *data)
|
||||
component_sizes);
|
||||
abort_if(rval, "find_components failed");
|
||||
|
||||
#if LOG_LEVEL >= LOG_LEVEL_DEBUG
|
||||
int original_cut_pool_size = lp->cut_pool_size;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < cluster_count; i++)
|
||||
{
|
||||
@@ -447,7 +446,11 @@ int find_comb_cuts(struct LP *lp, struct GTSP *data)
|
||||
abort_if(rval, "add_comb_cut failed");
|
||||
}
|
||||
|
||||
log_debug(" %d combs\n", lp->cut_pool_size - original_cut_pool_size);
|
||||
int added_cuts_count = lp->cut_pool_size - original_cut_pool_size;
|
||||
log_debug(" %d combs\n", added_cuts_count);
|
||||
|
||||
COMBS_TIME += get_current_time() - initial_time;
|
||||
COMBS_COUNT += added_cuts_count;
|
||||
|
||||
CLEANUP:
|
||||
graph_free(&shrunken_graph);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "util.h"
|
||||
#include "flow.h"
|
||||
|
||||
extern double FLOW_CPU_TIME;
|
||||
extern double SUBTOUR_TIME;
|
||||
|
||||
int static build_flow_digraph(
|
||||
struct GTSP *data, double *x, struct Graph *digraph, double *capacities)
|
||||
@@ -178,6 +178,7 @@ int find_exact_subtour_cuts(
|
||||
|
||||
double *x = 0;
|
||||
double *capacities = 0;
|
||||
double initial_time = get_current_time();
|
||||
|
||||
int added_cuts_count = 0;
|
||||
struct Graph *graph = data->graph;
|
||||
@@ -214,6 +215,7 @@ int find_exact_subtour_cuts(
|
||||
|
||||
added_cuts_count = lp->cut_pool_size - original_cut_pool_size;
|
||||
log_debug(" %d cluster-to-cluster\n", added_cuts_count);
|
||||
SUBTOUR_CLUSTER_CLUSTER_COUNT += added_cuts_count;
|
||||
if (added_cuts_count > 0)
|
||||
goto CLEANUP;
|
||||
|
||||
@@ -225,6 +227,7 @@ int find_exact_subtour_cuts(
|
||||
|
||||
added_cuts_count = lp->cut_pool_size - original_cut_pool_size;
|
||||
log_debug(" %d node-to-cluster\n", added_cuts_count);
|
||||
SUBTOUR_NODE_CLUSTER_COUNT += added_cuts_count;
|
||||
if (added_cuts_count > 0)
|
||||
goto CLEANUP;
|
||||
|
||||
@@ -236,9 +239,12 @@ int find_exact_subtour_cuts(
|
||||
|
||||
added_cuts_count = lp->cut_pool_size - original_cut_pool_size;
|
||||
log_debug(" %d node-to-node\n", added_cuts_count);
|
||||
SUBTOUR_NODE_NODE_COUNT += added_cuts_count;
|
||||
if (added_cuts_count > 0)
|
||||
goto CLEANUP;
|
||||
|
||||
SUBTOUR_TIME += get_current_time() - initial_time;
|
||||
|
||||
CLEANUP:
|
||||
graph_free(&digraph);
|
||||
if (capacities) free(capacities);
|
||||
|
||||
87
src/gtsp.c
87
src/gtsp.c
@@ -3,10 +3,10 @@
|
||||
#include <getopt.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include "gtsp.h"
|
||||
#include "geometry.h"
|
||||
#include "util.h"
|
||||
#include "flow.h"
|
||||
#include "gtsp-subtour.h"
|
||||
#include "gtsp-comb.h"
|
||||
|
||||
@@ -618,11 +618,6 @@ static int GTSP_parse_args(int argc, char **argv)
|
||||
return rval;
|
||||
}
|
||||
|
||||
double FLOW_CPU_TIME = 0;
|
||||
double LP_SOLVE_TIME = 0;
|
||||
double LP_CUT_POOL_TIME = 0;
|
||||
int LP_OPTIMIZE_COUNT = 0;
|
||||
|
||||
int GTSP_main(int argc, char **argv)
|
||||
{
|
||||
int rval = 0;
|
||||
@@ -631,8 +626,9 @@ int GTSP_main(int argc, char **argv)
|
||||
struct GTSP data;
|
||||
|
||||
double *initial_x = 0;
|
||||
double initial_time = get_current_time();
|
||||
|
||||
SEED = (unsigned int) get_real_time() % 1000000;
|
||||
SEED = (unsigned int) get_real_time() % 1000;
|
||||
|
||||
rval = GTSP_init_data(&data);
|
||||
abort_if(rval, "GTSP_init_data failed");
|
||||
@@ -651,13 +647,16 @@ int GTSP_main(int argc, char **argv)
|
||||
log_info(" input_cluster_count = %d\n", input_cluster_count);
|
||||
log_info(" grid_size = %d\n", grid_size);
|
||||
|
||||
char instance_name[1000];
|
||||
sprintf(instance_name, "gtsp-m%d-n%d-s%d", input_cluster_count,
|
||||
input_node_count, SEED);
|
||||
|
||||
rval = GTSP_create_random_problem(input_node_count, input_cluster_count,
|
||||
grid_size, &data);
|
||||
abort_if(rval, "GTSP_create_random_problem failed");
|
||||
|
||||
char filename[100];
|
||||
sprintf(filename, "input/gtsp-m%d-n%d-s%d.in", input_cluster_count,
|
||||
input_node_count, SEED);
|
||||
sprintf(filename, "input/%s.in", instance_name);
|
||||
log_info("Writing random instance to file %s\n", filename);
|
||||
rval = GTSP_write_problem(&data, filename);
|
||||
abort_if(rval, "GTSP_write_problem failed");
|
||||
@@ -669,7 +668,8 @@ int GTSP_main(int argc, char **argv)
|
||||
|
||||
int init_val;
|
||||
|
||||
initial_x = (double*) malloc((data.graph->node_count + data.graph->edge_count) * sizeof(double));
|
||||
initial_x = (double *) malloc(
|
||||
(data.graph->node_count + data.graph->edge_count) * sizeof(double));
|
||||
abort_if(!initial_x, "could not allocate initial_x");
|
||||
|
||||
rval = inital_tour_value(&data, &init_val, initial_x);
|
||||
@@ -684,15 +684,14 @@ int GTSP_main(int argc, char **argv)
|
||||
bnc.problem_init_lp = (int (*)(struct LP *, void *)) GTSP_init_lp;
|
||||
bnc.problem_add_cutting_planes = (int (*)(
|
||||
struct LP *, void *)) GTSP_add_cutting_planes;
|
||||
bnc.problem_solution_found = (int (*)(struct BNC*,
|
||||
void *, double *)) GTSP_solution_found;
|
||||
bnc.problem_solution_found = (int (*)(
|
||||
struct BNC *, void *, double *)) GTSP_solution_found;
|
||||
|
||||
double opt_val = 0.0;
|
||||
|
||||
if (strlen(input_x_filename) == 0)
|
||||
{
|
||||
sprintf(input_x_filename, "optimal/gtsp-m%d-n%d-s%d.out",
|
||||
input_cluster_count, input_node_count, SEED);
|
||||
sprintf(input_x_filename, "optimal/%s.out", instance_name);
|
||||
|
||||
FILE *file = fopen(input_x_filename, "r");
|
||||
|
||||
@@ -742,12 +741,64 @@ int GTSP_main(int argc, char **argv)
|
||||
opt_val);
|
||||
}
|
||||
|
||||
TOTAL_TIME = get_current_time() - initial_time;
|
||||
|
||||
log_info("Branch-and-bound nodes: %d\n", BNC_NODE_COUNT);
|
||||
log_info("Max-flow calls: %d\n", FLOW_MAX_FLOW_COUNT);
|
||||
log_info("Max-flow computation time: %.2lf\n", FLOW_CPU_TIME);
|
||||
log_info("LP optimize calls: %d\n", LP_OPTIMIZE_COUNT);
|
||||
log_info("LP optimize calls: %d\n", LP_SOLVE_COUNT);
|
||||
log_info("LP solving time: %.2lf\n", LP_SOLVE_TIME);
|
||||
log_info("LP cut pool management time: %.2lf\n", LP_CUT_POOL_TIME);
|
||||
log_info("LP cut pool management time: %.2lf\n", CUT_POOL_TIME);
|
||||
|
||||
FILE *file = fopen("stats.tab", "a");
|
||||
abort_if(!file, "could not open stats.tab");
|
||||
|
||||
|
||||
struct stat st;
|
||||
stat("stats.tab", &st);
|
||||
|
||||
if(st.st_size == 0)
|
||||
{
|
||||
fprintf(file, "%-20s ", "instance");
|
||||
fprintf(file, "%-8s ", "time");
|
||||
fprintf(file, "%-8s ", "subt-t");
|
||||
fprintf(file, "%-8s ", "combs-t");
|
||||
fprintf(file, "%-8s ", "pool-t");
|
||||
fprintf(file, "%-8s ", "pool-m");
|
||||
fprintf(file, "%-8s ", "lp-count");
|
||||
fprintf(file, "%-8s ", "lp-time");
|
||||
fprintf(file, "%-8s ", "lp-rows");
|
||||
fprintf(file, "%-8s ", "lp-cols");
|
||||
fprintf(file, "%-8s ", "init-v");
|
||||
fprintf(file, "%-8s ", "opt-v");
|
||||
fprintf(file, "%-8s ", "root-v");
|
||||
fprintf(file, "%-8s ", "nodes");
|
||||
fprintf(file, "%-8s ", "subt-cc");
|
||||
fprintf(file, "%-8s ", "subt-nc");
|
||||
fprintf(file, "%-8s ", "subt-nn");
|
||||
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_CLUSTER_CLUSTER_COUNT);
|
||||
fprintf(file, "%-8d ", SUBTOUR_NODE_CLUSTER_COUNT);
|
||||
fprintf(file, "%-8d ", SUBTOUR_NODE_NODE_COUNT);
|
||||
fprintf(file, "%-8d ", COMBS_COUNT);
|
||||
fprintf(file, "\n");
|
||||
fclose(file);
|
||||
|
||||
CLEANUP:
|
||||
if (OPTIMAL_X) free(OPTIMAL_X);
|
||||
|
||||
@@ -62,7 +62,5 @@ int list_length(struct Tour * tour, struct GTSP* data);
|
||||
|
||||
void print_list(struct Tour * tour, struct GTSP* data);
|
||||
|
||||
extern double *OPTIMAL_X;
|
||||
extern double FLOW_CPU_TIME;
|
||||
|
||||
#endif //_PROJECT_GTSP_H_
|
||||
|
||||
39
src/lp.c
39
src/lp.c
@@ -5,6 +5,7 @@
|
||||
#include <assert.h>
|
||||
#include "lp.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
|
||||
int LP_open(struct LP *lp)
|
||||
{
|
||||
@@ -158,9 +159,9 @@ int LP_change_bound(struct LP *lp, int col, char lower_or_upper, double bnd)
|
||||
return rval;
|
||||
}
|
||||
|
||||
extern int LP_OPTIMIZE_COUNT;
|
||||
extern int LP_SOLVE_COUNT;
|
||||
extern double LP_SOLVE_TIME;
|
||||
extern double LP_CUT_POOL_TIME;
|
||||
extern double CUT_POOL_TIME;
|
||||
|
||||
int LP_update_cut_ages(struct LP *lp)
|
||||
{
|
||||
@@ -196,26 +197,30 @@ int LP_update_cut_ages(struct LP *lp)
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int LP_optimize(struct LP *lp, int *infeasible)
|
||||
{
|
||||
LP_OPTIMIZE_COUNT++;
|
||||
LP_SOLVE_COUNT++;
|
||||
|
||||
int rval = 0, solstat;
|
||||
|
||||
*infeasible = 0;
|
||||
|
||||
#if LOG_LEVEL >= LOG_LEVEL_DEBUG
|
||||
int numrows = CPXgetnumrows(lp->cplex_env, lp->cplex_lp);
|
||||
int numcols = CPXgetnumcols(lp->cplex_env, lp->cplex_lp);
|
||||
log_debug("Optimizing LP (%d rows %d cols)...\n", numrows, numcols);
|
||||
#endif
|
||||
|
||||
double time_before = get_current_time();
|
||||
if(numrows > LP_MAX_ROWS) LP_MAX_ROWS = numrows;
|
||||
if(numrows > LP_MAX_COLS) LP_MAX_COLS = numcols;
|
||||
|
||||
log_debug("Optimizing LP (%d rows %d cols)...\n", numrows, numcols);
|
||||
|
||||
double initial_time = get_current_time();
|
||||
|
||||
rval = CPXdualopt(lp->cplex_env, lp->cplex_lp);
|
||||
abort_if(rval, "CPXdualopt failed");
|
||||
|
||||
double time_after = get_current_time();
|
||||
LP_SOLVE_TIME += time_after - time_before;
|
||||
LP_SOLVE_TIME += get_current_time() - initial_time;
|
||||
|
||||
solstat = CPXgetstat(lp->cplex_env, lp->cplex_lp);
|
||||
if (solstat == CPX_STAT_INFEASIBLE)
|
||||
@@ -234,9 +239,9 @@ int LP_optimize(struct LP *lp, int *infeasible)
|
||||
abort_if(rval, "LP_get_obj_val failed");
|
||||
|
||||
log_debug(" obj val = %.4lf\n", objval);
|
||||
log_debug(" time = %.4lf\n", time_after - time_before);
|
||||
log_debug(" time = %.4lf\n", get_current_time() - initial_time);
|
||||
|
||||
time_before = get_current_time();
|
||||
initial_time = get_current_time();
|
||||
rval = LP_update_cut_ages(lp);
|
||||
abort_if(rval, "LP_update_cut_ages failed");
|
||||
|
||||
@@ -244,8 +249,7 @@ int LP_optimize(struct LP *lp, int *infeasible)
|
||||
rval = LP_remove_old_cuts(lp);
|
||||
abort_if(rval, "LP_remove_old_cuts failed");
|
||||
|
||||
time_after = get_current_time();
|
||||
LP_CUT_POOL_TIME += time_after - time_before;
|
||||
CUT_POOL_TIME += get_current_time() - initial_time;
|
||||
|
||||
CLEANUP:
|
||||
return rval;
|
||||
@@ -352,6 +356,9 @@ int LP_remove_old_cuts(struct LP *lp)
|
||||
|
||||
log_debug(" %ld cuts (%ld nz, %ld MiB)\n", lp->cut_pool_size, nz, size/1024/1024);
|
||||
|
||||
if(size > CUT_POOL_MAX_MEMORY)
|
||||
CUT_POOL_MAX_MEMORY = size;
|
||||
|
||||
CLEANUP:
|
||||
if (should_remove) free(should_remove);
|
||||
return rval;
|
||||
@@ -426,8 +433,8 @@ int compare_cuts(struct Row *cut1, struct Row *cut2)
|
||||
int LP_add_cut(struct LP *lp, struct Row *cut)
|
||||
{
|
||||
int rval = 0;
|
||||
double initial_time = get_current_time();
|
||||
|
||||
double time_before = get_current_time();
|
||||
rval = LP_update_hash(cut);
|
||||
abort_if(rval, "LP_update_hash failed");
|
||||
|
||||
@@ -458,9 +465,7 @@ int LP_add_cut(struct LP *lp, struct Row *cut)
|
||||
cut->cplex_row_index = CPXgetnumrows(lp->cplex_env, lp->cplex_lp) - 1;
|
||||
cut->age = 0;
|
||||
|
||||
double time_after = get_current_time();
|
||||
LP_CUT_POOL_TIME += time_after - time_before;
|
||||
|
||||
CUT_POOL_TIME += get_current_time() - initial_time;
|
||||
CLEANUP:
|
||||
return rval;
|
||||
}
|
||||
|
||||
21
src/main.c
21
src/main.c
@@ -10,6 +10,27 @@ int GEOMETRIC_DATA = 0;
|
||||
int NODE_COUNT_RAND = 0;
|
||||
int GRID_SIZE_RAND = 100;
|
||||
|
||||
double SUBTOUR_TIME = 0;
|
||||
double COMBS_TIME = 0;
|
||||
|
||||
double CUT_POOL_TIME = 0;
|
||||
long CUT_POOL_MAX_MEMORY = 0;
|
||||
|
||||
double LP_SOLVE_TIME = 0;
|
||||
|
||||
int LP_MAX_COLS = 0;
|
||||
int LP_MAX_ROWS = 0;
|
||||
int LP_SOLVE_COUNT = 0;
|
||||
|
||||
double TOTAL_TIME = 0;
|
||||
double ROOT_VALUE = 0;
|
||||
|
||||
int SUBTOUR_CLUSTER_CLUSTER_COUNT = 0;
|
||||
int SUBTOUR_NODE_CLUSTER_COUNT = 0;
|
||||
int SUBTOUR_NODE_NODE_COUNT = 0;
|
||||
int COMBS_COUNT = 0;
|
||||
|
||||
|
||||
static const struct option options_tab[] = {
|
||||
{"help", no_argument, 0, 'h'}, {"tsp", no_argument, 0, 't'},
|
||||
{"gtsp", no_argument, 0, 'g'}, {"flow", no_argument, 0, 'f'},
|
||||
|
||||
23
src/main.h
23
src/main.h
@@ -7,4 +7,27 @@ extern int GEOMETRIC_DATA;
|
||||
extern int NODE_COUNT_RAND;
|
||||
extern int GRID_SIZE_RAND;
|
||||
|
||||
extern double *OPTIMAL_X;
|
||||
extern double SUBTOUR_TIME;
|
||||
extern double COMBS_TIME;
|
||||
|
||||
extern double LP_SOLVE_TIME;
|
||||
extern int LP_SOLVE_COUNT;
|
||||
extern int LP_MAX_ROWS;
|
||||
extern int LP_MAX_COLS;
|
||||
|
||||
extern double CUT_POOL_TIME;
|
||||
extern long CUT_POOL_MAX_MEMORY;
|
||||
|
||||
extern int FLOW_MAX_FLOW_COUNT;
|
||||
|
||||
extern double TOTAL_TIME;
|
||||
extern double ROOT_VALUE;
|
||||
|
||||
extern int SUBTOUR_CLUSTER_CLUSTER_COUNT;
|
||||
extern int SUBTOUR_NODE_CLUSTER_COUNT;
|
||||
extern int SUBTOUR_NODE_NODE_COUNT;
|
||||
|
||||
extern int COMBS_COUNT;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user