Unify code style and rename some variables
This commit is contained in:
@@ -248,10 +248,10 @@ int re_optimize_integral(struct BNC *bnc){
|
|||||||
int node_count = data->graph->node_count;
|
int node_count = data->graph->node_count;
|
||||||
int cluster_count = data->cluster_count;
|
int cluster_count = data->cluster_count;
|
||||||
int edge_count = data->graph->edge_count;
|
int edge_count = data->graph->edge_count;
|
||||||
struct TOUR * tour = (struct TOUR*) NULL;
|
struct Tour * tour = (struct Tour*) NULL;
|
||||||
|
|
||||||
//intialize the tour
|
//intialize the tour
|
||||||
tour = (struct TOUR *) malloc( cluster_count * sizeof(struct TOUR));
|
tour = (struct Tour *) malloc( cluster_count * sizeof(struct Tour));
|
||||||
for (i = 0; i < edge_count; i++){
|
for (i = 0; i < edge_count; i++){
|
||||||
tour[i].vertex = -1;
|
tour[i].vertex = -1;
|
||||||
tour[i].next = -1;
|
tour[i].next = -1;
|
||||||
@@ -312,20 +312,20 @@ int optimize_vertex_in_cluster(struct BNC *bnc, double best_val)
|
|||||||
|
|
||||||
//reoptmizing the your with two-opt
|
//reoptmizing the your with two-opt
|
||||||
//rval = two_opt(cluster_count, tour, data->dist_matrix);
|
//rval = two_opt(cluster_count, tour, data->dist_matrix);
|
||||||
//Optimizing the vertices inside the clusters
|
//Optimizing the vertices inside the node_to_cluster
|
||||||
int current_cluster = 0;
|
int current_cluster = 0;
|
||||||
int insertion_cost = 0;
|
int insertion_cost = 0;
|
||||||
|
|
||||||
//printf(" o-- val = %.2lf **\n", best_val);
|
//printf(" o-- val = %.2lf **\n", best_val);
|
||||||
for(i = 1; i < cluster_count - 2; i++){
|
for(i = 1; i < cluster_count - 2; i++){
|
||||||
//printf(" vertex in tour = %d **\n", tour[current_vertex]);
|
//printf(" vertex in tour = %d **\n", tour[current_vertex]);
|
||||||
current_cluster = data->clusters[tour[i]];
|
current_cluster = data->node_to_cluster[tour[i]];
|
||||||
//printf(" o-- val = %.2lf **\n", best_val);
|
//printf(" o-- val = %.2lf **\n", best_val);
|
||||||
insertion_cost = data->dist_matrix[tour[i-1]][tour[i]] +
|
insertion_cost = data->dist_matrix[tour[i-1]][tour[i]] +
|
||||||
data->dist_matrix[tour[i]][tour[i+1]];
|
data->dist_matrix[tour[i]][tour[i+1]];
|
||||||
//printf(" o-- val = %.2lf **\n", best_val);
|
//printf(" o-- val = %.2lf **\n", best_val);
|
||||||
for(j = 0; j < node_count; j++)
|
for(j = 0; j < node_count; j++)
|
||||||
if (current_cluster == data->clusters[j])
|
if (current_cluster == data->node_to_cluster[j])
|
||||||
if (insertion_cost > data->dist_matrix[j][tour[i]] +
|
if (insertion_cost > data->dist_matrix[j][tour[i]] +
|
||||||
data->dist_matrix[j][tour[i+1]]){
|
data->dist_matrix[j][tour[i+1]]){
|
||||||
log_info("Optmize vertex in cluster improved the bound\n");
|
log_info("Optmize vertex in cluster improved the bound\n");
|
||||||
|
|||||||
@@ -3,12 +3,6 @@
|
|||||||
|
|
||||||
#include "lp.h"
|
#include "lp.h"
|
||||||
|
|
||||||
struct TOUR {
|
|
||||||
int vertex;
|
|
||||||
int next;
|
|
||||||
int prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BNC
|
struct BNC
|
||||||
{
|
{
|
||||||
struct LP *lp;
|
struct LP *lp;
|
||||||
@@ -41,5 +35,4 @@ int re_optimize_integral(struct BNC *bnc);
|
|||||||
|
|
||||||
extern int BNC_NODE_COUNT;
|
extern int BNC_NODE_COUNT;
|
||||||
|
|
||||||
|
|
||||||
#endif //_PROJECT_BRANCH_AND_CUT_H_
|
#endif //_PROJECT_BRANCH_AND_CUT_H_
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ int add_comb_cut(
|
|||||||
// {
|
// {
|
||||||
// double val;
|
// double val;
|
||||||
// struct Node *n = &graph->nodes[i];
|
// struct Node *n = &graph->nodes[i];
|
||||||
// int c = clusters[n->index];
|
// int c = node_to_cluster[n->index];
|
||||||
//
|
//
|
||||||
// if (components[c] == current_component)
|
// if (components[c] == current_component)
|
||||||
// val = (teeth[c] < 0 ? 1.0 : 0.0);
|
// val = (teeth[c] < 0 ? 1.0 : 0.0);
|
||||||
@@ -273,7 +273,7 @@ static int shrink_clusters(
|
|||||||
double *y_coords = 0;
|
double *y_coords = 0;
|
||||||
int *cluster_sizes = 0;
|
int *cluster_sizes = 0;
|
||||||
|
|
||||||
const int *clusters = data->clusters;
|
const int *clusters = data->node_to_cluster;
|
||||||
const int cluster_count = data->cluster_count;
|
const int cluster_count = data->cluster_count;
|
||||||
const struct Graph *graph = data->graph;
|
const struct Graph *graph = data->graph;
|
||||||
|
|
||||||
@@ -429,7 +429,7 @@ int find_comb_cuts(struct LP *lp, struct GTSP *data)
|
|||||||
|
|
||||||
if (tooth_count % 2 == 0) continue;
|
if (tooth_count % 2 == 0) continue;
|
||||||
|
|
||||||
rval = add_comb_cut(lp, data->graph, i, data->clusters, components,
|
rval = add_comb_cut(lp, data->graph, i, data->node_to_cluster, components,
|
||||||
component_sizes, teeth, tooth_count, x);
|
component_sizes, teeth, tooth_count, x);
|
||||||
abort_if(rval, "add_comb_cut failed");
|
abort_if(rval, "add_comb_cut failed");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ int static build_flow_digraph(
|
|||||||
for (int i = 0; i < node_count; i++)
|
for (int i = 0; i < node_count; i++)
|
||||||
{
|
{
|
||||||
struct Node *n = &graph->nodes[i];
|
struct Node *n = &graph->nodes[i];
|
||||||
int cl = data->clusters[n->index];
|
int cl = data->node_to_cluster[n->index];
|
||||||
|
|
||||||
digraph_edges[ke++] = n->index;
|
digraph_edges[ke++] = n->index;
|
||||||
digraph_edges[ke++] = node_count + cl;
|
digraph_edges[ke++] = node_count + cl;
|
||||||
@@ -260,7 +260,7 @@ int find_exact_subtour_cuts_node_to_node(
|
|||||||
double *flow = 0;
|
double *flow = 0;
|
||||||
|
|
||||||
struct Graph *graph = data->graph;
|
struct Graph *graph = data->graph;
|
||||||
int *clusters = data->clusters;
|
int *clusters = data->node_to_cluster;
|
||||||
|
|
||||||
cut_edges = (struct Edge **) malloc(
|
cut_edges = (struct Edge **) malloc(
|
||||||
graph->edge_count * sizeof(struct Edge *));
|
graph->edge_count * sizeof(struct Edge *));
|
||||||
@@ -344,7 +344,7 @@ int find_exact_subtour_cuts_node_to_cluster(
|
|||||||
double *flow = 0;
|
double *flow = 0;
|
||||||
|
|
||||||
struct Graph *graph = data->graph;
|
struct Graph *graph = data->graph;
|
||||||
int *clusters = data->clusters;
|
int *clusters = data->node_to_cluster;
|
||||||
|
|
||||||
cut_edges = (struct Edge **) malloc(
|
cut_edges = (struct Edge **) malloc(
|
||||||
graph->edge_count * sizeof(struct Edge *));
|
graph->edge_count * sizeof(struct Edge *));
|
||||||
|
|||||||
295
src/gtsp.c
295
src/gtsp.c
@@ -1,13 +1,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <float.h>
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "gtsp.h"
|
#include "gtsp.h"
|
||||||
#include "geometry.h"
|
#include "geometry.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "flow.h"
|
#include "flow.h"
|
||||||
#include "branch_and_cut.h"
|
|
||||||
#include "gtsp-subtour.h"
|
#include "gtsp-subtour.h"
|
||||||
#include "gtsp-comb.h"
|
#include "gtsp-comb.h"
|
||||||
|
|
||||||
@@ -17,13 +15,13 @@ int GTSP_init_data(struct GTSP *data)
|
|||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
|
|
||||||
data->clusters = 0;
|
data->node_to_cluster = 0;
|
||||||
data->cluster_count = 0;
|
data->cluster_count = 0;
|
||||||
|
|
||||||
data->graph = (struct Graph *) malloc(sizeof(struct Graph));
|
data->graph = (struct Graph *) malloc(sizeof(struct Graph));
|
||||||
abort_if(!data->graph, "could not allocate data->graph");
|
abort_if(!data->graph, "could not allocate data->graph");
|
||||||
|
|
||||||
data->vertex_set = (struct CLUSTER *) malloc(sizeof(struct CLUSTER));
|
data->clusters = (struct Cluster *) malloc(sizeof(struct Cluster));
|
||||||
|
|
||||||
graph_init(data->graph);
|
graph_init(data->graph);
|
||||||
|
|
||||||
@@ -38,7 +36,7 @@ void GTSP_free(struct GTSP *data)
|
|||||||
graph_free(data->graph);
|
graph_free(data->graph);
|
||||||
free(data->graph);
|
free(data->graph);
|
||||||
|
|
||||||
if (data->clusters) free(data->clusters);
|
if (data->node_to_cluster) free(data->node_to_cluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
int GTSP_create_random_problem(
|
int GTSP_create_random_problem(
|
||||||
@@ -69,7 +67,7 @@ int GTSP_create_random_problem(
|
|||||||
abort_if(!data->graph, "could not allocate data->graph");
|
abort_if(!data->graph, "could not allocate data->graph");
|
||||||
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(!weights, "could not allocate weights\n");
|
||||||
abort_if(!clusters, "could not allocate clusters\n");
|
abort_if(!clusters, "could not allocate node_to_cluster\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));
|
||||||
@@ -82,38 +80,40 @@ abort_if(!data->graph, "could not allocate data->graph");
|
|||||||
dist_matrix[i] = (int *) malloc(node_count * sizeof(int));
|
dist_matrix[i] = (int *) malloc(node_count * sizeof(int));
|
||||||
abort_if(!dist_matrix, "could not allocate dist_matrix\n");
|
abort_if(!dist_matrix, "could not allocate dist_matrix\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");
|
||||||
|
|
||||||
rval = generate_dist_matrix(node_count,
|
rval = generate_dist_matrix(node_count, x_coords, y_coords, dist_matrix);
|
||||||
x_coords, y_coords, dist_matrix);
|
|
||||||
abort_if(rval, "generate_distance_matrix_2d failed");
|
abort_if(rval, "generate_distance_matrix_2d failed");
|
||||||
|
|
||||||
struct CLUSTER *cluster_member;
|
struct Cluster *cluster_member;
|
||||||
cluster_member = (struct CLUSTER *) malloc(cluster_count * sizeof(struct CLUSTER));
|
cluster_member = (struct Cluster *) malloc(
|
||||||
for (int j=0; j<cluster_count; j++){
|
cluster_count * sizeof(struct Cluster));
|
||||||
|
for (int j = 0; j < cluster_count; j++)
|
||||||
|
{
|
||||||
cluster_member[j].size = 0;
|
cluster_member[j].size = 0;
|
||||||
for (int i = 0; i < node_count; i++)
|
for (int i = 0; i < node_count; i++)
|
||||||
if (clusters[i] == j)
|
if (clusters[i] == j)
|
||||||
cluster_member[j].size += 1;
|
cluster_member[j].size += 1;
|
||||||
}
|
}
|
||||||
for (int j = 0; j < cluster_count; j++)
|
for (int j = 0; j < cluster_count; j++)
|
||||||
cluster_member[j].set = (int *) malloc(cluster_member[j].size * sizeof(int));
|
cluster_member[j].nodes = (int *) malloc(
|
||||||
|
cluster_member[j].size * sizeof(int));
|
||||||
|
|
||||||
int current_vertex = 0;
|
int current_vertex = 0;
|
||||||
for (int j=0; j<cluster_count; j++){
|
for (int j = 0; j < cluster_count; j++)
|
||||||
|
{
|
||||||
current_vertex = 0;
|
current_vertex = 0;
|
||||||
for (int i = 0; i < node_count; i++)
|
for (int i = 0; i < node_count; i++)
|
||||||
if(clusters[i] == j){
|
if (clusters[i] == j)
|
||||||
cluster_member[j].set[current_vertex] = i;
|
{
|
||||||
|
cluster_member[j].nodes[current_vertex] = i;
|
||||||
|
|
||||||
current_vertex += 1;
|
current_vertex += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int curr_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++)
|
||||||
@@ -138,12 +138,12 @@ abort_if(!data->graph, "could not allocate data->graph");
|
|||||||
graph->edges[i].weight = weights[i];
|
graph->edges[i].weight = weights[i];
|
||||||
|
|
||||||
data->graph = graph;
|
data->graph = graph;
|
||||||
data->clusters = clusters;
|
data->node_to_cluster = clusters;
|
||||||
data->cluster_count = cluster_count;
|
data->cluster_count = cluster_count;
|
||||||
graph->x_coordinates = x_coords;
|
graph->x_coordinates = x_coords;
|
||||||
graph->y_coordinates = y_coords;
|
graph->y_coordinates = y_coords;
|
||||||
data->dist_matrix = dist_matrix;
|
data->dist_matrix = dist_matrix;
|
||||||
data->vertex_set = cluster_member;
|
data->clusters = cluster_member;
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
if (weights) free(weights);
|
if (weights) free(weights);
|
||||||
@@ -162,7 +162,7 @@ int GTSP_init_lp(struct LP *lp, struct GTSP *data)
|
|||||||
int node_count = data->graph->node_count;
|
int node_count = data->graph->node_count;
|
||||||
int edge_count = data->graph->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->node_to_cluster;
|
||||||
struct Edge *edges = data->graph->edges;
|
struct Edge *edges = data->graph->edges;
|
||||||
|
|
||||||
for (int i = 0; i < node_count; i++)
|
for (int i = 0; i < node_count; i++)
|
||||||
@@ -273,7 +273,7 @@ int GTSP_write_problem(struct GTSP *data, char *filename)
|
|||||||
for (int i = 0; i < graph->node_count; i++)
|
for (int i = 0; i < graph->node_count; i++)
|
||||||
{
|
{
|
||||||
fprintf(file, "%.2lf %.2lf %d\n", graph->x_coordinates[i],
|
fprintf(file, "%.2lf %.2lf %d\n", graph->x_coordinates[i],
|
||||||
graph->y_coordinates[i], data->clusters[i]);
|
graph->y_coordinates[i], data->node_to_cluster[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
@@ -350,7 +350,7 @@ int GTSP_read_solution(struct GTSP *gtsp, char *filename, double **p_x)
|
|||||||
{
|
{
|
||||||
for (int j = i + 1; j < node_count; j++)
|
for (int j = i + 1; j < node_count; j++)
|
||||||
{
|
{
|
||||||
if (gtsp->clusters[i] == gtsp->clusters[j]) continue;
|
if (gtsp->node_to_cluster[i] == gtsp->node_to_cluster[j]) continue;
|
||||||
edge_map[i * node_count + j] = k;
|
edge_map[i * node_count + j] = k;
|
||||||
edge_map[j * node_count + i] = k;
|
edge_map[j * node_count + i] = k;
|
||||||
k++;
|
k++;
|
||||||
@@ -431,7 +431,7 @@ int GTSP_check_solution(struct GTSP *data, double *x)
|
|||||||
while (stack_top > 0)
|
while (stack_top > 0)
|
||||||
{
|
{
|
||||||
struct Node *n = stack[--stack_top];
|
struct Node *n = stack[--stack_top];
|
||||||
cluster_mark[data->clusters[n->index]]++;
|
cluster_mark[data->node_to_cluster[n->index]]++;
|
||||||
|
|
||||||
for (int i = 0; i < n->degree; i++)
|
for (int i = 0; i < n->degree; i++)
|
||||||
{
|
{
|
||||||
@@ -480,7 +480,7 @@ int GTSP_solution_found(struct GTSP *data, double *x)
|
|||||||
|
|
||||||
static const struct option options_tab[] = {{"help", no_argument, 0, 'h'},
|
static const struct option options_tab[] = {{"help", no_argument, 0, 'h'},
|
||||||
{"nodes", required_argument, 0, 'n'},
|
{"nodes", required_argument, 0, 'n'},
|
||||||
{"clusters", required_argument, 0, 'm'},
|
{"node_to_cluster", required_argument, 0, 'm'},
|
||||||
{"grid-size", required_argument, 0, 'g'},
|
{"grid-size", required_argument, 0, 'g'},
|
||||||
{"optimal", required_argument, 0, 'x'},
|
{"optimal", required_argument, 0, 'x'},
|
||||||
{"seed", required_argument, 0, 's'},
|
{"seed", required_argument, 0, 's'},
|
||||||
@@ -495,7 +495,7 @@ static void GTSP_print_usage()
|
|||||||
{
|
{
|
||||||
printf("Parameters:\n");
|
printf("Parameters:\n");
|
||||||
printf("%4s %-13s %s\n", "-n", "--nodes", "number of nodes");
|
printf("%4s %-13s %s\n", "-n", "--nodes", "number of nodes");
|
||||||
printf("%4s %-13s %s\n", "-m", "--clusters", "number of clusters");
|
printf("%4s %-13s %s\n", "-m", "--node_to_cluster", "number of node_to_cluster");
|
||||||
printf("%4s %-13s %s\n", "-s", "--seed", "random seed");
|
printf("%4s %-13s %s\n", "-s", "--seed", "random seed");
|
||||||
printf("%4s %-13s %s\n", "-g", "--grid-size",
|
printf("%4s %-13s %s\n", "-g", "--grid-size",
|
||||||
"size of the box used for generating random points");
|
"size of the box used for generating random points");
|
||||||
@@ -567,7 +567,7 @@ static int GTSP_parse_args(int argc, char **argv)
|
|||||||
|
|
||||||
if (input_cluster_count > input_node_count)
|
if (input_cluster_count > input_node_count)
|
||||||
{
|
{
|
||||||
printf("Number of clusters must be at most number of nodes.\n");
|
printf("Number of node_to_cluster must be at most number of nodes.\n");
|
||||||
rval = 1;
|
rval = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -615,9 +615,11 @@ int GTSP_main(int argc, char **argv)
|
|||||||
rval = GTSP_create_random_problem(input_node_count, input_cluster_count,
|
rval = GTSP_create_random_problem(input_node_count, input_cluster_count,
|
||||||
grid_size, &data);
|
grid_size, &data);
|
||||||
abort_if(rval, "GTSP_create_random_problem failed");
|
abort_if(rval, "GTSP_create_random_problem failed");
|
||||||
int init_val ;
|
|
||||||
|
|
||||||
init_val = inital_tour_value(&data);
|
int init_val;
|
||||||
|
rval = inital_tour_value(&data, &init_val);
|
||||||
|
abort_if(rval, "initial_tour_value failed");
|
||||||
|
|
||||||
log_info("Writing random instance to file gtsp.in\n");
|
log_info("Writing random instance to file gtsp.in\n");
|
||||||
rval = GTSP_write_problem(&data, "gtsp.in");
|
rval = GTSP_write_problem(&data, "gtsp.in");
|
||||||
|
|
||||||
@@ -708,86 +710,102 @@ int GTSP_main(int argc, char **argv)
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int inital_tour_value(struct GTSP *data)
|
int inital_tour_value(struct GTSP *data, int *tour_cost)
|
||||||
{
|
{
|
||||||
int cluster_count = data->cluster_count;
|
int rval = 0;
|
||||||
int * tour;
|
|
||||||
int * uncovered_sets;
|
|
||||||
int min_vertex = -1;
|
|
||||||
int min_cost = 100000000;
|
|
||||||
int tour_cost = 0;
|
|
||||||
|
|
||||||
int* cluster_in_tour;
|
int cluster_count = data->cluster_count;
|
||||||
cluster_in_tour = (int *) malloc(cluster_count*sizeof(int));
|
|
||||||
|
int *tour = 0;
|
||||||
|
int *uncovered_sets = 0;
|
||||||
|
int *cluster_in_tour = 0;
|
||||||
|
|
||||||
tour = (int *) malloc(cluster_count * sizeof(int));
|
tour = (int *) malloc(cluster_count * sizeof(int));
|
||||||
uncovered_sets = (int *) malloc((cluster_count - 1) * sizeof(int));
|
uncovered_sets = (int *) malloc((cluster_count - 1) * sizeof(int));
|
||||||
|
cluster_in_tour = (int *) malloc(cluster_count * sizeof(int));
|
||||||
|
abort_if(!tour, "could not allocate tour");
|
||||||
|
abort_if(!uncovered_sets, "could not allocate uncovered_sets");
|
||||||
|
abort_if(!cluster_in_tour, "could not allocate cluster_in_tour");
|
||||||
|
|
||||||
int cluster_num = 0;
|
int cluster_num = 0;
|
||||||
for(int i =0; i< cluster_count; i++){
|
for (int i = 0; i < cluster_count; i++)
|
||||||
|
{
|
||||||
cluster_in_tour[i] = 0;
|
cluster_in_tour[i] = 0;
|
||||||
if(data->clusters[0] != i){
|
if (data->node_to_cluster[0] != i)
|
||||||
|
{
|
||||||
uncovered_sets[cluster_num] = i;
|
uncovered_sets[cluster_num] = i;
|
||||||
cluster_num += 1;
|
cluster_num += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int new_vertex = 1;
|
int new_vertex = 1;
|
||||||
tour[0] = 0;
|
tour[0] = 0;
|
||||||
cluster_in_tour[0] = 1;
|
cluster_in_tour[0] = 1;
|
||||||
while(new_vertex <= data->cluster_count){
|
|
||||||
min_vertex = -1;
|
while (new_vertex <= data->cluster_count)
|
||||||
min_cost = 100000000;
|
{
|
||||||
for (int i = 1; i < data->graph->node_count; i++) {
|
int min_vertex = -1;
|
||||||
if (cluster_in_tour[data->clusters[i]] == 0){
|
int min_cost = INT_MAX;
|
||||||
for (int k = 0; k < new_vertex; k++) {
|
|
||||||
|
for (int i = 1; i < data->graph->node_count; i++)
|
||||||
|
{
|
||||||
|
if (!cluster_in_tour[data->node_to_cluster[i]])
|
||||||
|
{
|
||||||
|
for (int k = 0; k < new_vertex; k++)
|
||||||
|
{
|
||||||
int cost = data->dist_matrix[i][tour[k]];
|
int cost = data->dist_matrix[i][tour[k]];
|
||||||
if (cost < min_cost) {
|
if (cost < min_cost)
|
||||||
|
{
|
||||||
min_cost = cost;
|
min_cost = cost;
|
||||||
min_vertex = i;
|
min_vertex = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tour[new_vertex] = min_vertex;
|
tour[new_vertex] = min_vertex;
|
||||||
cluster_in_tour[data->clusters[min_vertex]] = 1;
|
cluster_in_tour[data->node_to_cluster[min_vertex]] = 1;
|
||||||
new_vertex += 1;
|
new_vertex += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rval = large_neighborhood_search(tour, data, tour_cost);
|
||||||
|
abort_if(rval, "large_neighborhood_search failed");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
tour_cost = Larg_neighborhood_search(tour, data);
|
|
||||||
//tour_cost = optimize_vertex_in_cluster(tour, data);
|
//tour_cost = optimize_vertex_in_cluster(tour, data);
|
||||||
log_info("Initial upper-bound: %d \n", tour_cost);
|
log_info("Initial upper-bound: %d \n", *tour_cost);
|
||||||
return tour_cost;
|
|
||||||
|
CLEANUP:
|
||||||
|
if (cluster_in_tour) free(cluster_in_tour);
|
||||||
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int optimize_vertex_in_cluster(struct Tour *tour, struct GTSP *data)
|
||||||
|
|
||||||
int optimize_vertex_in_cluster(struct TOUR * tour, struct GTSP *data)
|
|
||||||
{
|
{
|
||||||
int i = 0 , j, current_cluster, tour_cost;
|
int current_cluster;
|
||||||
int insertion_cost = 1000000;
|
int insertion_cost;
|
||||||
int rval = 0;
|
|
||||||
|
|
||||||
if(rval)
|
int **dist_matrix = data->dist_matrix;
|
||||||
printf("Larg_neighborhood_search stopped unexpectedly");
|
int cluster_count = data->cluster_count;
|
||||||
|
struct Cluster *vertex_set = data->clusters;
|
||||||
|
|
||||||
for(i = 0; i < data->cluster_count ; i++){
|
for (int i = 0; i < cluster_count; i++)
|
||||||
|
{
|
||||||
int vertex = tour[i].vertex;
|
int vertex = tour[i].vertex;
|
||||||
int prev_vertex = tour[tour[i].prev].vertex;
|
int prev_vertex = tour[tour[i].prev].vertex;
|
||||||
int next_vertex = tour[tour[i].next].vertex;
|
int next_vertex = tour[tour[i].next].vertex;
|
||||||
|
|
||||||
current_cluster = data->clusters[vertex];
|
current_cluster = data->node_to_cluster[vertex];
|
||||||
insertion_cost = data->dist_matrix[prev_vertex][vertex] +
|
|
||||||
data->dist_matrix[vertex][next_vertex];
|
|
||||||
|
|
||||||
for(j = 0; j < data->vertex_set[current_cluster].size; j++){
|
insertion_cost = dist_matrix[prev_vertex][vertex] +
|
||||||
int vertex_in_cluster = data->vertex_set[current_cluster].set[j];
|
dist_matrix[vertex][next_vertex];
|
||||||
int cost = data->dist_matrix[vertex_in_cluster][prev_vertex] +
|
|
||||||
data->dist_matrix[vertex_in_cluster][next_vertex];
|
for (int j = 0; j < vertex_set[current_cluster].size; j++)
|
||||||
if (insertion_cost > cost){
|
{
|
||||||
|
int vertex_in_cluster = vertex_set[current_cluster].nodes[j];
|
||||||
|
int cost = dist_matrix[vertex_in_cluster][prev_vertex] +
|
||||||
|
dist_matrix[vertex_in_cluster][next_vertex];
|
||||||
|
if (insertion_cost > cost)
|
||||||
|
{
|
||||||
insertion_cost = cost;
|
insertion_cost = cost;
|
||||||
tour[i].vertex = vertex_in_cluster;
|
tour[i].vertex = vertex_in_cluster;
|
||||||
}
|
}
|
||||||
@@ -797,21 +815,22 @@ int optimize_vertex_in_cluster(struct TOUR * tour, struct GTSP *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int two_opt(struct TOUR* tour, struct GTSP *data){
|
int two_opt(struct Tour *tour, struct GTSP *data)
|
||||||
|
{
|
||||||
|
int **dist_matrix = data->dist_matrix;
|
||||||
|
|
||||||
int rval = 0, i;
|
for (int i = 0; i < data->cluster_count; i++)
|
||||||
for (i = 0; i < data->cluster_count; i++){
|
{
|
||||||
int vertex1 = tour[i].vertex;
|
int v1 = tour[i].vertex;
|
||||||
int vertex2 = tour[tour[i].prev].vertex;
|
int v2 = tour[tour[i].prev].vertex;
|
||||||
int vertex3 = tour[tour[i].next].vertex;
|
int v3 = tour[tour[i].next].vertex;
|
||||||
int vertex4 = tour[tour[tour[i].next].next].vertex;
|
int v4 = tour[tour[tour[i].next].next].vertex;
|
||||||
|
|
||||||
int current_cost = data->dist_matrix[vertex2][vertex1] +
|
int current_cost = dist_matrix[v2][v1] + dist_matrix[v3][v4];
|
||||||
data->dist_matrix[vertex3][vertex4];
|
int temp_cost = dist_matrix[v2][v3] + dist_matrix[v1][v4];
|
||||||
|
|
||||||
int temp_cost = data->dist_matrix[vertex2][vertex3] +
|
if (current_cost > temp_cost)
|
||||||
data->dist_matrix[vertex1][vertex4];
|
{
|
||||||
if(current_cost > temp_cost){
|
|
||||||
int temp_next = tour[i].next;
|
int temp_next = tour[i].next;
|
||||||
int temp_prev = tour[i].prev;
|
int temp_prev = tour[i].prev;
|
||||||
|
|
||||||
@@ -827,8 +846,10 @@ int two_opt(struct TOUR* tour, struct GTSP *data){
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rval;
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
int K_opt(int* tour, struct GTSP *data){
|
int K_opt(int* tour, struct GTSP *data){
|
||||||
int rval = 0, i, k, I, j;
|
int rval = 0, i, k, I, j;
|
||||||
@@ -863,31 +884,39 @@ int K_opt(int* tour, struct GTSP *data){
|
|||||||
return rval;
|
return rval;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
int Larg_neighborhood_search(int* tour, struct GTSP *data){
|
int large_neighborhood_search(int *tour, struct GTSP *data, int *tour_cost)
|
||||||
int i, best_vertex, best_pose, tour_cost, rval;
|
{
|
||||||
struct TOUR *vertex_seq;
|
int rval = 0;
|
||||||
vertex_seq = (struct TOUR*) malloc(data->cluster_count*sizeof(struct TOUR));
|
struct Tour *vertex_seq = 0;
|
||||||
|
|
||||||
|
int cluster_count = data->cluster_count;
|
||||||
|
int *clusters = data->node_to_cluster;
|
||||||
|
int **dist_matrix = data->dist_matrix;
|
||||||
|
struct Cluster *vertex_set = data->clusters;
|
||||||
|
|
||||||
|
vertex_seq = (struct Tour *) malloc(cluster_count * sizeof(struct Tour));
|
||||||
|
abort_if(!vertex_seq, "could not allocate vertex_seq");
|
||||||
|
|
||||||
//Construct the list
|
//Construct the list
|
||||||
for(i = 0; i < data->cluster_count; i++){
|
for (int i = 0; i < cluster_count; i++)
|
||||||
|
{
|
||||||
vertex_seq[i].vertex = tour[i];
|
vertex_seq[i].vertex = tour[i];
|
||||||
if ( i == 0){
|
if (i == 0)
|
||||||
vertex_seq[i].prev = data->cluster_count-1;
|
vertex_seq[i].prev = cluster_count - 1;
|
||||||
}else{
|
else
|
||||||
vertex_seq[i].prev = i - 1;
|
vertex_seq[i].prev = i - 1;
|
||||||
}
|
|
||||||
if ( i == data->cluster_count-1){
|
if (i == cluster_count - 1)
|
||||||
vertex_seq[i].next = 0;
|
vertex_seq[i].next = 0;
|
||||||
}else{
|
else
|
||||||
vertex_seq[i].next = i + 1;
|
vertex_seq[i].next = i + 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//LNS starts
|
//LNS starts
|
||||||
for(int iter = 0; iter < 1000; iter++){
|
for (int iter = 0; iter < 1000; iter++)
|
||||||
|
{
|
||||||
//Delete a vertex
|
//Delete a vertex
|
||||||
int delete_vertex = rand()%(data->cluster_count - 1) + 1;
|
int delete_vertex = rand() % (cluster_count - 1) + 1;
|
||||||
|
|
||||||
int prev_vertex = vertex_seq[delete_vertex].prev;
|
int prev_vertex = vertex_seq[delete_vertex].prev;
|
||||||
int next_vertex = vertex_seq[delete_vertex].next;
|
int next_vertex = vertex_seq[delete_vertex].next;
|
||||||
@@ -895,24 +924,33 @@ int Larg_neighborhood_search(int* tour, struct GTSP *data){
|
|||||||
vertex_seq[prev_vertex].next = next_vertex;
|
vertex_seq[prev_vertex].next = next_vertex;
|
||||||
vertex_seq[next_vertex].prev = prev_vertex;
|
vertex_seq[next_vertex].prev = prev_vertex;
|
||||||
|
|
||||||
int cluster_to_insert = data->clusters[vertex_seq[delete_vertex].vertex];
|
int cluster_to_insert = clusters[vertex_seq[delete_vertex].vertex];
|
||||||
int min_cost = 10000000;
|
|
||||||
for(i =0 ; i < data->vertex_set[cluster_to_insert].size ; i++){
|
int best_pose;
|
||||||
int vertex_to_insert = data->vertex_set[cluster_to_insert].set[i];
|
int best_vertex;
|
||||||
|
int min_cost = INT_MAX;
|
||||||
|
|
||||||
|
for (int i = 0; i < vertex_set[cluster_to_insert].size; i++)
|
||||||
|
{
|
||||||
|
int vertex_to_insert = vertex_set[cluster_to_insert].nodes[i];
|
||||||
|
|
||||||
int next_edge = vertex_seq[0].next;
|
int next_edge = vertex_seq[0].next;
|
||||||
for(int j = 1; j < data->cluster_count ; j++){
|
for (int j = 1; j < cluster_count; j++)
|
||||||
|
{
|
||||||
int vertex1 = vertex_seq[next_edge].vertex;
|
int vertex1 = vertex_seq[next_edge].vertex;
|
||||||
int vertex2 = vertex_seq[vertex_seq[next_edge].next].vertex;
|
int vertex2 = vertex_seq[vertex_seq[next_edge].next].vertex;
|
||||||
|
|
||||||
int insert_cost = data->dist_matrix[vertex1][vertex_to_insert] +
|
int insert_cost = dist_matrix[vertex1][vertex_to_insert] +
|
||||||
data->dist_matrix[vertex_to_insert][vertex2] -
|
dist_matrix[vertex_to_insert][vertex2] -
|
||||||
data->dist_matrix[vertex1][vertex2];
|
dist_matrix[vertex1][vertex2];
|
||||||
if(insert_cost < min_cost){
|
|
||||||
|
if (insert_cost < min_cost)
|
||||||
|
{
|
||||||
min_cost = insert_cost;
|
min_cost = insert_cost;
|
||||||
best_pose = next_edge;
|
best_pose = next_edge;
|
||||||
best_vertex = vertex_to_insert;
|
best_vertex = vertex_to_insert;
|
||||||
}
|
}
|
||||||
|
|
||||||
next_edge = vertex_seq[next_edge].next;
|
next_edge = vertex_seq[next_edge].next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -925,33 +963,38 @@ int Larg_neighborhood_search(int* tour, struct GTSP *data){
|
|||||||
vertex_seq[next_vertex].prev = delete_vertex;
|
vertex_seq[next_vertex].prev = delete_vertex;
|
||||||
|
|
||||||
rval = optimize_vertex_in_cluster(vertex_seq, data);
|
rval = optimize_vertex_in_cluster(vertex_seq, data);
|
||||||
|
abort_if(rval, "optimize_vertex_in_cluster failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
//TWO OPT MOVE
|
|
||||||
rval = two_opt(vertex_seq, data);
|
rval = two_opt(vertex_seq, data);
|
||||||
|
abort_if(rval, "two_opt failed");
|
||||||
|
|
||||||
tour_cost = list_length(vertex_seq, data);
|
*tour_cost = list_length(vertex_seq, data);
|
||||||
|
|
||||||
return tour_cost;
|
CLEANUP:
|
||||||
|
if (vertex_seq) free(vertex_seq);
|
||||||
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tour_length(int* tour, struct GTSP* data){
|
int tour_length(int *tour, struct GTSP *data)
|
||||||
|
{
|
||||||
int tour_cost = 0;
|
int tour_cost = 0;
|
||||||
for(int i = 0; i< data->cluster_count ; i++){
|
for (int i = 0; i < data->cluster_count; i++)
|
||||||
if(i==data->cluster_count-1){
|
{
|
||||||
|
if (i == data->cluster_count - 1)
|
||||||
tour_cost += data->dist_matrix[tour[i]][tour[0]];
|
tour_cost += data->dist_matrix[tour[i]][tour[0]];
|
||||||
}else{
|
else
|
||||||
tour_cost += data->dist_matrix[tour[i]][tour[i + 1]];
|
tour_cost += data->dist_matrix[tour[i]][tour[i + 1]];
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return tour_cost;
|
return tour_cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
int list_length(struct TOUR *tour, struct GTSP* data){
|
int list_length(struct Tour *tour, struct GTSP *data)
|
||||||
|
{
|
||||||
int tour_cost = 0;
|
int tour_cost = 0;
|
||||||
for(int i = 0; i< data->cluster_count ; i++){
|
for (int i = 0; i < data->cluster_count; i++)
|
||||||
|
{
|
||||||
int vertex1 = tour[i].vertex;
|
int vertex1 = tour[i].vertex;
|
||||||
int vertex2 = tour[tour[i].next].vertex;
|
int vertex2 = tour[tour[i].next].vertex;
|
||||||
tour_cost += data->dist_matrix[vertex1][vertex2];
|
tour_cost += data->dist_matrix[vertex1][vertex2];
|
||||||
@@ -959,21 +1002,27 @@ int list_length(struct TOUR *tour, struct GTSP* data){
|
|||||||
return tour_cost;
|
return tour_cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_tour(int* tour, struct GTSP* data){
|
void print_tour(int *tour, struct GTSP *data)
|
||||||
|
{
|
||||||
for(int i = 0; i< data->cluster_count ; i++){
|
for (int i = 0; i < data->cluster_count; i++)
|
||||||
|
{
|
||||||
printf("%d\t", tour[i]);
|
printf("%d\t", tour[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_list(struct TOUR * tour, struct GTSP* data){
|
void print_list(struct Tour *tour, struct GTSP *data)
|
||||||
|
{
|
||||||
printf("%d\t", tour[0].vertex);
|
printf("%d\t", tour[0].vertex);
|
||||||
int vertex_next = tour[0].next;
|
int vertex_next = tour[0].next;
|
||||||
for(int i = 1; i< data->cluster_count ; i++){
|
|
||||||
|
for (int i = 1; i < data->cluster_count; i++)
|
||||||
|
{
|
||||||
printf("%d\t", tour[vertex_next].vertex);
|
printf("%d\t", tour[vertex_next].vertex);
|
||||||
vertex_next = tour[vertex_next].next;
|
vertex_next = tour[vertex_next].next;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
28
src/gtsp.h
28
src/gtsp.h
@@ -5,26 +5,34 @@
|
|||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
#include "branch_and_cut.h"
|
#include "branch_and_cut.h"
|
||||||
|
|
||||||
struct CLUSTER
|
struct Tour
|
||||||
|
{
|
||||||
|
int vertex;
|
||||||
|
int next;
|
||||||
|
int prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Cluster
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
int* set;
|
int* nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GTSP
|
struct GTSP
|
||||||
{
|
{
|
||||||
struct Graph *graph;
|
struct Graph *graph;
|
||||||
|
|
||||||
int *clusters;
|
|
||||||
int cluster_count;
|
|
||||||
int** dist_matrix;
|
int** dist_matrix;
|
||||||
struct CLUSTER *vertex_set;
|
|
||||||
|
int cluster_count;
|
||||||
|
int *node_to_cluster;
|
||||||
|
struct Cluster *clusters;
|
||||||
};
|
};
|
||||||
|
|
||||||
int GTSP_create_random_problem(
|
int GTSP_create_random_problem(
|
||||||
int node_count, int cluster_count, int grid_size, struct GTSP *data);
|
int node_count, int cluster_count, int grid_size, struct GTSP *data);
|
||||||
|
|
||||||
int inital_tour_value(struct GTSP *data);
|
int inital_tour_value(struct GTSP *data, int *value);
|
||||||
|
|
||||||
void GTSP_free(struct GTSP *data);
|
void GTSP_free(struct GTSP *data);
|
||||||
|
|
||||||
@@ -40,9 +48,9 @@ int GTSP_write_solution(struct GTSP *data, char *filename, double *x);
|
|||||||
|
|
||||||
int GTSP_main(int argc, char **argv);
|
int GTSP_main(int argc, char **argv);
|
||||||
|
|
||||||
int optimize_vertex_in_cluster(struct TOUR * tour, struct GTSP *data);
|
int optimize_vertex_in_cluster(struct Tour * tour, struct GTSP *data);
|
||||||
|
|
||||||
int two_opt(struct TOUR* tour, struct GTSP *data);
|
int two_opt(struct Tour * tour, struct GTSP *data);
|
||||||
|
|
||||||
int K_opt(int* tour, struct GTSP *data);
|
int K_opt(int* tour, struct GTSP *data);
|
||||||
|
|
||||||
@@ -50,9 +58,9 @@ int tour_length(int* tour, struct GTSP* data);
|
|||||||
|
|
||||||
void print_tour(int* tour, struct GTSP* data);
|
void print_tour(int* tour, struct GTSP* data);
|
||||||
|
|
||||||
int list_length(struct TOUR* tour, struct GTSP* data);
|
int list_length(struct Tour * tour, struct GTSP* data);
|
||||||
|
|
||||||
void print_list(struct TOUR * tour, struct GTSP* data);
|
void print_list(struct Tour * tour, struct GTSP* data);
|
||||||
|
|
||||||
extern double *OPTIMAL_X;
|
extern double *OPTIMAL_X;
|
||||||
extern double FLOW_CPU_TIME;
|
extern double FLOW_CPU_TIME;
|
||||||
|
|||||||
Reference in New Issue
Block a user