Extract method to build flow digraph
This commit is contained in:
113
src/gtsp.c
113
src/gtsp.c
@@ -385,56 +385,26 @@ int GTSP_add_subtour_elimination_cut_3(
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GTSP_find_exact_subtour_elimination_cuts(
|
int GTSP_build_flow_digraph(struct GTSP *data, double *x, struct Graph *digraph, double *capacities)
|
||||||
struct LP *lp, struct GTSP *data, int *added_cuts_count)
|
|
||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
|
|
||||||
int *clusters = data->clusters;
|
|
||||||
|
|
||||||
double *x = 0;
|
|
||||||
double *capacities = 0;
|
|
||||||
|
|
||||||
double *flow = 0;
|
|
||||||
struct Edge **cut_edges = 0;
|
|
||||||
|
|
||||||
int *digraph_edges = 0;
|
int *digraph_edges = 0;
|
||||||
|
|
||||||
struct Graph *graph = data->graph;
|
struct Graph *graph = data->graph;
|
||||||
|
|
||||||
int node_count = graph->node_count;
|
int node_count = graph->node_count;
|
||||||
|
|
||||||
int num_cols = LP_get_num_cols(lp);
|
|
||||||
x = (double *) malloc(num_cols * sizeof(double));
|
|
||||||
abort_if(!x, "could not allocate x");
|
|
||||||
|
|
||||||
rval = LP_get_x(lp, x);
|
|
||||||
abort_if(rval, "LP_get_x failed");
|
|
||||||
|
|
||||||
struct Graph digraph;
|
|
||||||
graph_init(&digraph);
|
|
||||||
|
|
||||||
int digraph_edge_count = 4 * graph->edge_count + 2 * graph->node_count +
|
int digraph_edge_count = 4 * graph->edge_count + 2 * graph->node_count +
|
||||||
2 * data->cluster_count;
|
2 * data->cluster_count;
|
||||||
int digraph_node_count = node_count + data->cluster_count + 1;
|
int digraph_node_count = node_count + data->cluster_count + 1;
|
||||||
|
|
||||||
digraph_edges = (int *) malloc(2 * digraph_edge_count * sizeof(int));
|
digraph_edges = (int *) malloc(2 * digraph_edge_count * sizeof(int));
|
||||||
flow = (double *) malloc(digraph_edge_count * sizeof(double));
|
|
||||||
capacities = (double *) malloc(digraph_edge_count * sizeof(double));
|
|
||||||
cut_edges =
|
|
||||||
(struct Edge **) malloc(digraph_edge_count * sizeof(struct Edge *));
|
|
||||||
|
|
||||||
abort_if(!digraph_edges, "could not allocate digraph_edges");
|
|
||||||
abort_if(!flow, "could not allocate flow");
|
|
||||||
abort_if(!capacities, "could not allocate capacities");
|
|
||||||
abort_if(!cut_edges, "could not allocate cut_edges");
|
|
||||||
|
|
||||||
// Create four directed edges for each edge of the original graph
|
// Create four directed edges for each edge of the original graph
|
||||||
int ke = 0;
|
int ke = 0;
|
||||||
int kc = 0;
|
int kc = 0;
|
||||||
for (int i = 0; i < graph->edge_count; i++)
|
for (int i = 0; i < graph->edge_count; i++)
|
||||||
{
|
{
|
||||||
assert(node_count + i < num_cols);
|
|
||||||
|
|
||||||
struct Edge *e = &graph->edges[i];
|
struct Edge *e = &graph->edges[i];
|
||||||
int from = e->from->index;
|
int from = e->from->index;
|
||||||
int to = e->to->index;
|
int to = e->to->index;
|
||||||
@@ -489,30 +459,78 @@ int GTSP_find_exact_subtour_elimination_cuts(
|
|||||||
assert(kc == digraph_edge_count);
|
assert(kc == digraph_edge_count);
|
||||||
|
|
||||||
rval = graph_build(digraph_node_count, digraph_edge_count, digraph_edges, 1,
|
rval = graph_build(digraph_node_count, digraph_edge_count, digraph_edges, 1,
|
||||||
&digraph);
|
digraph);
|
||||||
abort_if(rval, "graph_build failed");
|
abort_if(rval, "graph_build failed");
|
||||||
|
|
||||||
for (int i = 0; i < digraph_edge_count; i += 2)
|
for (int i = 0; i < digraph_edge_count; i += 2)
|
||||||
{
|
{
|
||||||
digraph.edges[i].reverse = &digraph.edges[i + 1];
|
digraph->edges[i].reverse = &digraph->edges[i + 1];
|
||||||
digraph.edges[i + 1].reverse = &digraph.edges[i];
|
digraph->edges[i + 1].reverse = &digraph->edges[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
int max_x_index = 0;
|
|
||||||
double max_x = DBL_MIN;
|
|
||||||
|
|
||||||
for (int i = 0; i < node_count; i++)
|
CLEANUP:
|
||||||
{
|
return rval;
|
||||||
struct Node *n = &graph->nodes[i];
|
}
|
||||||
if (x[n->index] > max_x)
|
|
||||||
{
|
int GTSP_find_exact_subtour_elimination_cuts(
|
||||||
max_x = x[n->index];
|
struct LP *lp, struct GTSP *data, int *added_cuts_count)
|
||||||
max_x_index = i;
|
{
|
||||||
}
|
int rval = 0;
|
||||||
}
|
|
||||||
|
double *x = 0;
|
||||||
|
double *flow = 0;
|
||||||
|
double *capacities = 0;
|
||||||
|
|
||||||
|
struct Edge **cut_edges = 0;
|
||||||
|
|
||||||
|
int *clusters = data->clusters;
|
||||||
|
struct Graph *graph = data->graph;
|
||||||
|
int node_count = graph->node_count;
|
||||||
|
|
||||||
|
|
||||||
|
int num_cols = LP_get_num_cols(lp);
|
||||||
|
x = (double *) malloc(num_cols * sizeof(double));
|
||||||
|
abort_if(!x, "could not allocate x");
|
||||||
|
|
||||||
|
rval = LP_get_x(lp, x);
|
||||||
|
abort_if(rval, "LP_get_x failed");
|
||||||
|
|
||||||
|
struct Graph digraph;
|
||||||
|
graph_init(&digraph);
|
||||||
|
|
||||||
|
int digraph_edge_count = 4 * graph->edge_count + 2 * graph->node_count +
|
||||||
|
2 * data->cluster_count;
|
||||||
|
|
||||||
|
flow = (double *) malloc(digraph_edge_count * sizeof(double));
|
||||||
|
capacities = (double *) malloc(digraph_edge_count * sizeof(double));
|
||||||
|
cut_edges =
|
||||||
|
(struct Edge **) malloc(digraph_edge_count * sizeof(struct Edge *));
|
||||||
|
|
||||||
|
abort_if(!flow, "could not allocate flow");
|
||||||
|
abort_if(!capacities, "could not allocate capacities");
|
||||||
|
abort_if(!cut_edges, "could not allocate cut_edges");
|
||||||
|
|
||||||
|
|
||||||
|
rval = GTSP_build_flow_digraph(data, x, &digraph, capacities);
|
||||||
|
abort_if(rval, "GTSP_build_flow_digraph failed");
|
||||||
|
|
||||||
|
|
||||||
// Constraints (2.3)
|
// Constraints (2.3)
|
||||||
{
|
{
|
||||||
|
int max_x_index = 0;
|
||||||
|
double max_x = DBL_MIN;
|
||||||
|
|
||||||
|
for (int i = 0; i < node_count; i++)
|
||||||
|
{
|
||||||
|
struct Node *n = &graph->nodes[i];
|
||||||
|
if (x[n->index] > max_x)
|
||||||
|
{
|
||||||
|
max_x = x[n->index];
|
||||||
|
max_x_index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int i = max_x_index;
|
int i = max_x_index;
|
||||||
|
|
||||||
for (int j = 0; j < node_count; j++)
|
for (int j = 0; j < node_count; j++)
|
||||||
@@ -681,7 +699,7 @@ int GTSP_find_exact_subtour_elimination_cuts(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// subcluster
|
// subcluster
|
||||||
struct Node *root = &digraph.nodes[digraph_node_count - 1];
|
struct Node *root = &digraph.nodes[digraph.node_count - 1];
|
||||||
for (int e_index = 0; e_index < graph->edge_count; e_index++)
|
for (int e_index = 0; e_index < graph->edge_count; e_index++)
|
||||||
{
|
{
|
||||||
struct Edge *e = &graph->edges[e_index];
|
struct Edge *e = &graph->edges[e_index];
|
||||||
@@ -821,7 +839,6 @@ int GTSP_find_exact_subtour_elimination_cuts(
|
|||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
graph_free(&digraph);
|
graph_free(&digraph);
|
||||||
if (digraph_edges) free(digraph_edges);
|
|
||||||
if (flow) free(flow);
|
if (flow) free(flow);
|
||||||
if (cut_edges) free(cut_edges);
|
if (cut_edges) free(cut_edges);
|
||||||
if (capacities) free(capacities);
|
if (capacities) free(capacities);
|
||||||
|
|||||||
Reference in New Issue
Block a user