Implement max flow algorithm

master
Alinson S. Xavier 11 years ago
parent 42f96fd01e
commit 91a2731d35

@ -0,0 +1,154 @@
#include <malloc.h>
#include <float.h>
#include "gtsp.h"
#include "flow.h"
#include "util.h"
int flow_find_max_flow(
const struct Graph *digraph,
const double *capacities,
struct Node *from,
struct Node *to,
double *flow,
double *value)
{
int rval = 0;
int path_length;
struct Edge **path_edges = 0;
double path_capacity;
double *residual_caps = 0;
residual_caps = (double *) malloc(digraph->edge_count * sizeof(double));
abort_if(!residual_caps, "could not allocate residual_caps");
path_edges = (struct Edge **) malloc(
digraph->edge_count * sizeof(struct Edge *));
abort_if(!path_edges, "could not allocate path_edges");
for (int i = 0; i < digraph->edge_count; i++)
{
flow[i] = 0;
residual_caps[i] = capacities[i];
abort_if(!digraph->edges[i].reverse,
"digraph must have reverse edge information");
}
*value = 0;
while (1)
{
flow_find_augmenting_path(digraph, residual_caps, from, to,
&path_length, path_edges, &path_capacity);
if (path_length == 0) break;
(*value) += path_capacity;
for (int i = 0; i < path_length; i++)
{
struct Edge *e = &digraph->edges[path_edges[i]->index];
residual_caps[e->index] -= path_capacity;
residual_caps[e->reverse->index] += path_capacity;
flow[e->index] += path_capacity;
flow[e->reverse->index] -= path_capacity;
}
}
CLEANUP:
if (path_edges) free(path_edges);
if (residual_caps) free(residual_caps);
return rval;
}
int flow_find_augmenting_path(
const struct Graph *graph,
const double *residual_caps,
struct Node *from,
struct Node *to,
int *path_length,
struct Edge **path_edges,
double *path_capacity)
{
int rval = 0;
struct Node **queue = 0;
int queue_start = 0;
int queue_end = 0;
struct Node **parents = 0;
struct Edge **parent_edges = 0;
int node_count = graph->node_count;
queue = (struct Node **) malloc(node_count * sizeof(struct Node *));
parents = (struct Node **) malloc(node_count * sizeof(struct Node *));
parent_edges = (struct Edge **) malloc(node_count * sizeof(struct Edge *));
abort_if(!queue, "could not allocate queue");
abort_if(!parents, "could not allocate parents");
abort_if(!parent_edges, "could not allocate parent_edges");
for (int i = 0; i < node_count; i++)
graph->nodes[i].mark = 0;
int found = 0;
queue[queue_end++] = from;
while (queue_end > queue_start)
{
struct Node *n = queue[queue_start++];
n->mark = 2;
for (int i = 0; i < n->degree; i++)
{
struct Node *neighbor = n->adj[i].neighbor;
struct Edge *edge = n->adj[i].edge;
if (neighbor->mark > 0) continue;
if (residual_caps[edge->index] < LP_EPSILON) continue;
parents[neighbor->index] = n;
parent_edges[neighbor->index] = edge;
queue[queue_end++] = neighbor;
neighbor->mark = 1;
if (neighbor == to)
{
found = 1;
break;
}
}
if (found) break;
}
*path_length = 0;
*path_capacity = DBL_MAX;
if (queue_end == queue_start) goto CLEANUP;
struct Node *n = to;
while (n != from)
{
struct Edge *edge = parent_edges[n->index];
path_edges[*path_length] = edge;
double c = residual_caps[edge->index];
if (c < *path_capacity) *path_capacity = c;
n = parents[n->index];
(*path_length)++;
}
CLEANUP:
if (parents) free(parents);
if (parent_edges) free(parent_edges);
if (queue) free(queue);
return rval;
}

@ -0,0 +1,27 @@
//
// Created by isoron on 19/03/15.
//
#ifndef _PROJECT_FLOW_H_
#define _PROJECT_FLOW_H_
int flow_find_augmenting_path(
const struct Graph *graph,
const double *residual_caps,
struct Node *from,
struct Node *to,
int *path_length,
struct Edge **path_edges,
double *path_capacity);
int flow_find_max_flow(
const struct Graph *digraph,
const double *capacities,
struct Node *from,
struct Node *to,
double *flow,
double *value);
#include "graph.h"
#endif //_PROJECT_FLOW_H_

@ -1,106 +1,162 @@
#include <malloc.h> #include <malloc.h>
#include "main.h"
#include "graph.h" #include "graph.h"
#include "util.h" #include "util.h"
#include "lp.h" #include "lp.h"
void graph_dfs( void graph_init(struct Graph *graph)
int n, struct Graph *G, double *x, int *island_size, int *island_nodes)
{ {
*(island_nodes + (*island_size)) = n; if (!graph) return;
(*island_size)++;
struct Node *pn = &G->node_list[n]; graph->nodes = 0;
pn->mark = 1; graph->adj = 0;
graph->node_count = 0;
for (int i = 0; i < pn->deg; i++) graph->edge_count = 0;
{
if (x[pn->adj[i].e] > LP_EPSILON)
{
int neighbor = pn->adj[i].n;
if (G->node_list[neighbor].mark == 0)
graph_dfs(neighbor, G, x, island_size, island_nodes);
}
}
} }
void graph_init(struct Graph *G) void graph_free(struct Graph *graph)
{ {
if (!G) return; if (!graph) return;
G->node_list = 0; if (graph->nodes) free(graph->nodes);
G->adj_space = 0; if (graph->adj) free(graph->adj);
G->node_count = 0;
G->edge_count = 0;
} }
void graph_free(struct Graph *G) int graph_build(
{ int node_count,
if (!G) return; int edge_count,
int *edges,
if (G->node_list) free(G->node_list); int is_directed,
if (G->adj_space) free(G->adj_space); struct Graph *graph)
}
int graph_build(int node_count, int edge_count, int *edge_list, struct Graph *G)
{ {
int rval = 0; int rval = 0;
struct Node *n; struct Node *n;
struct AdjObj *p; struct Adjacency *p;
G->node_list = (struct Node *) malloc(node_count * sizeof(struct Node)); graph->edges = (struct Edge *) malloc(edge_count * sizeof(struct Edge));
G->adj_space = graph->nodes = (struct Node *) malloc(node_count * sizeof(struct Node));
(struct AdjObj *) malloc(2 * edge_count * sizeof(struct AdjObj)); graph->adj = (struct Adjacency *) malloc(
2 * edge_count * sizeof(struct Adjacency));
abort_if(!G->node_list, "could not allocate G->node_list"); abort_if(!graph->edges, "could not allocate G->edges\n");
abort_if(!G->adj_space, "could not allocate G->adj_space"); abort_if(!graph->nodes, "could not allocate G->nodes");
abort_if(!graph->adj, "could not allocate G->adj");
for (int i = 0; i < node_count; i++) for (int i = 0; i < node_count; i++)
G->node_list[i].deg = 0; {
graph->nodes[i].index = i;
graph->nodes[i].degree = 0;
}
for (int i = 0; i < edge_count; i++) for (int i = 0; i < edge_count; i++)
{ {
int a = edge_list[2 * i]; int a = edges[2 * i];
int b = edge_list[2 * i + 1]; int b = edges[2 * i + 1];
G->node_list[a].deg++; graph->nodes[a].degree++;
G->node_list[b].deg++; if(!is_directed) graph->nodes[b].degree++;
graph->edges[i].reverse = 0;
graph->edges[i].index = i;
graph->edges[i].from = &graph->nodes[a];
graph->edges[i].to = &graph->nodes[b];
} }
p = G->adj_space; p = graph->adj;
for (int i = 0; i < node_count; i++) for (int i = 0; i < node_count; i++)
{ {
G->node_list[i].adj = p; graph->nodes[i].adj = p;
p += G->node_list[i].deg; p += graph->nodes[i].degree;
G->node_list[i].deg = 0; graph->nodes[i].degree = 0;
} }
for (int i = 0; i < edge_count; i++) for (int i = 0; i < edge_count; i++)
{ {
int a = edge_list[2 * i]; int a = edges[2 * i];
int b = edge_list[2 * i + 1]; int b = edges[2 * i + 1];
n = &G->node_list[a];
n->adj[n->deg].n = b; n = &graph->nodes[a];
n->adj[n->deg].e = i; n->adj[n->degree].neighbor_index = b;
n->deg++; n->adj[n->degree].edge_index = i;
n = &G->node_list[b]; n->adj[n->degree].neighbor = &graph->nodes[b];
n->adj[n->deg].n = a; n->adj[n->degree].edge = &graph->edges[i];
n->adj[n->deg].e = i; n->degree++;
n->deg++;
if(!is_directed)
{
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[b];
n->adj[n->degree].edge = &graph->edges[i];
n->degree++;
}
} }
G->node_count = node_count; graph->node_count = node_count;
G->edge_count = edge_count; graph->edge_count = edge_count;
CLEANUP: CLEANUP:
if (rval) if (rval)
{ {
if (G->node_list) free(G->node_list); if (graph->edges) free(graph->edges);
if (G->adj_space) free(G->adj_space); if (graph->nodes) free(graph->nodes);
if (graph->adj) free(graph->adj);
} }
return rval; return rval;
} }
void graph_dfs(
int n, struct Graph *G, double *x, int *island_size, int *island_nodes)
{
*(island_nodes + (*island_size)) = n;
(*island_size)++;
struct Node *pn = &G->nodes[n];
pn->mark = 1;
for (int i = 0; i < pn->degree; i++)
{
if (x[pn->adj[i].edge_index] > LP_EPSILON)
{
int neighbor = pn->adj[i].neighbor_index;
if (G->nodes[neighbor].mark == 0)
graph_dfs(neighbor, G, x, island_size, island_nodes);
}
}
}
int graph_build_directed_from_undirected(
const struct Graph *graph, struct Graph *digraph)
{
int rval = 0;
int *edges = 0;
edges = (int *) malloc(4 * graph->edge_count * sizeof(int));
abort_if(!edges, "could not allocate edges");
for (int i = 0; i < graph->edge_count; i++)
{
struct Edge *e = &graph->edges[i];
edges[4 * i] = edges[4 * i + 3] = e->from->index;
edges[4 * i + 1] = edges[4 * i + 2] = e->to->index;
}
rval = graph_build(graph->node_count, 2 * graph->edge_count, edges, 1,
digraph);
abort_if(rval, "graph_build failed");
for (int i = 0; i < graph->edge_count; i++)
{
digraph->edges[2 * i].reverse = &digraph->edges[i * 2 + 1];
digraph->edges[2 * i + 1].reverse = &digraph->edges[i * 2];
}
CLEANUP:
if (!edges) free(edges);
return rval;
}
void get_delta( void get_delta(
int island_node_count, int island_node_count,
int *island_nodes, int *island_nodes,
@ -122,4 +178,4 @@ void get_delta(
for (int i = 0; i < island_node_count; i++) for (int i = 0; i < island_node_count; i++)
marks[island_nodes[i]] = 0; marks[island_nodes[i]] = 0;
} }

@ -3,39 +3,60 @@
#include "main.h" #include "main.h"
struct AdjObj struct Adjacency
{ {
/* Index of neighbor node */ int edge_index;
int n; int neighbor_index;
/* Index of adj joining neighbor */ struct Edge *edge;
int e; struct Node *neighbor;
}; };
struct Node struct Node
{ {
int deg;
struct AdjObj *adj;
int mark; int mark;
int index;
int degree;
struct Adjacency *adj;
};
struct Edge
{
int index;
int weight;
struct Node *from;
struct Node *to;
struct Edge *reverse;
}; };
struct Graph struct Graph
{ {
int node_count; int node_count;
int edge_count; int edge_count;
struct Node *node_list;
struct AdjObj *adj_space; struct Edge *edges;
struct Node *nodes;
struct Adjacency *adj;
}; };
void graph_dfs( void graph_dfs(
int n, struct Graph *G, double *x, int *icount, int *island); int n, struct Graph *G, double *x, int *icount, int *island);
void graph_init(struct Graph *G); void graph_init(struct Graph *graph);
void graph_free(struct Graph *G); void graph_free(struct Graph *graph);
int graph_build int graph_build(
(int node_count, int edge_count, int *edge_list, struct Graph *G); int node_count,
int edge_count,
int *edges,
int is_directed,
struct Graph *graph);
void get_delta( void get_delta(
int nsize, int nsize,
@ -46,4 +67,7 @@ void get_delta(
int *delta, int *delta,
int *marks); int *marks);
int graph_build_directed_from_undirected
(const struct Graph *graph, struct Graph *digraph);
#endif #endif

@ -6,20 +6,19 @@
int GTSP_init_data(struct GTSP *data) int GTSP_init_data(struct GTSP *data)
{ {
data->node_count = 0;
data->edge_count = 0;
data->edges = 0;
data->clusters = 0; data->clusters = 0;
data->cluster_count = 0; data->cluster_count = 0;
data->x_coordinates = 0; data->x_coordinates = 0;
data->y_coordinates = 0; data->y_coordinates = 0;
graph_init(data->graph);
return 0; return 0;
} }
void GTSP_free(struct GTSP *data) void GTSP_free(struct GTSP *data)
{ {
if (!data) return; if (!data) return;
if (data->edges) free(data->edges); if (data->graph) graph_free(data->graph);
if (data->clusters) free(data->clusters); if (data->clusters) free(data->clusters);
if (data->x_coordinates) free(data->x_coordinates); if (data->x_coordinates) free(data->x_coordinates);
if (data->y_coordinates) free(data->y_coordinates); if (data->y_coordinates) free(data->y_coordinates);
@ -30,21 +29,33 @@ int GTSP_create_random_problem(
{ {
int rval = 0; int rval = 0;
struct Edge *edges = 0; int *edges = 0;
int *weights = 0;
int *clusters = 0; int *clusters = 0;
double *x_coords = 0; double *x_coords = 0;
double *y_coords = 0; double *y_coords = 0;
struct Graph *graph = 0;
int edge_count = (node_count * (node_count - 1)) / 2; int edge_count = (node_count * (node_count - 1)) / 2;
edges = (struct Edge *) malloc(edge_count * sizeof(struct Edge)); graph = (struct Graph*) malloc(sizeof(struct Graph));
abort_if(!graph, "could not allocate graph\n");
graph_init(graph);
edges = (int *) malloc(2 * edge_count * sizeof(int));
weights = (int *) malloc(edge_count * sizeof(int));
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(!weights, "could not allocate weights\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");
@ -52,21 +63,22 @@ int GTSP_create_random_problem(
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 curr_edge = 0;
for (int i = 0; i < edge_count; i++) for (int i = 0; i < edge_count; i++)
for (int j = i + 1; j < node_count; j++) for (int j = i + 1; j < node_count; j++)
{ {
edges[current_edge].from = i; edges[curr_edge * 2] = i;
edges[current_edge].to = j; edges[curr_edge * 2 + 1] = j;
edges[current_edge].weight = weights[curr_edge] =
get_euclidean_distance(x_coords, y_coords, i, j); get_euclidean_distance(x_coords, y_coords, i, j);
current_edge++; curr_edge++;
} }
data->node_count = node_count; rval = graph_build(node_count, edge_count, edges, 0, graph);
data->edge_count = edge_count; abort_if(rval, "graph_build failed");
data->edges = edges;
data->graph = graph;
data->clusters = clusters; data->clusters = clusters;
data->cluster_count = cluster_count; data->cluster_count = cluster_count;
data->x_coordinates = x_coords; data->x_coordinates = x_coords;
@ -85,11 +97,11 @@ int GTSP_init_lp(struct LP *lp, struct GTSP *data)
{ {
int rval = 0; int rval = 0;
int node_count = data->node_count; int node_count = data->graph->node_count;
int edge_count = data->edge_count; int edge_count = data->graph->edge_count;
int cluster_count = data->cluster_count; int cluster_count = data->cluster_count;
int *clusters = data->clusters; int *clusters = data->clusters;
struct Edge *edges = data->edges; struct Edge *edges = data->graph->edges;
for (int i = 0; i < node_count; i++) for (int i = 0; i < node_count; i++)
{ {
@ -122,7 +134,7 @@ int GTSP_init_lp(struct LP *lp, struct GTSP *data)
{ {
double obj = (double) edges[i].weight; double obj = (double) edges[i].weight;
double cmatval[] = {1.0, 1.0}; double cmatval[] = {1.0, 1.0};
int cmatind[] = {edges[i].from, edges[i].to}; int cmatind[] = {edges[i].from->index, edges[i].to->index};
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);
@ -142,9 +154,9 @@ int GTSP_write_data(struct GTSP *data, char *filename)
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->graph->node_count, data->cluster_count);
for (int i = 0; i < data->node_count; i++) for (int i = 0; i < data->graph->node_count; i++)
{ {
fprintf(file, "%.2lf %.2lf %d\n", data->x_coordinates[i], fprintf(file, "%.2lf %.2lf %d\n", data->x_coordinates[i],
data->y_coordinates[i], data->clusters[i]); data->y_coordinates[i], data->clusters[i]);
@ -159,25 +171,27 @@ int GTSP_write_solution(struct GTSP *data, char *filename, double *x)
{ {
int rval = 0; int rval = 0;
struct Edge *edges = data->edges; struct Edge *edges = data->graph->edges;
int node_count = data->node_count; int node_count = data->graph->node_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");
int positive_edge_count = 0; int positive_edge_count = 0;
for (int i = 0; i < data->edge_count; i++) for (int i = 0; i < edge_count; i++)
if (x[i + node_count] > 0.5) if (x[i + node_count] > 0.5)
positive_edge_count++; positive_edge_count++;
fprintf(file, "%d\n", positive_edge_count); fprintf(file, "%d\n", positive_edge_count);
for (int i = 0; i < data->edge_count; i++) for (int i = 0; i < edge_count; i++)
if (x[i + node_count] > 0.5) if (x[i + node_count] > 0.5)
fprintf(file, "%d %d\n", edges[i].from, edges[i].to); fprintf(file, "%d %d\n", edges[i].from->index, edges[i].to->index);
CLEANUP: CLEANUP:
if (file) fclose(file); if (file) fclose(file);
return rval; return rval;
} }

@ -6,19 +6,11 @@
#define _PROJECT_GTSP_H_ #define _PROJECT_GTSP_H_
#include "lp.h" #include "lp.h"
#include "graph.h"
struct Edge
{
int from;
int to;
int weight;
};
struct GTSP struct GTSP
{ {
int node_count; struct Graph *graph;
int edge_count;
struct Edge *edges;
int *clusters; int *clusters;
int cluster_count; int cluster_count;

@ -8,6 +8,7 @@
#include "tsp.h" #include "tsp.h"
#include "branch_and_cut.h" #include "branch_and_cut.h"
#include "gtsp.h" #include "gtsp.h"
#include "flow.h"
char *INPUT_FILENAME = 0; char *INPUT_FILENAME = 0;
unsigned int SEED = 0; unsigned int SEED = 0;
@ -19,6 +20,79 @@ static int parse_arguments_tsp(int ac, char **av);
static void print_usage_tsp(char *f); static void print_usage_tsp(char *f);
int test_max_flow()
{
int rval = 0;
int *edges = 0;
double *capacities = 0;
double *flow = 0;
double flow_value;
FILE *f = fopen("tmp/flow.in", "r");
abort_if(!f, "could not open input file");
struct Graph graph;
graph_init(&graph);
int node_count, edge_count;
rval = fscanf(f, "%d %d ", &node_count, &edge_count);
abort_if(rval != 2, "invalid input format");
edges = (int *) malloc(4 * edge_count * sizeof(int));
abort_if(!edges, "could not allocate edges\n");
capacities = (double *) malloc(2 * edge_count * sizeof(double));
abort_if(!capacities, "could not allocate capacities");
for (int i = 0; i < edge_count; i++)
{
int from, to, cap;
rval = fscanf(f, "%d %d %d ", &from, &to, &cap);
abort_if(rval != 3, "invalid input format");
edges[i*4] = edges[i*4+3] = from;
edges[i*4+1] = edges[i*4 + 2] = to;
capacities[2 * i] = cap;
capacities[2 * i + 1] = 0;
}
rval = graph_build(node_count, 2 * edge_count, edges, 1, &graph);
abort_if(rval, "graph_build failed");
for (int i = 0; i < edge_count; i++)
{
graph.edges[2*i].reverse = &graph.edges[2*i+1];
graph.edges[2*i+1].reverse = &graph.edges[2*i];
}
flow = (double *) malloc(graph.edge_count * sizeof(double));
abort_if(!flow, "could not allocate flow");
struct Node *from = &graph.nodes[0];
struct Node *to = &graph.nodes[graph.node_count - 1];
rval = flow_find_max_flow(&graph, capacities, from, to, flow, &flow_value);
abort_if(rval, "flow_find_max_flow failed");
log_info("Optimal flow has value %f\n", flow_value);
for (int i = 0; i < graph.edge_count; i++)
{
struct Edge *e = &graph.edges[i];
if(flow[e->index] <= 0) continue;
log_info(" %d %d %6.2f / %6.2f\n", e->from->index, e->to->index, flow[e->index], capacities[e->index]);
}
CLEANUP:
if (capacities) free(capacities);
if (edges) free(edges);
if (flow) free(flow);
return rval;
}
int main_tsp(int ac, char **av) int main_tsp(int ac, char **av)
{ {
int rval = 0; int rval = 0;
@ -172,7 +246,8 @@ static int parse_arguments_tsp(int ac, char **av)
int main(int ac, char **av) int main(int ac, char **av)
{ {
return main_gtsp(ac, av); return test_max_flow();
// return main_gtsp(ac, av);
// return main_tsp(ac, av); // return main_tsp(ac, av);
} }

@ -38,7 +38,7 @@ int TSP_init_lp(struct LP *lp, struct TSPData *data)
abort_if(rval, "LP_new_row failed"); abort_if(rval, "LP_new_row failed");
} }
/* Build a column for each edge of the graph */ /* Build a column for each edge_index of the graph */
double lb = 0.0; double lb = 0.0;
double ub = 1.0; double ub = 1.0;
int cmatbeg = 0; int cmatbeg = 0;
@ -83,7 +83,7 @@ int TSP_find_violated_subtour_elimination_cut(
abort_if(rval, "LP_optimize failed"); abort_if(rval, "LP_optimize failed");
abort_if(is_infeasible, "LP is infeasible"); abort_if(is_infeasible, "LP is infeasible");
rval = graph_build(ncount, edge_count, edges, &G); rval = graph_build(ncount, edge_count, edges, 0, &G);
abort_if(rval, "graph_build failed"); abort_if(rval, "graph_build failed");
x = (double *) malloc(edge_count * sizeof(double)); x = (double *) malloc(edge_count * sizeof(double));
@ -185,7 +185,7 @@ int TSP_is_graph_connected(
{ {
for (int i = 0; i < G->node_count; i++) for (int i = 0; i < G->node_count; i++)
{ {
G->node_list[i].mark = 0; G->nodes[i].mark = 0;
island_nodes[i] = -1; island_nodes[i] = -1;
} }
@ -193,7 +193,7 @@ int TSP_is_graph_connected(
for (int i = 0; i < G->node_count; i++) for (int i = 0; i < G->node_count; i++)
{ {
if (G->node_list[i].mark != 0) continue; if (G->nodes[i].mark != 0) continue;
island_sizes[current_island] = 0; island_sizes[current_island] = 0;
@ -224,29 +224,29 @@ int TSP_find_closest_neighbor_tour(
struct Graph G; struct Graph G;
graph_init(&G); graph_init(&G);
rval = graph_build(node_count, edge_count, edges, &G); rval = graph_build(node_count, edge_count, edges, 0, &G);
abort_if(rval, "graph_build failed"); 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.nodes[j].mark = 0;
for (int j = 0; j < node_count; j++) for (int j = 0; j < node_count; j++)
{ {
if (j == node_count - 1) if (j == node_count - 1)
G.node_list[start].mark = 0; G.nodes[start].mark = 0;
struct Node *pn = &G.node_list[current_node]; struct Node *pn = &G.nodes[current_node];
pn->mark = 1; pn->mark = 1;
int closest_neighbor = -1; int closest_neighbor = -1;
int closest_edge_length = 10000000; int closest_edge_length = 10000000;
for (int i = 0; i < pn->deg; i++) for (int i = 0; i < pn->degree; i++)
{ {
int edge = pn->adj[i].e; int edge = pn->adj[i].edge_index;
int neighbor = pn->adj[i].n; int neighbor = pn->adj[i].neighbor_index;
if (G.node_list[neighbor].mark == 1) continue; if (G.nodes[neighbor].mark == 1) continue;
if (elen[edge] > closest_edge_length) continue; if (elen[edge] > closest_edge_length) continue;
closest_neighbor = neighbor; closest_neighbor = neighbor;
@ -439,7 +439,7 @@ double TSP_find_initial_solution(struct TSPData *data)
{ {
double best_val = 1e99; double best_val = 1e99;
log_verbose("Finding closest neighbor tour\n"); log_verbose("Finding closest neighbor_index 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;