diff --git a/gtsp.in b/gtsp.in new file mode 100644 index 0000000..82c73c0 --- /dev/null +++ b/gtsp.in @@ -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 diff --git a/src/gtsp.c b/src/gtsp.c index f5ec533..4600b1c 100644 --- a/src/gtsp.c +++ b/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"); @@ -631,76 +631,78 @@ int inital_tour_value(struct GTSP *data) new_vertex += 1; } - - 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 rval = 0; - rval = two_opt(tour, data); + int i = 0 , j, current_cluster, tour_cost; + int insertion_cost = 1000000; + int rval = 0; + 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]; + 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; - - if(i == data->cluster_count-2) - vertex4 = 0; + 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; + + 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; icluster_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]; + vertex_seq[i].next = 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++){ + + + //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 insert_cost = + 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"); +} + + diff --git a/src/gtsp.h b/src/gtsp.h index 272b6e5..86f1729 100644 --- a/src/gtsp.h +++ b/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;