From e04edbe7ef0672ab2ab78eec76552d6c87fc8958 Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Thu, 26 Mar 2015 07:39:58 -0400 Subject: [PATCH] Remove subcluster cuts --- src/gtsp.c | 216 +++-------------------------------------------------- 1 file changed, 10 insertions(+), 206 deletions(-) diff --git a/src/gtsp.c b/src/gtsp.c index 6944fbc..0ad364a 100644 --- a/src/gtsp.c +++ b/src/gtsp.c @@ -178,60 +178,6 @@ int GTSP_init_lp(struct LP *lp, struct GTSP *data) return rval; } -static int add_subcluster_cut( - struct LP *lp, - struct Graph *graph, - struct Edge *e, - struct Edge **cut_edges, - int cut_edges_count) -{ - int rval = 0; - - char sense = 'G'; - double rhs = 0.0; - int newnz = cut_edges_count + 1; - - int rmatbeg = 0; - int *rmatind = 0; - double *rmatval = 0; - - rmatind = (int *) malloc(newnz * sizeof(int)); - abort_if(!rmatind, "could not allocate rmatind"); - - rmatval = (double *) malloc(newnz * sizeof(double)); - abort_if(!rmatval, "could not allocate rmatval"); - - for (int i = 0; i < cut_edges_count; i++) - { - rmatind[i] = cut_edges[i]->index + graph->node_count; - rmatval[i] = 1.0; - } - - rmatind[cut_edges_count] = graph->node_count + e->index; - rmatval[cut_edges_count] = -1.0; - - log_debug("Generated cut:\n"); - for (int i = 0; i < newnz; i++) - log_debug("%8.2f x%d\n", rmatval[i], rmatind[i]); - log_debug(" %c %.2lf\n", sense, rhs); - - if (OPTIMAL_X) - { - double sum = 0; - for (int i = 0; i < newnz; i++) - sum += rmatval[i] * OPTIMAL_X[rmatind[i]]; - abort_if(sum <= rhs - LP_EPSILON, "cannot add invalid cut"); - } - - rval = LP_add_rows(lp, 1, newnz, &rhs, &sense, &rmatbeg, rmatind, rmatval); - abort_if(rval, "LP_add_rows failed"); - - CLEANUP: - if (rmatval) free(rmatval); - if (rmatind) free(rmatind); - return rval; -} - static int add_subtour_cut( struct LP *lp, struct Graph *graph, @@ -366,7 +312,7 @@ static int build_flow_digraph( capacities[kc++] = 0; } - // Create an extra node and connect it to each cluster node through + // Create an extra root node and connect it to each cluster node through // some edge with zero capacity for (int i = 0; i < data->cluster_count; i++) { @@ -400,10 +346,9 @@ static int build_flow_digraph( } static int map_cut_edges_from_digraph_to_graph( - struct Graph *graph, - struct Edge **edge_map, - int *cut_edges_count, - struct Edge **cut_edges) + struct Edge **edge_map, + int *cut_edges_count, + struct Edge **cut_edges) { int count = 0; @@ -495,13 +440,11 @@ int find_exact_subtour_cuts_cluster_to_cluster( if (flow_value >= 2 - LP_EPSILON) continue; -// log_debug("Flow from cluster %d to %d is insufficient\n", i, j); - rval = get_cut_edges_from_marks(digraph, &cut_edges_count, cut_edges); abort_if(rval, "get_cut_edges_from_marks failed"); - rval = map_cut_edges_from_digraph_to_graph(graph, edge_map, + rval = map_cut_edges_from_digraph_to_graph(edge_map, &cut_edges_count, cut_edges); abort_if(rval, "map_cut_edges_from_digraph_to_graph failed"); @@ -576,7 +519,7 @@ int find_exact_subtour_cuts_node_to_cluster( cut_edges); abort_if(rval, "get_cut_edges_from_marks failed"); - rval = map_cut_edges_from_digraph_to_graph(graph, edge_map, + rval = map_cut_edges_from_digraph_to_graph(edge_map, &cut_edges_count, cut_edges); abort_if(rval, "map_cut_edges_from_digraph_to_graph failed"); @@ -656,8 +599,8 @@ int find_exact_subtour_cuts_node_to_node( rval = get_cut_edges_from_marks(digraph, &cut_edges_count, cut_edges); abort_if(rval, "get_cut_edges_from_marks failed"); - rval = map_cut_edges_from_digraph_to_graph(graph, edge_map, - &cut_edges_count, cut_edges); + rval = map_cut_edges_from_digraph_to_graph(edge_map, &cut_edges_count, + cut_edges); abort_if(rval, "map_cut_edges_from_digraph_to_graph failed"); rval = add_subtour_cut(lp, graph, from, to, cut_edges, cut_edges_count, @@ -738,145 +681,6 @@ int find_exact_subtour_cuts( log_debug("Added %d node-to-node subtour cuts\n", added_cuts_count); (*total_added_cuts) += added_cuts_count; -// // subcluster -// struct Node *root = &digraph.nodes[digraph.node_count - 1]; -// for (int e_index = 0; e_index < graph->edge_count; e_index++) -// { -// struct Edge *e = &graph->edges[e_index]; -// double x_e = x[node_count + e_index]; -// if (x_e < LP_EPSILON) continue; -// -// struct Node *from = &digraph.nodes[e->from->index]; -// struct Node *to = &digraph.nodes[e->to->index]; -// -// if (x[from->index] > 1 - LP_EPSILON && x[to->index] > 1 - LP_EPSILON) -// continue; -// -// capacities[4 * e_index] = capacities[4 * e_index + 2] = 0; -// -// int cluster_from_index = data->clusters[from->index]; -// int cluster_to_index = data->clusters[to->index]; -// -// for (int k = 0; k < data->cluster_count; k++) -// { -// if (cluster_from_index == k) continue; -// if (cluster_to_index == k) continue; -// -// int offset = 4 * graph->edge_count + 2 * node_count + 2 * k; -// capacities[offset] = 1e10; -// capacities[offset + 1] = 1e10; -// } -// -// for (int k = 0; k < graph->node_count; k++) -// { -// struct Node *n = &graph->nodes[k]; -// if (clusters[n->index] != cluster_from_index && -// clusters[n->index] != cluster_to_index) -// continue; -// -// int offset = 4 * graph->edge_count + 2 * k; -// capacities[offset] = 0; -// capacities[offset + 1] = 0; -// } -// -// // First direction -// log_debug("Calculating max flow from (%d,%d) to root\n", from->index, -// to->index); -// double flow_value; -// rval = flow_find_max_flow(&digraph, capacities, from, root, flow, -// &flow_value); -// abort_if(rval, "flow_find_max_flow failed"); -// -// log_debug(" %.2lf\n", flow_value); -// -// if (flow_value + LP_EPSILON < x_e) -// { -// log_debug("violation: %.2lf > %.2lf\n", flow_value, x_e); -// -// int cut_edges_count; -// rval = get_cut_edges_from_marks(&digraph, &cut_edges_count, -// cut_edges); -// abort_if(rval, "get_cut_edges_from_marks failed"); -// -// log_debug("Adding cut for i=%d j=root, cut edges:\n", from->index); -// int c = 0; -// for (int k = 0; k < cut_edges_count / 2; k++) -// { -// int idx = cut_edges[k * 2]->index / 4; -// if (idx == e_index) continue; -// if (idx >= graph->edge_count) continue; -// -// cut_edges[c++] = &graph->edges[idx]; -// log_debug(" %d %d\n", cut_edges[c - 1]->from->index, -// cut_edges[c - 1]->to->index); -// } -// -// rval = add_subcluster_cut(lp, graph, e, cut_edges, c); -// abort_if(rval, "add_subcluster_cut failed"); -// -// (*total_added_cuts)++; -// if (*total_added_cuts > 10) goto CLEANUP; -// -// } else -// { -// // Reverse direction -// log_debug("Trying reverse edge:\n", to->index, from->index); -// -// rval = flow_find_max_flow(&digraph, capacities, to, root, flow, -// &flow_value); -// abort_if(rval, "flow_find_max_flow failed"); -// -// log_debug(" %.2lf\n", flow_value); -// -// if (flow_value + LP_EPSILON < x_e) -// { -// log_debug("violation: %.2lf > %.2lf\n", flow_value, x_e); -// -// int cut_edges_count; -// rval = get_cut_edges_from_marks(&digraph, &cut_edges_count, -// cut_edges); -// abort_if(rval, "get_cut_edges_from_marks failed"); -// -// log_debug("Adding cut for i=%d j=root, cut edges:\n", -// from->index); -// int c = 0; -// for (int k = 0; k < cut_edges_count / 2; k++) -// { -// int idx = cut_edges[k * 2]->index / 4; -// if (idx == e_index) continue; -// if (idx >= graph->edge_count) continue; -// -// cut_edges[c++] = &graph->edges[idx]; -// log_debug(" %d %d\n", cut_edges[c - 1]->from->index, -// cut_edges[c - 1]->to->index); -// } -// -// rval = add_subcluster_cut(lp, graph, e, cut_edges, c); -// abort_if(rval, "add_subcluster_cut failed"); -// -// (*total_added_cuts)++; -// if (*total_added_cuts > 10) goto CLEANUP; -// } -// } -// -// capacities[4 * e_index] = x_e; -// capacities[4 * e_index + 2] = x_e; -// -// for (int k = 0; k < graph->node_count; k++) -// { -// int offset = 4 * graph->edge_count + 2 * k; -// capacities[offset] = 1e10; -// capacities[offset + 1] = 1e10; -// } -// -// for (int k = 0; k < data->cluster_count; k++) -// { -// int offset = 4 * graph->edge_count + 2 * graph->node_count; -// capacities[offset + 2 * k] = 0; -// capacities[offset + 2 * k + 1] = 0; -// } -// } - CLEANUP: graph_free(&digraph); if (edge_map) free(edge_map); @@ -1108,7 +912,7 @@ int GTSP_solution_found(struct GTSP *data, double *x) { int rval = 0; - log_info("Writting solution to file gtsp.out\n"); + log_info("Writting integral solution to file gtsp.out\n"); rval = GTSP_write_solution(data, "gtsp.out", x); abort_if(rval, "GTSP_write_solution failed"); @@ -1196,4 +1000,4 @@ int GTSP_main(int argc, char **argv) GTSP_free(&data); BNC_free(&bnc); return rval; -} \ No newline at end of file +}