heuristics improved slightly
This commit is contained in:
201
gtsp.in
Normal file
201
gtsp.in
Normal file
@@ -0,0 +1,201 @@
|
||||
200 50
|
||||
31.00 90.00 0
|
||||
53.00 38.00 1
|
||||
73.00 38.00 2
|
||||
59.00 41.00 3
|
||||
4.00 8.00 4
|
||||
44.00 92.00 5
|
||||
64.00 54.00 6
|
||||
43.00 16.00 7
|
||||
13.00 24.00 8
|
||||
32.00 39.00 9
|
||||
28.00 72.00 10
|
||||
47.00 79.00 11
|
||||
81.00 29.00 12
|
||||
11.00 12.00 13
|
||||
12.00 43.00 14
|
||||
83.00 43.00 15
|
||||
34.00 36.00 16
|
||||
33.00 59.00 17
|
||||
75.00 93.00 18
|
||||
1.00 31.00 19
|
||||
53.00 97.00 20
|
||||
75.00 18.00 21
|
||||
3.00 18.00 22
|
||||
86.00 16.00 23
|
||||
42.00 19.00 24
|
||||
55.00 70.00 25
|
||||
91.00 54.00 26
|
||||
1.00 25.00 27
|
||||
35.00 13.00 28
|
||||
37.00 48.00 29
|
||||
56.00 20.00 30
|
||||
43.00 42.00 31
|
||||
9.00 77.00 32
|
||||
2.00 36.00 33
|
||||
22.00 3.00 34
|
||||
67.00 27.00 35
|
||||
0.00 42.00 36
|
||||
45.00 56.00 37
|
||||
12.00 84.00 38
|
||||
72.00 54.00 39
|
||||
55.00 28.00 40
|
||||
24.00 98.00 41
|
||||
34.00 26.00 42
|
||||
23.00 70.00 43
|
||||
91.00 61.00 44
|
||||
18.00 99.00 45
|
||||
33.00 13.00 46
|
||||
42.00 42.00 47
|
||||
90.00 44.00 48
|
||||
78.00 64.00 49
|
||||
99.00 97.00 18
|
||||
92.00 51.00 26
|
||||
91.00 89.00 18
|
||||
7.00 3.00 4
|
||||
25.00 80.00 10
|
||||
57.00 80.00 11
|
||||
60.00 34.00 3
|
||||
79.00 46.00 15
|
||||
12.00 54.00 14
|
||||
16.00 3.00 34
|
||||
15.00 86.00 38
|
||||
54.00 49.00 3
|
||||
0.00 48.00 36
|
||||
92.00 22.00 23
|
||||
59.00 43.00 3
|
||||
19.00 51.00 14
|
||||
95.00 11.00 23
|
||||
92.00 54.00 26
|
||||
66.00 18.00 21
|
||||
86.00 24.00 12
|
||||
50.00 98.00 20
|
||||
58.00 81.00 11
|
||||
45.00 70.00 11
|
||||
36.00 61.00 17
|
||||
25.00 3.00 34
|
||||
48.00 31.00 40
|
||||
4.00 0.00 4
|
||||
80.00 48.00 15
|
||||
94.00 24.00 23
|
||||
70.00 53.00 39
|
||||
68.00 41.00 2
|
||||
56.00 15.00 30
|
||||
4.00 49.00 36
|
||||
69.00 71.00 49
|
||||
19.00 8.00 34
|
||||
47.00 69.00 25
|
||||
6.00 5.00 4
|
||||
3.00 51.00 36
|
||||
27.00 39.00 9
|
||||
65.00 4.00 21
|
||||
94.00 65.00 44
|
||||
35.00 99.00 0
|
||||
65.00 15.00 21
|
||||
47.00 59.00 37
|
||||
40.00 69.00 10
|
||||
65.00 60.00 6
|
||||
10.00 21.00 8
|
||||
27.00 67.00 10
|
||||
70.00 48.00 39
|
||||
38.00 41.00 47
|
||||
56.00 85.00 11
|
||||
63.00 63.00 6
|
||||
42.00 66.00 37
|
||||
66.00 21.00 35
|
||||
57.00 31.00 40
|
||||
25.00 51.00 17
|
||||
96.00 12.00 23
|
||||
2.00 13.00 4
|
||||
28.00 49.00 29
|
||||
25.00 20.00 42
|
||||
18.00 90.00 38
|
||||
32.00 81.00 0
|
||||
11.00 59.00 14
|
||||
48.00 34.00 1
|
||||
7.00 38.00 33
|
||||
27.00 64.00 43
|
||||
75.00 90.00 18
|
||||
79.00 17.00 21
|
||||
8.00 45.00 14
|
||||
90.00 65.00 44
|
||||
29.00 67.00 10
|
||||
69.00 77.00 25
|
||||
79.00 71.00 49
|
||||
91.00 59.00 44
|
||||
73.00 68.00 49
|
||||
79.00 43.00 15
|
||||
10.00 11.00 13
|
||||
24.00 21.00 8
|
||||
70.00 72.00 49
|
||||
7.00 78.00 32
|
||||
62.00 87.00 20
|
||||
94.00 37.00 48
|
||||
77.00 73.00 49
|
||||
6.00 86.00 38
|
||||
70.00 96.00 18
|
||||
3.00 99.00 45
|
||||
63.00 72.00 25
|
||||
29.00 95.00 0
|
||||
96.00 72.00 44
|
||||
54.00 69.00 25
|
||||
40.00 34.00 16
|
||||
12.00 50.00 14
|
||||
97.00 89.00 18
|
||||
23.00 20.00 8
|
||||
13.00 83.00 38
|
||||
50.00 76.00 11
|
||||
70.00 44.00 2
|
||||
13.00 47.00 14
|
||||
17.00 20.00 8
|
||||
85.00 39.00 15
|
||||
91.00 32.00 12
|
||||
65.00 20.00 35
|
||||
27.00 61.00 17
|
||||
92.00 33.00 48
|
||||
82.00 32.00 12
|
||||
67.00 47.00 6
|
||||
34.00 17.00 28
|
||||
36.00 57.00 17
|
||||
37.00 49.00 29
|
||||
40.00 87.00 5
|
||||
25.00 62.00 43
|
||||
31.00 91.00 0
|
||||
10.00 0.00 4
|
||||
11.00 47.00 14
|
||||
91.00 31.00 12
|
||||
88.00 82.00 18
|
||||
63.00 54.00 6
|
||||
2.00 42.00 36
|
||||
67.00 94.00 18
|
||||
76.00 50.00 39
|
||||
78.00 95.00 18
|
||||
97.00 12.00 23
|
||||
64.00 33.00 35
|
||||
70.00 1.00 21
|
||||
34.00 62.00 17
|
||||
40.00 12.00 7
|
||||
25.00 23.00 42
|
||||
3.00 87.00 38
|
||||
23.00 66.00 43
|
||||
86.00 67.00 44
|
||||
97.00 75.00 44
|
||||
49.00 13.00 7
|
||||
81.00 52.00 15
|
||||
7.00 48.00 14
|
||||
46.00 35.00 1
|
||||
50.00 25.00 40
|
||||
31.00 47.00 29
|
||||
89.00 95.00 18
|
||||
32.00 59.00 17
|
||||
49.00 19.00 7
|
||||
74.00 89.00 18
|
||||
31.00 99.00 41
|
||||
13.00 34.00 14
|
||||
38.00 88.00 0
|
||||
52.00 24.00 40
|
||||
55.00 49.00 3
|
||||
51.00 57.00 37
|
||||
14.00 32.00 8
|
||||
9.00 22.00 8
|
||||
33.00 7.00 28
|
||||
233
src/gtsp.c
233
src/gtsp.c
@@ -73,7 +73,7 @@ int GTSP_create_random_problem(
|
||||
struct Graph *graph = 0;
|
||||
|
||||
int edge_count = (node_count * (node_count - 1)) / 2;
|
||||
|
||||
http://ns-webapp-b.private.uwaterloo.ca/wifisetup/index.html?cmd=login&switchip=fd74:6b6a:8eca:402::6&mac=44:6d:57:16:be:2a&ip=2620:101:f000:701::5d3c:2c75&essid=uw-wifi-setup-no-encrypt&apname=ENG-AP-E5-5--E&apgroup=E5&url=http%3A%2F%2Fwww%2Egstatic%2Ecom%2Fgenerate_204
|
||||
graph = (struct Graph *) malloc(sizeof(struct Graph));
|
||||
abort_if(!graph, "could not allocate graph\n");
|
||||
|
||||
@@ -632,75 +632,77 @@ int inital_tour_value(struct GTSP *data)
|
||||
}
|
||||
|
||||
|
||||
tour_cost = optimize_vertex_in_cluster(tour, data);
|
||||
|
||||
|
||||
|
||||
tour_cost = Larg_neighborhood_search(tour, data);
|
||||
//tour_cost = optimize_vertex_in_cluster(tour, data);
|
||||
log_info("Initial upper-bound: %d \n", tour_cost);
|
||||
return tour_cost;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int optimize_vertex_in_cluster(int* tour, struct GTSP *data)
|
||||
int optimize_vertex_in_cluster(struct TOUR * tour, struct GTSP *data)
|
||||
{
|
||||
|
||||
int i = 0 , j, current_cluster;
|
||||
int insertion_cost = 0;
|
||||
int i = 0 , j, current_cluster, tour_cost;
|
||||
int insertion_cost = 1000000;
|
||||
int rval = 0;
|
||||
rval = two_opt(tour, data);
|
||||
if(rval)
|
||||
printf("Two opt local search stopped unexpectedly");
|
||||
//rval = K_opt(tour, data);
|
||||
|
||||
for(i = 1; i < data->cluster_count - 2; i++){
|
||||
current_cluster = data->clusters[tour[i]];
|
||||
insertion_cost = data->dist_matrix[tour[i-1]][tour[i]] +
|
||||
data->dist_matrix[tour[i]][tour[i+1]];
|
||||
current_cluster = data->clusters[i];
|
||||
if(rval)
|
||||
printf("Larg_neighborhood_search stopped unexpectedly");
|
||||
|
||||
for(i = 0; i < data->cluster_count ; i++){
|
||||
int vertex = tour[i].vertex;
|
||||
int prev_vertex = tour[tour[i].prev].vertex;
|
||||
int next_vertex = tour[tour[i].next].vertex;
|
||||
|
||||
current_cluster = data->clusters[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++){
|
||||
int vertex = data->vertex_set[current_cluster].set[j];
|
||||
if (insertion_cost > data->dist_matrix[vertex][tour[i]] +
|
||||
data->dist_matrix[vertex][tour[i+1]]){
|
||||
insertion_cost = data->dist_matrix[vertex][tour[i]] +
|
||||
data->dist_matrix[vertex][tour[i+1]];
|
||||
tour[i] = vertex;
|
||||
}
|
||||
int vertex_in_cluster = data->vertex_set[current_cluster].set[j];
|
||||
int cost = data->dist_matrix[vertex_in_cluster][prev_vertex] +
|
||||
data->dist_matrix[vertex_in_cluster][next_vertex];
|
||||
if (insertion_cost > cost){
|
||||
insertion_cost = cost;
|
||||
tour[i].vertex = vertex_in_cluster;
|
||||
}
|
||||
}
|
||||
}
|
||||
int tour_cost = 0;
|
||||
for(i = 0; i< data->cluster_count ; i++){
|
||||
if (i == data->cluster_count - 1)
|
||||
tour_cost += data->dist_matrix[tour[i]][tour[0]];
|
||||
else
|
||||
tour_cost += data->dist_matrix[tour[i]][tour[i+1]];
|
||||
}
|
||||
return tour_cost;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int two_opt(int* tour, struct GTSP *data){
|
||||
int two_opt(struct TOUR* tour, struct GTSP *data){
|
||||
|
||||
int rval = 0, i;
|
||||
for (i = 0; i < data->cluster_count; i++){
|
||||
int vertex1 = i;
|
||||
int vertex2 = i - 1;
|
||||
int vertex3 = i + 1;
|
||||
int vertex4 = i + 2;
|
||||
if(i == 0)
|
||||
vertex2 = data->cluster_count - 1;
|
||||
int vertex1 = tour[i].vertex;
|
||||
int vertex2 = tour[tour[i].prev].vertex;
|
||||
int vertex3 = tour[tour[i].next].vertex;
|
||||
int vertex4 = tour[tour[tour[i].next].next].vertex;
|
||||
|
||||
if(i == data->cluster_count-2)
|
||||
vertex4 = 0;
|
||||
int current_cost = data->dist_matrix[vertex2][vertex1] +
|
||||
data->dist_matrix[vertex3][vertex4];
|
||||
|
||||
if(i == data->cluster_count-1){
|
||||
vertex3 = 0;
|
||||
vertex4 = 1;
|
||||
}
|
||||
|
||||
int current_cost = data->dist_matrix[tour[vertex2]][tour[vertex1]] +
|
||||
data->dist_matrix[tour[vertex3]][tour[vertex4]];
|
||||
int temp_cost = data->dist_matrix[tour[vertex2]][tour[vertex3]] +
|
||||
data->dist_matrix[tour[vertex1]][tour[vertex4]];
|
||||
int temp_cost = data->dist_matrix[vertex2][vertex3] +
|
||||
data->dist_matrix[vertex1][vertex4];
|
||||
if(current_cost > temp_cost){
|
||||
int temp_vertex = tour[vertex1];
|
||||
tour[vertex1] = tour[vertex3];
|
||||
tour[vertex3] = temp_vertex;
|
||||
int temp_next = tour[i].next;
|
||||
int temp_prev = tour[i].prev;
|
||||
|
||||
tour[i].next = tour[temp_next].next;
|
||||
tour[i].prev = temp_next;
|
||||
|
||||
tour[tour[temp_next].next].prev = i;
|
||||
|
||||
tour[temp_next].next = i;
|
||||
tour[temp_next].prev = temp_prev;
|
||||
|
||||
tour[temp_prev].next = temp_next;
|
||||
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
@@ -738,38 +740,119 @@ int K_opt(int* tour, struct GTSP *data){
|
||||
}
|
||||
return rval;
|
||||
}*/
|
||||
/*
|
||||
|
||||
int Larg_neighborhood_search(int* tour, struct GTSP *data){
|
||||
int i ;
|
||||
struct TOUR* vertex_seq;
|
||||
int i, best_vertex, best_pose, tour_cost, rval;
|
||||
struct TOUR *vertex_seq;
|
||||
vertex_seq = (struct TOUR*) malloc(data->cluster_count*sizeof(struct TOUR));
|
||||
for(i = 0; i<data->cluster_count; i++){
|
||||
|
||||
//Construct the list
|
||||
for(i = 0; i < data->cluster_count; i++){
|
||||
vertex_seq[i].vertex = tour[i];
|
||||
if ( i == 0){
|
||||
vertex_seq[i].prev = tour[data->cluster_count-1];
|
||||
vertex_seq[i].prev = data->cluster_count-1;
|
||||
}else{
|
||||
vertex_seq[i].prev = tour[i - 1];
|
||||
vertex_seq[i].prev = i - 1;
|
||||
}
|
||||
if ( i == data->cluster_count-1){
|
||||
vertex_seq[i].next = tour[0];
|
||||
vertex_seq[i].next = 0;
|
||||
}else{
|
||||
vertex_seq[i].next = tour[i+1];
|
||||
}
|
||||
}
|
||||
//Delete a vertex
|
||||
int delete_vertex = rand()%(data->cluster_count - 1) + 1;
|
||||
int prev_vertex = vertex_seq[delete_vertex].prev;
|
||||
int next_vertex = vertex_seq[delete_vertex].next;
|
||||
vertex_seq[prev_vertex].next = next_vertex;
|
||||
vertex_seq[next_vertex].prev = prev_vertex;
|
||||
int cluster_to_insert = data->clusters[vertex_seq[delete_vertex].vertex];
|
||||
int min_cost = 10000000;
|
||||
for(i =0 ; i < data->vertex_set[cluster_to_insert].size ; i++){
|
||||
int current_vertex = data->vertex_set[cluster_to_insert].set[i];
|
||||
for(int j = 0; j < data->cluster_count - 1; j++){
|
||||
|
||||
//int insert_cost =
|
||||
vertex_seq[i].next = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
//LNS starts
|
||||
for(int iter = 0; iter < 500; iter++){
|
||||
//Delete a vertex
|
||||
int delete_vertex = rand()%(data->cluster_count - 1) + 1;
|
||||
|
||||
int prev_vertex = vertex_seq[delete_vertex].prev;
|
||||
int next_vertex = vertex_seq[delete_vertex].next;
|
||||
|
||||
vertex_seq[prev_vertex].next = next_vertex;
|
||||
vertex_seq[next_vertex].prev = prev_vertex;
|
||||
|
||||
int cluster_to_insert = data->clusters[vertex_seq[delete_vertex].vertex];
|
||||
int min_cost = 10000000;
|
||||
for(i =0 ; i < data->vertex_set[cluster_to_insert].size ; i++){
|
||||
int vertex_to_insert = data->vertex_set[cluster_to_insert].set[i];
|
||||
|
||||
int next_edge = vertex_seq[0].next;
|
||||
for(int j = 1; j < data->cluster_count ; j++){
|
||||
int vertex1 = vertex_seq[next_edge].vertex;
|
||||
int vertex2 = vertex_seq[vertex_seq[next_edge].next].vertex;
|
||||
|
||||
int insert_cost = data->dist_matrix[vertex1][vertex_to_insert] +
|
||||
data->dist_matrix[vertex_to_insert][vertex2] -
|
||||
data->dist_matrix[vertex1][vertex2];
|
||||
if(insert_cost < min_cost){
|
||||
min_cost = insert_cost;
|
||||
best_pose = next_edge;
|
||||
best_vertex = vertex_to_insert;
|
||||
}
|
||||
next_edge = vertex_seq[next_edge].next;
|
||||
}
|
||||
}
|
||||
|
||||
next_vertex = vertex_seq[best_pose].next;
|
||||
vertex_seq[delete_vertex].prev = best_pose;
|
||||
vertex_seq[delete_vertex].vertex = best_vertex;
|
||||
vertex_seq[delete_vertex].next = next_vertex;
|
||||
vertex_seq[best_pose].next = delete_vertex;
|
||||
vertex_seq[next_vertex].prev = delete_vertex;
|
||||
|
||||
rval = optimize_vertex_in_cluster(vertex_seq, data);
|
||||
|
||||
}
|
||||
|
||||
//TWO OPT MOVE
|
||||
rval = two_opt(vertex_seq, data);
|
||||
|
||||
tour_cost = list_length(vertex_seq, data);
|
||||
|
||||
return tour_cost;
|
||||
}
|
||||
|
||||
int tour_length(int* tour, struct GTSP* data){
|
||||
int tour_cost = 0;
|
||||
for(int i = 0; i< data->cluster_count ; i++){
|
||||
if(i==data->cluster_count-1){
|
||||
tour_cost += data->dist_matrix[tour[i]][tour[0]];
|
||||
}else{
|
||||
tour_cost += data->dist_matrix[tour[i]][tour[i+1]];
|
||||
}
|
||||
|
||||
}
|
||||
return tour_cost;
|
||||
}
|
||||
|
||||
int list_length(struct TOUR *tour, struct GTSP* data){
|
||||
int tour_cost = 0;
|
||||
for(int i = 0; i< data->cluster_count ; i++){
|
||||
int vertex1 = tour[i].vertex;
|
||||
int vertex2 = tour[tour[i].next].vertex;
|
||||
tour_cost += data->dist_matrix[vertex1][vertex2];
|
||||
}
|
||||
return tour_cost;
|
||||
}
|
||||
|
||||
void print_tour(int* tour, struct GTSP* data){
|
||||
|
||||
for(int i = 0; i< data->cluster_count ; i++){
|
||||
printf("%d\t", tour[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void print_list(struct TOUR * tour, struct GTSP* data){
|
||||
printf("%d\t", tour[0].vertex);
|
||||
int vertex_next = tour[0].next;
|
||||
for(int i = 1; i< data->cluster_count ; i++){
|
||||
printf("%d\t", tour[vertex_next].vertex);
|
||||
vertex_next = tour[vertex_next].next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
13
src/gtsp.h
13
src/gtsp.h
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "lp.h"
|
||||
#include "graph.h"
|
||||
#include "branch_and_cut.h"
|
||||
|
||||
struct CLUSTER
|
||||
{
|
||||
@@ -46,12 +47,20 @@ int GTSP_write_solution(struct GTSP *data, char *filename, double *x);
|
||||
|
||||
int GTSP_main(int argc, char **argv);
|
||||
|
||||
int optimize_vertex_in_cluster(int* tour, struct GTSP *data);
|
||||
int optimize_vertex_in_cluster(struct TOUR * tour, struct GTSP *data);
|
||||
|
||||
int two_opt(int* tour, struct GTSP *data);
|
||||
int two_opt(struct TOUR* tour, struct GTSP *data);
|
||||
|
||||
int K_opt(int* tour, struct GTSP *data);
|
||||
|
||||
int tour_length(int* tour, struct GTSP* data);
|
||||
|
||||
void print_tour(int* tour, struct GTSP* data);
|
||||
|
||||
int list_length(struct TOUR* tour, struct GTSP* data);
|
||||
|
||||
void print_list(struct TOUR * tour, struct GTSP* data);
|
||||
|
||||
extern double *OPTIMAL_X;
|
||||
extern double FLOW_CPU_TIME;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user