New logging macros
This commit is contained in:
@@ -26,7 +26,7 @@ int BNC_init(struct BNC *bnc)
|
|||||||
bnc->best_obj_val = 0;
|
bnc->best_obj_val = 0;
|
||||||
|
|
||||||
bnc->lp = (struct LP *) malloc(sizeof(struct LP));
|
bnc->lp = (struct LP *) malloc(sizeof(struct LP));
|
||||||
ABORT_IF(!bnc->lp, "could not allocate bnc->lp\n");
|
abort_if(!bnc->lp, "could not allocate bnc->lp");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
return rval;
|
return rval;
|
||||||
@@ -45,19 +45,19 @@ void BNC_free(struct BNC *bnc)
|
|||||||
int BNC_init_lp(struct BNC *bnc)
|
int BNC_init_lp(struct BNC *bnc)
|
||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
time_printf("Initializing LP...\n");
|
log_verbose("Initializing LP...\n");
|
||||||
|
|
||||||
rval = LP_open(bnc->lp);
|
rval = LP_open(bnc->lp);
|
||||||
ABORT_IF(rval, "LP_open failed\n");
|
abort_if(rval, "LP_open failed");
|
||||||
|
|
||||||
rval = LP_create(bnc->lp, "subtour");
|
rval = LP_create(bnc->lp, "subtour");
|
||||||
ABORT_IF(rval, "LP_create failed\n");
|
abort_if(rval, "LP_create failed");
|
||||||
|
|
||||||
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\n");
|
abort_if(rval, "problem_init_lp failed");
|
||||||
|
|
||||||
rval = LP_write(bnc->lp, "subtour.lp");
|
rval = LP_write(bnc->lp, "subtour.lp");
|
||||||
ABORT_IF(rval, "LP_write failed\n");
|
abort_if(rval, "LP_write failed");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
return rval;
|
return rval;
|
||||||
@@ -76,27 +76,27 @@ static int BNC_solve_node(struct BNC *bnc, int depth)
|
|||||||
int rval = 0;
|
int rval = 0;
|
||||||
double *x = (double *) NULL;
|
double *x = (double *) NULL;
|
||||||
|
|
||||||
time_printf("Optimizing...\n");
|
log_verbose("Optimizing...\n");
|
||||||
|
|
||||||
int is_infeasible;
|
int is_infeasible;
|
||||||
rval = LP_optimize(lp, &is_infeasible);
|
rval = LP_optimize(lp, &is_infeasible);
|
||||||
ABORT_IF (rval, "LP_optimize failed\n");
|
abort_if(rval, "LP_optimize failed\n");
|
||||||
|
|
||||||
if (is_infeasible)
|
if (is_infeasible)
|
||||||
{
|
{
|
||||||
time_printf("Branch pruned by infeasibility.\n");
|
log_verbose("Branch pruned by infeasibility.\n");
|
||||||
goto CLEANUP;
|
goto CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
double objval;
|
double objval;
|
||||||
rval = LP_get_obj_val(lp, &objval);
|
rval = LP_get_obj_val(lp, &objval);
|
||||||
ABORT_IF (rval, "LP_get_obj_val failed\n");
|
abort_if(rval, "LP_get_obj_val failed\n");
|
||||||
|
|
||||||
time_printf(" objective value = %.2f\n", objval);
|
log_verbose(" objective value = %.2f\n", objval);
|
||||||
|
|
||||||
if (objval > *best_val)
|
if (objval > *best_val)
|
||||||
{
|
{
|
||||||
time_printf("Branch pruned by bound (%.2lf > %.2lf).\n", objval,
|
log_verbose("Branch pruned by bound (%.2lf > %.2lf).\n", objval,
|
||||||
*best_val);
|
*best_val);
|
||||||
rval = 0;
|
rval = 0;
|
||||||
goto CLEANUP;
|
goto CLEANUP;
|
||||||
@@ -105,29 +105,29 @@ static int BNC_solve_node(struct BNC *bnc, int depth)
|
|||||||
int num_cols = LP_get_num_cols(lp);
|
int num_cols = LP_get_num_cols(lp);
|
||||||
|
|
||||||
x = (double *) malloc(num_cols * sizeof(double));
|
x = (double *) malloc(num_cols * sizeof(double));
|
||||||
ABORT_IF(!x, "could not allocate x\n");
|
abort_if(!x, "could not allocate x");
|
||||||
|
|
||||||
rval = LP_get_x(lp, x);
|
rval = LP_get_x(lp, x);
|
||||||
ABORT_IF(rval, "LP_get_x failed\n");
|
abort_if(rval, "LP_get_x failed");
|
||||||
|
|
||||||
if (bnc->problem_add_cutting_planes)
|
if (bnc->problem_add_cutting_planes)
|
||||||
{
|
{
|
||||||
rval = bnc->problem_add_cutting_planes(lp, bnc->problem_data);
|
rval = bnc->problem_add_cutting_planes(lp, bnc->problem_data);
|
||||||
ABORT_IF(rval, "problem_add_cutting_planes failed\n");
|
abort_if(rval, "problem_add_cutting_planes failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
rval = LP_optimize(lp, &is_infeasible);
|
rval = LP_optimize(lp, &is_infeasible);
|
||||||
ABORT_IF (rval, "LP_optimize failed\n");
|
abort_if(rval, "LP_optimize failed\n");
|
||||||
|
|
||||||
rval = LP_get_obj_val(lp, &objval);
|
rval = LP_get_obj_val(lp, &objval);
|
||||||
ABORT_IF(rval, "LP_get_obj_val failed\n");
|
abort_if(rval, "LP_get_obj_val failed");
|
||||||
|
|
||||||
rval = LP_get_x(lp, x);
|
rval = LP_get_x(lp, x);
|
||||||
ABORT_IF(rval, "LP_get_x failed\n");
|
abort_if(rval, "LP_get_x failed");
|
||||||
|
|
||||||
if (BNC_is_integral(x, num_cols))
|
if (BNC_is_integral(x, num_cols))
|
||||||
{
|
{
|
||||||
time_printf(" solution is integral\n");
|
log_verbose(" solution is integral\n");
|
||||||
|
|
||||||
if (objval < *best_val)
|
if (objval < *best_val)
|
||||||
{
|
{
|
||||||
@@ -135,15 +135,15 @@ static int BNC_solve_node(struct BNC *bnc, int depth)
|
|||||||
bnc->best_x = x;
|
bnc->best_x = x;
|
||||||
x = 0;
|
x = 0;
|
||||||
|
|
||||||
time_printf("Found a better integral solution:\n");
|
log_info("Found a better integral solution:\n");
|
||||||
time_printf(" objval = %.2lf **\n", objval);
|
log_info(" objval = %.2lf **\n", objval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
time_printf(" solution is fractional\n");
|
log_verbose(" solution is fractional\n");
|
||||||
rval = BNC_branch_node(bnc, x, depth);
|
rval = BNC_branch_node(bnc, x, depth);
|
||||||
ABORT_IF(rval, "BNC_branch_node failed\n");
|
abort_if(rval, "BNC_branch_node failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
@@ -160,30 +160,30 @@ static int BNC_branch_node(struct BNC *bnc, double *x, int depth)
|
|||||||
int num_cols = LP_get_num_cols(lp);
|
int num_cols = LP_get_num_cols(lp);
|
||||||
int best_branch_var = BNC_find_best_branching_var(x, num_cols);
|
int best_branch_var = BNC_find_best_branching_var(x, num_cols);
|
||||||
|
|
||||||
time_printf("Branching on variable x%d = %.6lf (depth %d)...\n",
|
log_verbose("Branching on variable x%d = %.6lf (depth %d)...\n",
|
||||||
best_branch_var, x[best_branch_var], depth);
|
best_branch_var, x[best_branch_var], depth);
|
||||||
|
|
||||||
time_printf("Fixing variable x%d to one...\n", best_branch_var);
|
log_verbose("Fixing variable x%d to one...\n", best_branch_var);
|
||||||
rval = LP_change_bound(lp, best_branch_var, 'L', 1.0);
|
rval = LP_change_bound(lp, best_branch_var, 'L', 1.0);
|
||||||
ABORT_IF(rval, "LP_change_bound failed\n");
|
abort_if(rval, "LP_change_bound failed");
|
||||||
|
|
||||||
rval = BNC_solve_node(bnc, depth + 1);
|
rval = BNC_solve_node(bnc, depth + 1);
|
||||||
ABORT_IF(rval, "BNC_solve_node failed\n");
|
abort_if(rval, "BNC_solve_node failed");
|
||||||
|
|
||||||
rval = LP_change_bound(lp, best_branch_var, 'L', 0.0);
|
rval = LP_change_bound(lp, best_branch_var, 'L', 0.0);
|
||||||
ABORT_IF(rval, "LP_change_bound failed\n");
|
abort_if(rval, "LP_change_bound failed");
|
||||||
|
|
||||||
time_printf("Fixing variable x%d to zero...\n", best_branch_var);
|
log_verbose("Fixing variable x%d to zero...\n", best_branch_var);
|
||||||
rval = LP_change_bound(lp, best_branch_var, 'U', 0.0);
|
rval = LP_change_bound(lp, best_branch_var, 'U', 0.0);
|
||||||
ABORT_IF(rval, "LP_change_bound failed\n");
|
abort_if(rval, "LP_change_bound failed");
|
||||||
|
|
||||||
rval = BNC_solve_node(bnc, depth + 1);
|
rval = BNC_solve_node(bnc, depth + 1);
|
||||||
ABORT_IF(rval, "BNC_solve_node failed\n");
|
abort_if(rval, "BNC_solve_node failed");
|
||||||
|
|
||||||
rval = LP_change_bound(lp, best_branch_var, 'U', 1.0);
|
rval = LP_change_bound(lp, best_branch_var, 'U', 1.0);
|
||||||
ABORT_IF(rval, "LP_change_bound failed\n");
|
abort_if(rval, "LP_change_bound failed");
|
||||||
|
|
||||||
time_printf("Finished branching on variable %d\n", best_branch_var);
|
log_verbose("Finished branching on variable %d\n", best_branch_var);
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
return rval;
|
return rval;
|
||||||
|
|||||||
@@ -17,13 +17,13 @@ int generate_random_points_2d(
|
|||||||
int **hit = 0, *hit_count = 0;
|
int **hit = 0, *hit_count = 0;
|
||||||
|
|
||||||
hit = (int **) malloc(grid_size * sizeof(int *));
|
hit = (int **) malloc(grid_size * sizeof(int *));
|
||||||
ABORT_IF (!hit, "out of memory for hit\n");
|
abort_if(!hit, "could not allocate hit");
|
||||||
|
|
||||||
for (i = 0; i < grid_size; i++)
|
for (i = 0; i < grid_size; i++)
|
||||||
hit[i] = 0;
|
hit[i] = 0;
|
||||||
|
|
||||||
hit_count = (int *) malloc(grid_size * sizeof(int));
|
hit_count = (int *) malloc(grid_size * sizeof(int));
|
||||||
ABORT_IF(!hit_count, "out of memory for hit_count\n");
|
abort_if(!hit_count, "could not allocate hit_count");
|
||||||
|
|
||||||
for (i = 0; i < grid_size; i++)
|
for (i = 0; i < grid_size; i++)
|
||||||
hit_count[i] = 0;
|
hit_count[i] = 0;
|
||||||
@@ -44,7 +44,7 @@ int generate_random_points_2d(
|
|||||||
{
|
{
|
||||||
void *tmp_ptr = (void *) hit[x];
|
void *tmp_ptr = (void *) hit[x];
|
||||||
tmp_ptr = realloc(tmp_ptr, (hit_count[x] + 1) * sizeof(int));
|
tmp_ptr = realloc(tmp_ptr, (hit_count[x] + 1) * sizeof(int));
|
||||||
ABORT_IF (!tmp_ptr, "could not reallocate hit_count\n");
|
abort_if(!tmp_ptr, "could not reallocate hit_count");
|
||||||
|
|
||||||
hit[x] = (int *) tmp_ptr;
|
hit[x] = (int *) tmp_ptr;
|
||||||
hit[x][hit_count[x]] = y;
|
hit[x][hit_count[x]] = y;
|
||||||
@@ -82,7 +82,7 @@ int generate_random_clusters_2d(
|
|||||||
|
|
||||||
rval = generate_random_points_2d(node_count, grid_size, x_coordinates,
|
rval = generate_random_points_2d(node_count, grid_size, x_coordinates,
|
||||||
y_coordinates);
|
y_coordinates);
|
||||||
ABORT_IF(rval, "generate_random_points_2d failed");
|
abort_if(rval, "generate_random_points_2d failed");
|
||||||
|
|
||||||
for (int i = 0; i < cluster_count; i++)
|
for (int i = 0; i < cluster_count; i++)
|
||||||
clusters[i] = i;
|
clusters[i] = i;
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ int graph_build(int node_count, int edge_count, int *edge_list, struct Graph *G)
|
|||||||
G->adj_space =
|
G->adj_space =
|
||||||
(struct AdjObj *) malloc(2 * edge_count * sizeof(struct AdjObj));
|
(struct AdjObj *) malloc(2 * edge_count * sizeof(struct AdjObj));
|
||||||
|
|
||||||
ABORT_IF(!G->node_list, "could not allocate G->node_list\n");
|
abort_if(!G->node_list, "could not allocate G->node_list");
|
||||||
ABORT_IF(!G->adj_space, "could not allocate G->adj_space\n");
|
abort_if(!G->adj_space, "could not allocate G->adj_space");
|
||||||
|
|
||||||
for (int i = 0; i < node_count; i++)
|
for (int i = 0; i < node_count; i++)
|
||||||
G->node_list[i].deg = 0;
|
G->node_list[i].deg = 0;
|
||||||
|
|||||||
22
src/gtsp.c
22
src/gtsp.c
@@ -40,17 +40,17 @@ int GTSP_create_random_problem(
|
|||||||
|
|
||||||
edges = (struct Edge *) malloc(edge_count * sizeof(struct Edge));
|
edges = (struct Edge *) malloc(edge_count * sizeof(struct Edge));
|
||||||
clusters = (int *) malloc(node_count * sizeof(int));
|
clusters = (int *) malloc(node_count * sizeof(int));
|
||||||
ABORT_IF (!edges, "could not allocate data->edges\n");
|
abort_if(!edges, "could not allocate data->edges\n");
|
||||||
ABORT_IF (!clusters, "could not allocate clusters\n");
|
abort_if(!clusters, "could not allocate clusters\n");
|
||||||
|
|
||||||
x_coords = (double *) malloc(node_count * sizeof(double));
|
x_coords = (double *) malloc(node_count * sizeof(double));
|
||||||
y_coords = (double *) malloc(node_count * sizeof(double));
|
y_coords = (double *) malloc(node_count * sizeof(double));
|
||||||
ABORT_IF (!x_coords, "could not allocate x_coords\n");
|
abort_if(!x_coords, "could not allocate x_coords\n");
|
||||||
ABORT_IF (!y_coords, "could not allocate y_coords\n");
|
abort_if(!y_coords, "could not allocate y_coords\n");
|
||||||
|
|
||||||
rval = generate_random_clusters_2d(node_count, cluster_count, grid_size,
|
rval = generate_random_clusters_2d(node_count, cluster_count, grid_size,
|
||||||
x_coords, y_coords, clusters);
|
x_coords, y_coords, clusters);
|
||||||
ABORT_IF(rval, "generate_random_clusters_2d failed");
|
abort_if(rval, "generate_random_clusters_2d failed");
|
||||||
|
|
||||||
int current_edge = 0;
|
int current_edge = 0;
|
||||||
for (int i = 0; i < edge_count; i++)
|
for (int i = 0; i < edge_count; i++)
|
||||||
@@ -94,13 +94,13 @@ int GTSP_init_lp(struct LP *lp, struct GTSP *data)
|
|||||||
for (int i = 0; i < node_count; i++)
|
for (int i = 0; i < node_count; i++)
|
||||||
{
|
{
|
||||||
rval = LP_new_row(lp, 'E', 0.0);
|
rval = LP_new_row(lp, 'E', 0.0);
|
||||||
ABORT_IF(rval, "LP_new_row failed");
|
abort_if(rval, "LP_new_row failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < cluster_count; i++)
|
for (int i = 0; i < cluster_count; i++)
|
||||||
{
|
{
|
||||||
rval = LP_new_row(lp, 'E', 1.0);
|
rval = LP_new_row(lp, 'E', 1.0);
|
||||||
ABORT_IF(rval, "LP_new_row failed");
|
abort_if(rval, "LP_new_row failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
double lb = 0.0;
|
double lb = 0.0;
|
||||||
@@ -115,7 +115,7 @@ int GTSP_init_lp(struct LP *lp, struct GTSP *data)
|
|||||||
|
|
||||||
rval = LP_add_cols(lp, 1, 2, &obj, &cmatbeg, cmatind, cmatval, &lb,
|
rval = LP_add_cols(lp, 1, 2, &obj, &cmatbeg, cmatind, cmatval, &lb,
|
||||||
&ub);
|
&ub);
|
||||||
ABORT_IF(rval, "LP_add_cols failed");
|
abort_if(rval, "LP_add_cols failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < edge_count; i++)
|
for (int i = 0; i < edge_count; i++)
|
||||||
@@ -126,7 +126,7 @@ int GTSP_init_lp(struct LP *lp, struct GTSP *data)
|
|||||||
|
|
||||||
rval = LP_add_cols(lp, 1, 2, &obj, &cmatbeg, cmatind, cmatval, &lb,
|
rval = LP_add_cols(lp, 1, 2, &obj, &cmatbeg, cmatind, cmatval, &lb,
|
||||||
&ub);
|
&ub);
|
||||||
ABORT_IF(rval, "LP_add_cols failed");
|
abort_if(rval, "LP_add_cols failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
@@ -140,7 +140,7 @@ int GTSP_write_data(struct GTSP *data, char *filename)
|
|||||||
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");
|
||||||
|
|
||||||
fprintf(file, "%d %d\n", data->node_count, data->cluster_count);
|
fprintf(file, "%d %d\n", data->node_count, data->cluster_count);
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ int GTSP_write_solution(struct GTSP *data, char *filename, double *x)
|
|||||||
|
|
||||||
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");
|
||||||
|
|
||||||
int positive_edge_count = 0;
|
int positive_edge_count = 0;
|
||||||
for (int i = 0; i < data->edge_count; i++)
|
for (int i = 0; i < data->edge_count; i++)
|
||||||
|
|||||||
24
src/lp.c
24
src/lp.c
@@ -40,13 +40,13 @@ int LP_create(struct LP *lp, const char *name)
|
|||||||
int rval = 0;
|
int rval = 0;
|
||||||
char nambuf[MAX_NAME_LENGTH];
|
char nambuf[MAX_NAME_LENGTH];
|
||||||
|
|
||||||
ABORT_IF(!lp->cplex_env, "cplex_env is null\n");
|
abort_if(!lp->cplex_env, "cplex_env is null");
|
||||||
|
|
||||||
strncpy(nambuf, name, MAX_NAME_LENGTH);
|
strncpy(nambuf, name, MAX_NAME_LENGTH);
|
||||||
nambuf[MAX_NAME_LENGTH - 1] = '\0';
|
nambuf[MAX_NAME_LENGTH - 1] = '\0';
|
||||||
|
|
||||||
lp->cplex_lp = CPXcreateprob(lp->cplex_env, &rval, nambuf);
|
lp->cplex_lp = CPXcreateprob(lp->cplex_env, &rval, nambuf);
|
||||||
ABORT_IF(rval, "CPXcreateprob failed\n");
|
abort_if(rval, "CPXcreateprob failed");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
return rval;
|
return rval;
|
||||||
@@ -58,7 +58,7 @@ int LP_new_row(struct LP *lp, char sense, double rhs)
|
|||||||
|
|
||||||
rval = CPXnewrows(lp->cplex_env, lp->cplex_lp, 1, &rhs, &sense, 0, 0);
|
rval = CPXnewrows(lp->cplex_env, lp->cplex_lp, 1, &rhs, &sense, 0, 0);
|
||||||
|
|
||||||
ABORT_IF(rval, "CPXnewrows failed\n");
|
abort_if(rval, "CPXnewrows failed");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
return rval;
|
return rval;
|
||||||
@@ -79,7 +79,7 @@ int LP_add_rows(
|
|||||||
rval = CPXaddrows(lp->cplex_env, lp->cplex_lp, 0, newrows, newnz, rhs,
|
rval = CPXaddrows(lp->cplex_env, lp->cplex_lp, 0, newrows, newnz, rhs,
|
||||||
sense, rmatbeg, rmatind, rmatval, 0, 0);
|
sense, rmatbeg, rmatind, rmatval, 0, 0);
|
||||||
|
|
||||||
ABORT_IF(rval, "CPXaddrows failed\n");
|
abort_if(rval, "CPXaddrows failed");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
return rval;
|
return rval;
|
||||||
@@ -101,7 +101,7 @@ int LP_add_cols(
|
|||||||
rval = CPXaddcols(lp->cplex_env, lp->cplex_lp, newcols, newnz, obj, cmatbeg,
|
rval = CPXaddcols(lp->cplex_env, lp->cplex_lp, newcols, newnz, obj, cmatbeg,
|
||||||
cmatind, cmatval, lb, ub, (char **) NULL);
|
cmatind, cmatval, lb, ub, (char **) NULL);
|
||||||
|
|
||||||
ABORT_IF(rval, "CPXaddcols failed\n");
|
abort_if(rval, "CPXaddcols failed");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
return rval;
|
return rval;
|
||||||
@@ -113,7 +113,7 @@ int LP_change_bound(struct LP *lp, int col, char lower_or_upper, double bnd)
|
|||||||
|
|
||||||
rval = CPXchgbds(lp->cplex_env, lp->cplex_lp, 1, &col, &lower_or_upper,
|
rval = CPXchgbds(lp->cplex_env, lp->cplex_lp, 1, &col, &lower_or_upper,
|
||||||
&bnd);
|
&bnd);
|
||||||
ABORT_IF(rval, "CPXchgbds failed\n");
|
abort_if(rval, "CPXchgbds failed");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
return rval;
|
return rval;
|
||||||
@@ -126,7 +126,7 @@ int LP_optimize(struct LP *lp, int *infeasible)
|
|||||||
*infeasible = 0;
|
*infeasible = 0;
|
||||||
|
|
||||||
rval = CPXdualopt(lp->cplex_env, lp->cplex_lp);
|
rval = CPXdualopt(lp->cplex_env, lp->cplex_lp);
|
||||||
ABORT_IF(rval, "CPXdualopt failed\n");
|
abort_if(rval, "CPXdualopt failed");
|
||||||
|
|
||||||
solstat = CPXgetstat(lp->cplex_env, lp->cplex_lp);
|
solstat = CPXgetstat(lp->cplex_env, lp->cplex_lp);
|
||||||
if (solstat == CPX_STAT_INFEASIBLE)
|
if (solstat == CPX_STAT_INFEASIBLE)
|
||||||
@@ -135,7 +135,7 @@ int LP_optimize(struct LP *lp, int *infeasible)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ABORT_IF(solstat != CPX_STAT_OPTIMAL
|
abort_if(solstat != CPX_STAT_OPTIMAL
|
||||||
&& solstat != CPX_STAT_OPTIMAL_INFEAS,
|
&& solstat != CPX_STAT_OPTIMAL_INFEAS,
|
||||||
"Invalid solution status");
|
"Invalid solution status");
|
||||||
}
|
}
|
||||||
@@ -149,7 +149,7 @@ int LP_get_obj_val(struct LP *lp, double *obj)
|
|||||||
int rval = 0;
|
int rval = 0;
|
||||||
|
|
||||||
rval = CPXgetobjval(lp->cplex_env, lp->cplex_lp, obj);
|
rval = CPXgetobjval(lp->cplex_env, lp->cplex_lp, obj);
|
||||||
ABORT_IF(rval, "CPXgetobjval failed\n");
|
abort_if(rval, "CPXgetobjval failed");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
return rval;
|
return rval;
|
||||||
@@ -160,10 +160,10 @@ int LP_get_x(struct LP *lp, double *x)
|
|||||||
int rval = 0;
|
int rval = 0;
|
||||||
|
|
||||||
int ncols = CPXgetnumcols(lp->cplex_env, lp->cplex_lp);
|
int ncols = CPXgetnumcols(lp->cplex_env, lp->cplex_lp);
|
||||||
ABORT_IF(!ncols, "No columns in LP\n");
|
abort_if(!ncols, "No columns in LP");
|
||||||
|
|
||||||
rval = CPXgetx(lp->cplex_env, lp->cplex_lp, x, 0, ncols - 1);
|
rval = CPXgetx(lp->cplex_env, lp->cplex_lp, x, 0, ncols - 1);
|
||||||
ABORT_IF(rval, "CPXgetx failed\n");
|
abort_if(rval, "CPXgetx failed");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
return rval;
|
return rval;
|
||||||
@@ -183,7 +183,7 @@ int LP_write(struct LP *lp, const char *fname)
|
|||||||
nambuf[MAX_NAME_LENGTH - 1] = '\0';
|
nambuf[MAX_NAME_LENGTH - 1] = '\0';
|
||||||
|
|
||||||
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\n");
|
abort_if(rval, "CPXwriteprob failed");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
return rval;
|
return rval;
|
||||||
|
|||||||
39
src/main.c
39
src/main.c
@@ -29,19 +29,19 @@ int main_tsp(int ac, char **av)
|
|||||||
struct TSPData data;
|
struct TSPData data;
|
||||||
|
|
||||||
rval = TSP_init_data(&data);
|
rval = TSP_init_data(&data);
|
||||||
ABORT_IF(rval, "TSP_init_data failed");
|
abort_if(rval, "TSP_init_data failed");
|
||||||
|
|
||||||
rval = BNC_init(&bnc);
|
rval = BNC_init(&bnc);
|
||||||
ABORT_IF(rval, "BNC_init failed");
|
abort_if(rval, "BNC_init failed");
|
||||||
|
|
||||||
rval = parse_arguments_tsp(ac, av);
|
rval = parse_arguments_tsp(ac, av);
|
||||||
ABORT_IF(rval, "Failed to parse arguments.\n");
|
abort_if(rval, "Failed to parse arguments.");
|
||||||
|
|
||||||
printf("Seed = %d\n", SEED);
|
printf("Seed = %d\n", SEED);
|
||||||
srand(SEED);
|
srand(SEED);
|
||||||
|
|
||||||
rval = TSP_read_problem(INPUT_FILENAME, &data);
|
rval = TSP_read_problem(INPUT_FILENAME, &data);
|
||||||
ABORT_IF(rval, "TSP_read_problem failed\n");
|
abort_if(rval, "TSP_read_problem failed");
|
||||||
|
|
||||||
bnc.best_obj_val = TSP_find_initial_solution(&data);
|
bnc.best_obj_val = TSP_find_initial_solution(&data);
|
||||||
bnc.problem_data = (void *) &data;
|
bnc.problem_data = (void *) &data;
|
||||||
@@ -50,13 +50,13 @@ int main_tsp(int ac, char **av)
|
|||||||
(int (*)(struct LP *, void *)) TSP_add_cutting_planes;
|
(int (*)(struct LP *, void *)) TSP_add_cutting_planes;
|
||||||
|
|
||||||
rval = BNC_init_lp(&bnc);
|
rval = BNC_init_lp(&bnc);
|
||||||
ABORT_IF(rval, "BNC_init_lp failed");
|
abort_if(rval, "BNC_init_lp failed");
|
||||||
|
|
||||||
rval = BNC_solve(&bnc);
|
rval = BNC_solve(&bnc);
|
||||||
ABORT_IF(rval, "BNC_solve_node failed\n");
|
abort_if(rval, "BNC_solve_node failed");
|
||||||
|
|
||||||
time_printf("Optimal integral solution:\n");
|
log_info("Optimal integral solution:\n");
|
||||||
time_printf(" obj value = %.2lf **\n", bnc.best_obj_val);
|
log_info(" obj value = %.2lf **\n", bnc.best_obj_val);
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
BNC_free(&bnc);
|
BNC_free(&bnc);
|
||||||
@@ -79,19 +79,19 @@ int main_gtsp(int ac, char **av)
|
|||||||
struct GTSP data;
|
struct GTSP data;
|
||||||
|
|
||||||
rval = GTSP_init_data(&data);
|
rval = GTSP_init_data(&data);
|
||||||
ABORT_IF(rval, "GTSP_init_data failed");
|
abort_if(rval, "GTSP_init_data failed");
|
||||||
|
|
||||||
rval = GTSP_create_random_problem(node_count, cluster_count, grid_size,
|
rval = GTSP_create_random_problem(node_count, cluster_count, grid_size,
|
||||||
&data);
|
&data);
|
||||||
ABORT_IF(rval, "GTSP_create_random_problem failed");
|
abort_if(rval, "GTSP_create_random_problem failed");
|
||||||
|
|
||||||
rval = GTSP_write_data(&data, "gtsp.in");
|
rval = GTSP_write_data(&data, "gtsp.in");
|
||||||
ABORT_IF(rval, "GTSP_write_problem failed\n");
|
abort_if(rval, "GTSP_write_problem failed");
|
||||||
|
|
||||||
rval = BNC_init(&bnc);
|
rval = BNC_init(&bnc);
|
||||||
ABORT_IF(rval, "BNC_init failed\n");
|
abort_if(rval, "BNC_init failed");
|
||||||
|
|
||||||
printf("Seed = %d\n", SEED);
|
log_info("Setting seed = %d\n", SEED);
|
||||||
srand(SEED);
|
srand(SEED);
|
||||||
|
|
||||||
bnc.best_obj_val = DBL_MAX;
|
bnc.best_obj_val = DBL_MAX;
|
||||||
@@ -99,16 +99,17 @@ int main_gtsp(int ac, char **av)
|
|||||||
bnc.problem_init_lp = (int (*)(struct LP *, void *)) GTSP_init_lp;
|
bnc.problem_init_lp = (int (*)(struct LP *, void *)) GTSP_init_lp;
|
||||||
|
|
||||||
rval = BNC_init_lp(&bnc);
|
rval = BNC_init_lp(&bnc);
|
||||||
ABORT_IF(rval, "BNC_init_lp failed\n");
|
abort_if(rval, "BNC_init_lp failed");
|
||||||
|
|
||||||
|
log_info("Starting branch-and-cut solver...\n");
|
||||||
rval = BNC_solve(&bnc);
|
rval = BNC_solve(&bnc);
|
||||||
ABORT_IF(rval, "BNC_solve_node failed\n");
|
abort_if(rval, "BNC_solve_node failed");
|
||||||
|
|
||||||
time_printf("Optimal integral solution:\n");
|
log_info("Optimal integral solution:\n");
|
||||||
time_printf(" obj value = %.2lf **\n", bnc.best_obj_val);
|
log_info(" obj value = %.2lf **\n", bnc.best_obj_val);
|
||||||
|
|
||||||
rval = GTSP_write_solution(&data, "gtsp.out", bnc.best_x);
|
rval = GTSP_write_solution(&data, "gtsp.out", bnc.best_x);
|
||||||
ABORT_IF(rval, "GTSP_write_solution failed");
|
abort_if(rval, "GTSP_write_solution failed");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
GTSP_free(&data);
|
GTSP_free(&data);
|
||||||
@@ -162,7 +163,7 @@ static int parse_arguments_tsp(int ac, char **av)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ABORT_IF(!INPUT_FILENAME && !NODE_COUNT_RAND,
|
abort_if(!INPUT_FILENAME && !NODE_COUNT_RAND,
|
||||||
"Must specify an input file or use -k for random problem\n");
|
"Must specify an input file or use -k for random problem\n");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
|
|||||||
52
src/tsp.c
52
src/tsp.c
@@ -35,7 +35,7 @@ int TSP_init_lp(struct LP *lp, struct TSPData *data)
|
|||||||
for (int i = 0; i < node_count; i++)
|
for (int i = 0; i < node_count; i++)
|
||||||
{
|
{
|
||||||
rval = LP_new_row(lp, 'E', 2.0);
|
rval = LP_new_row(lp, 'E', 2.0);
|
||||||
ABORT_IF(rval, "LP_new_row failed\n");
|
abort_if(rval, "LP_new_row failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build a column for each edge of the graph */
|
/* Build a column for each edge of the graph */
|
||||||
@@ -51,7 +51,7 @@ int TSP_init_lp(struct LP *lp, struct TSPData *data)
|
|||||||
rval = LP_add_cols(lp, 1, 2, &obj, &cmatbeg, cmatind, cmatval, &lb,
|
rval = LP_add_cols(lp, 1, 2, &obj, &cmatbeg, cmatind, cmatval, &lb,
|
||||||
&ub);
|
&ub);
|
||||||
|
|
||||||
ABORT_IF(rval, "LP_add_cols failed\n");
|
abort_if(rval, "LP_add_cols failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
@@ -80,31 +80,31 @@ int TSP_find_violated_subtour_elimination_cut(
|
|||||||
graph_init(&G);
|
graph_init(&G);
|
||||||
|
|
||||||
rval = LP_optimize(lp, &is_infeasible);
|
rval = LP_optimize(lp, &is_infeasible);
|
||||||
ABORT_IF(rval, "LP_optimize failed\n");
|
abort_if(rval, "LP_optimize failed");
|
||||||
ABORT_IF(is_infeasible, "LP is infeasible\n");
|
abort_if(is_infeasible, "LP is infeasible");
|
||||||
|
|
||||||
rval = graph_build(ncount, edge_count, edges, &G);
|
rval = graph_build(ncount, edge_count, edges, &G);
|
||||||
ABORT_IF(rval, "graph_build failed\n");
|
abort_if(rval, "graph_build failed");
|
||||||
|
|
||||||
x = (double *) malloc(edge_count * sizeof(double));
|
x = (double *) malloc(edge_count * sizeof(double));
|
||||||
delta = (int *) malloc(edge_count * sizeof(int));
|
delta = (int *) malloc(edge_count * sizeof(int));
|
||||||
marks = (int *) malloc(ncount * sizeof(int));
|
marks = (int *) malloc(ncount * sizeof(int));
|
||||||
ABORT_IF(!x, "Could not allocate memory for x");
|
abort_if(!x, "Could not allocate memory for x");
|
||||||
ABORT_IF(!delta, "Could not allocate memory for delta");
|
abort_if(!delta, "Could not allocate memory for delta");
|
||||||
ABORT_IF(!marks, "Could not allocate memory for marks");
|
abort_if(!marks, "Could not allocate memory for marks");
|
||||||
|
|
||||||
island_nodes = (int *) malloc(ncount * sizeof(int));
|
island_nodes = (int *) malloc(ncount * sizeof(int));
|
||||||
island_start = (int *) malloc(ncount * sizeof(int));
|
island_start = (int *) malloc(ncount * sizeof(int));
|
||||||
island_sizes = (int *) malloc(ncount * sizeof(int));
|
island_sizes = (int *) malloc(ncount * sizeof(int));
|
||||||
ABORT_IF(!island_nodes, "Could not allocate memory for island_nodes");
|
abort_if(!island_nodes, "Could not allocate memory for island_nodes");
|
||||||
ABORT_IF(!island_start, "Could not allocate memory for island_start");
|
abort_if(!island_start, "Could not allocate memory for island_start");
|
||||||
ABORT_IF(!island_sizes, "Could not allocate memory for island_sizes");
|
abort_if(!island_sizes, "Could not allocate memory for island_sizes");
|
||||||
|
|
||||||
for (int i = 0; i < ncount; i++)
|
for (int i = 0; i < ncount; i++)
|
||||||
marks[i] = 0;
|
marks[i] = 0;
|
||||||
|
|
||||||
rval = LP_get_x(lp, x);
|
rval = LP_get_x(lp, x);
|
||||||
ABORT_IF(rval, "LP_get_x failed\n");
|
abort_if(rval, "LP_get_x failed");
|
||||||
|
|
||||||
int round = 0;
|
int round = 0;
|
||||||
int delta_count = 0;
|
int delta_count = 0;
|
||||||
@@ -113,7 +113,7 @@ int TSP_find_violated_subtour_elimination_cut(
|
|||||||
while (!TSP_is_graph_connected(&G, x, &island_count, island_sizes,
|
while (!TSP_is_graph_connected(&G, x, &island_count, island_sizes,
|
||||||
island_start, island_nodes))
|
island_start, island_nodes))
|
||||||
{
|
{
|
||||||
time_printf("Adding %d BNC_solve_node inequalities...\n", island_count);
|
log_verbose("Adding %d BNC_solve_node inequalities...\n", island_count);
|
||||||
for (int i = 0; i < island_count; i++)
|
for (int i = 0; i < island_count; i++)
|
||||||
{
|
{
|
||||||
get_delta(island_sizes[i], island_nodes + island_start[i],
|
get_delta(island_sizes[i], island_nodes + island_start[i],
|
||||||
@@ -122,23 +122,23 @@ int TSP_find_violated_subtour_elimination_cut(
|
|||||||
rval = TSP_add_subtour_elimination_cut(lp, delta_count, delta);
|
rval = TSP_add_subtour_elimination_cut(lp, delta_count, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
time_printf("Reoptimizing (round %d)...\n", ++round);
|
log_verbose("Reoptimizing (round %d)...\n", ++round);
|
||||||
ABORT_IF(rval, "TSP_add_subtour_elimination_cut failed");
|
abort_if(rval, "TSP_add_subtour_elimination_cut failed");
|
||||||
|
|
||||||
rval = LP_optimize(lp, &is_infeasible);
|
rval = LP_optimize(lp, &is_infeasible);
|
||||||
ABORT_IF(rval, "LP_optimize failed\n");
|
abort_if(rval, "LP_optimize failed");
|
||||||
|
|
||||||
if(is_infeasible) goto CLEANUP;
|
if(is_infeasible) goto CLEANUP;
|
||||||
|
|
||||||
double objval = 0;
|
double objval = 0;
|
||||||
rval = LP_get_obj_val(lp, &objval);
|
rval = LP_get_obj_val(lp, &objval);
|
||||||
ABORT_IF(rval, "LP_get_obj_val failed\n");
|
abort_if(rval, "LP_get_obj_val failed");
|
||||||
|
|
||||||
rval = LP_get_x(lp, x);
|
rval = LP_get_x(lp, x);
|
||||||
ABORT_IF(rval, "LP_get_x failed\n");
|
abort_if(rval, "LP_get_x failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
time_printf(" graph is connected\n");
|
log_verbose(" graph is connected\n");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
graph_free(&G);
|
graph_free(&G);
|
||||||
@@ -160,7 +160,7 @@ int TSP_add_subtour_elimination_cut(struct LP *lp, int delta_length, int *delta)
|
|||||||
int *rmatind = delta;
|
int *rmatind = delta;
|
||||||
|
|
||||||
rmatval = (double *) malloc(delta_length * sizeof(double));
|
rmatval = (double *) malloc(delta_length * sizeof(double));
|
||||||
ABORT_IF(!rmatval, "out of memory for rmatval\n");
|
abort_if(!rmatval, "out of memory for rmatval");
|
||||||
|
|
||||||
for (int i = 0; i < delta_length; i++)
|
for (int i = 0; i < delta_length; i++)
|
||||||
rmatval[i] = 1.0;
|
rmatval[i] = 1.0;
|
||||||
@@ -168,7 +168,7 @@ int TSP_add_subtour_elimination_cut(struct LP *lp, int delta_length, int *delta)
|
|||||||
rval = LP_add_rows(lp, 1, delta_length, &rhs, &sense, &rmatbeg, rmatind,
|
rval = LP_add_rows(lp, 1, delta_length, &rhs, &sense, &rmatbeg, rmatind,
|
||||||
rmatval);
|
rmatval);
|
||||||
|
|
||||||
ABORT_IF(rval, "LP_add_rows failed");
|
abort_if(rval, "LP_add_rows failed");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
if (rmatval) free(rmatval);
|
if (rmatval) free(rmatval);
|
||||||
@@ -225,7 +225,7 @@ int TSP_find_closest_neighbor_tour(
|
|||||||
graph_init(&G);
|
graph_init(&G);
|
||||||
|
|
||||||
rval = graph_build(node_count, edge_count, edges, &G);
|
rval = graph_build(node_count, edge_count, edges, &G);
|
||||||
ABORT_IF(rval, "graph_build failed\n");
|
abort_if(rval, "graph_build failed");
|
||||||
|
|
||||||
for (int j = 0; j < node_count; j++)
|
for (int j = 0; j < node_count; j++)
|
||||||
G.node_list[j].mark = 0;
|
G.node_list[j].mark = 0;
|
||||||
@@ -380,7 +380,7 @@ int TSP_read_problem(char *filename, struct TSPData *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
edge_count = (node_count * (node_count - 1)) / 2;
|
edge_count = (node_count * (node_count - 1)) / 2;
|
||||||
time_printf("Complete graph: %d nodes, %d edges\n", node_count,
|
log_verbose("Complete graph: %d nodes, %d edges\n", node_count,
|
||||||
edge_count);
|
edge_count);
|
||||||
|
|
||||||
edge_list = (int *) malloc(2 * edge_count * sizeof(int));
|
edge_list = (int *) malloc(2 * edge_count * sizeof(int));
|
||||||
@@ -429,7 +429,7 @@ int TSP_add_cutting_planes(struct LP *lp, struct TSPData *data)
|
|||||||
int rval = 0;
|
int rval = 0;
|
||||||
|
|
||||||
rval = TSP_find_violated_subtour_elimination_cut(lp, data);
|
rval = TSP_find_violated_subtour_elimination_cut(lp, data);
|
||||||
ABORT_IF (rval, "TSP_find_violated_subtour_elimination_cut failed\n");
|
abort_if (rval, "TSP_find_violated_subtour_elimination_cut failed\n");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
return rval;
|
return rval;
|
||||||
@@ -439,7 +439,7 @@ double TSP_find_initial_solution(struct TSPData *data)
|
|||||||
{
|
{
|
||||||
double best_val = 1e99;
|
double best_val = 1e99;
|
||||||
|
|
||||||
time_printf("Finding closest neighbor tour\n");
|
log_verbose("Finding closest neighbor tour\n");
|
||||||
for (int i = 0; i < data->node_count; i++)
|
for (int i = 0; i < data->node_count; i++)
|
||||||
{
|
{
|
||||||
int path_length = 0;
|
int path_length = 0;
|
||||||
@@ -450,7 +450,7 @@ double TSP_find_initial_solution(struct TSPData *data)
|
|||||||
if (best_val > path_length) best_val = path_length;
|
if (best_val > path_length) best_val = path_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_printf(" length = %lf\n", best_val);
|
log_verbose(" length = %lf\n", best_val);
|
||||||
|
|
||||||
return best_val;
|
return best_val;
|
||||||
}
|
}
|
||||||
@@ -19,14 +19,14 @@ double get_real_time()
|
|||||||
return (double) time (0);
|
return (double) time (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static double initial_time = 0;
|
static double INITIAL_TIME = 0;
|
||||||
|
|
||||||
void time_printf(const char *fmt, ...)
|
void time_printf(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
if (initial_time == 0)
|
if (INITIAL_TIME == 0)
|
||||||
initial_time = get_current_time();
|
INITIAL_TIME = get_current_time();
|
||||||
|
|
||||||
printf("[%10.2lf] ", get_current_time() - initial_time);
|
printf("[%10.2lf] ", get_current_time() - INITIAL_TIME);
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
|||||||
47
src/util.h
47
src/util.h
@@ -1,15 +1,54 @@
|
|||||||
#ifndef _PROJECT_UTIL_H_
|
#ifndef _PROJECT_UTIL_H_
|
||||||
#define _PROJECT_UTIL_H_
|
#define _PROJECT_UTIL_H_
|
||||||
|
|
||||||
#define ABORT_IF(cond, msg) if(cond) { \
|
#define LOG_LEVEL_ERROR 10
|
||||||
fprintf(stderr, msg); rval = 1; goto CLEANUP; }
|
#define LOG_LEVEL_WARNING 20
|
||||||
|
#define LOG_LEVEL_INFO 30
|
||||||
|
#define LOG_LEVEL_DEBUG 40
|
||||||
|
#define LOG_LEVEL_VERBOSE 50
|
||||||
|
|
||||||
|
#define LOG_LEVEL LOG_LEVEL_INFO
|
||||||
|
|
||||||
|
#if LOG_LEVEL < LOG_LEVEL_DEBUG
|
||||||
|
#define log_verbose(...)
|
||||||
|
#else
|
||||||
|
#define log_verbose(...) time_printf( __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LOG_LEVEL < LOG_LEVEL_VERBOSE
|
||||||
|
#define log_verbose(...)
|
||||||
|
#else
|
||||||
|
#define log_verbose(...) time_printf( __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LOG_LEVEL < LOG_LEVEL_INFO
|
||||||
|
#define log_info(...)
|
||||||
|
#else
|
||||||
|
#define log_info(...) time_printf( __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LOG_LEVEL < LOG_LEVEL_WARNING
|
||||||
|
#define log_warn(...)
|
||||||
|
#else
|
||||||
|
#define log_warn(...) time_printf( __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LOG_LEVEL < LOG_LEVEL_ERROR
|
||||||
|
#define log_error(...)
|
||||||
|
#else
|
||||||
|
#define log_error(...) time_printf( __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define abort_if(cond, msg) if(cond) { \
|
||||||
|
fprintf(stderr, "%20s:%d " msg "\n", __FILE__, __LINE__); \
|
||||||
|
rval = 1; goto CLEANUP; }
|
||||||
|
|
||||||
|
void time_printf(const char *fmt, ...);
|
||||||
|
|
||||||
double get_current_time(void);
|
double get_current_time(void);
|
||||||
|
|
||||||
double get_real_time();
|
double get_real_time();
|
||||||
|
|
||||||
void time_printf(const char *fmt, ...);
|
|
||||||
|
|
||||||
void next_set(int sz, int *set);
|
void next_set(int sz, int *set);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user