Advertisement
daskalot

Untitled

May 18th, 2019
377
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.46 KB | None | 0 0
  1. package aps2.tsp;
  2. class Node{
  3. int id;
  4. int x;
  5. int y;
  6. Node(int x,int y,int id){
  7. this.id = id;
  8. this.x = x;
  9. this.y = y;
  10. }
  11. }
  12. public class TravellingSalesman {
  13. int N,added, maxn = 18;
  14. int[] optimal;
  15. double resDist;
  16. Node nodes[];
  17. public TravellingSalesman() {
  18. this.N=0;
  19. this.nodes = new Node[100];
  20. }
  21. /**
  22. * To solve the travelling salesman problem (TSP) you need to find a shortest
  23. * tour over all nodes in the graph where each node must be visited exactly
  24. * once. You need to finish at the origin node.
  25. *
  26. * In this task we will consider complete undirected graphs only with
  27. * Euclidean distances between the nodes.
  28. */
  29.  
  30. /**
  31. * Adds a node to a graph with coordinates x and y. Assume the nodes are
  32. * named by the order of insertion.
  33. *
  34. * @param x X-coordinate
  35. * @param y Y-coordinate
  36. */
  37. public void addNode(int x, int y){
  38. Node n = new Node(x,y,N);
  39. nodes[N] = n;
  40. N++;
  41. }
  42.  
  43. /**
  44. * Returns the distance between nodes v1 and v2.
  45. *
  46. * @param v1 Identifier of the first node
  47. * @param v2 Identifier of the second node
  48. * @return Euclidean distance between the nodes
  49. */
  50. public double getDistance(int v1, int v2) {
  51. return Math.sqrt(Math.pow(nodes[v1].x - nodes[v2].x, 2)+Math.pow(nodes[v1].y - nodes[v2].y, 2));
  52. }
  53.  
  54. /**
  55. * Finds and returns an optimal shortest tour from the origin node and
  56. * returns the order of nodes to visit.
  57. *
  58. * Implementation note: Avoid exploring paths which are obviously longer
  59. * than the existing shortest tour.
  60. *
  61. * @param start Index of the origin node
  62. * @return List of nodes to visit in specific order
  63. */
  64.  
  65. double DP[][];
  66. public int[] calculateExactShortestTour(int start){
  67. calculateExactShortestTourDistance(start);
  68. int mask = (1<<N)-1, last = start;
  69. int path[] = new int[N];
  70. for(int i=0;i<N;i++) {
  71. for(int k=0;k<N;k++) {
  72. if((mask&(1<<k))!=0){
  73. if(DP[mask^(1<<last)][k]+getDistance(k,last)==DP[mask][last]) {
  74. mask ^= (1<<last);
  75. last = k;
  76. path[N-1-i]=k;
  77. break;
  78. }
  79. }
  80. }
  81. }
  82. return path;
  83. }
  84. /**
  85. * Returns an optimal shortest tour and returns its distance given the
  86. * origin node.
  87. *
  88. * @param start Index of the origin node
  89. * @return Distance of the optimal shortest TSP tour
  90. */
  91. public double calculateExactShortestTourDistance(int start){
  92. DP = new double[1<<maxn][maxn];
  93. for(int i=0;i<(1<<maxn);i++)
  94. for(int j=0;j<(maxn);j++)
  95. DP[i][j] = Double.MAX_VALUE;
  96. DP[0][start] = 0.0;
  97.  
  98. for (int k = 0; k < (1 << N); k++)
  99. for (int i = 0; i < N; i++) {
  100. for (int j = 0; j < N; j++) {
  101. if ((k & (1 << j)) == 0)
  102. DP[k | (1 << j)][j] = Math.min(DP[k | (1 << j)][j], getDistance(i, j) + DP[k][i]);
  103. }
  104. }
  105.  
  106. return DP[(1<<N) - 1][0];
  107.  
  108. }
  109. /**
  110. * Returns an approximate shortest tour and returns the order of nodes to
  111. * visit given the origin node.
  112. *
  113. * Implementation note: Use a greedy nearest neighbor apporach to construct
  114. * an initial tour. Then use iterative 2-opt method to improve the
  115. * solution.
  116. *
  117. * @param start Index of the origin node
  118. * @return List of nodes to visit in specific order
  119. */
  120. public int[] calculateApproximateShortestTour(int start){
  121. int[] initial = nearestNeighborGreedy(start);
  122. return twoOptExchange(initial);
  123. }
  124.  
  125. /**
  126. * Returns an approximate shortest tour and returns its distance given the
  127. * origin node.
  128. *
  129. * @param start Index of the origin node
  130. * @return Distance of the approximate shortest TSP tour
  131. */
  132. public double calculateApproximateShortestTourDistance(int start){
  133. optimal = calculateApproximateShortestTour(start);
  134. return calculateDistanceTravelled(optimal);
  135. }
  136.  
  137. /**
  138. * Constructs a Hamiltonian cycle by starting at the origin node and each
  139. * time adding the closest neighbor to the path.
  140. *
  141. * Implementation note: If multiple neighbors share the same distance,
  142. * select the one with the smallest id.
  143. *
  144. * @param start Origin node
  145. * @return List of nodes to visit in specific order
  146. */
  147. public int[] nearestNeighborGreedy(int start){
  148. int[] res = new int[N+1];
  149. boolean visited[] = new boolean[N];
  150. res[0] = start; visited[start] = true;
  151. int prev = start;
  152. for(int i=1;i<N;i++) {
  153. int next = -1;
  154. double min = Integer.MAX_VALUE;
  155. for(int j=0;j<N;j++) {
  156. double tempDist = getDistance(prev,j);
  157. if(!visited[j] && tempDist <= min) {
  158. min=tempDist;
  159. next = j;
  160. }
  161. }
  162. visited[next] = true;
  163. res[i] = next;
  164. prev = next;
  165. }
  166. res[N] = start;
  167. return res;
  168. }
  169.  
  170. /**
  171. * Improves the given route using 2-opt exchange.
  172. *
  173. * Implementation note: Repeat the procedure until the route is not
  174. * improved in the next iteration anymore.
  175. *
  176. * @param route Original route
  177. * @return Improved route using 2-opt exchange
  178. */
  179. private int[] twoOptExchange(int[] route) {
  180. boolean improvement = true;
  181. int validNodes = route.length - 2;
  182. while(improvement) {
  183. improvement = false;
  184. double bestDistance = calculateDistanceTravelled(route);
  185. for(int i=1;i<validNodes-1;i++) {
  186. for(int k=i+1;k<validNodes;k++) {
  187. int[] newRoute = twoOptSwap(route, i, k);
  188. double newDistance = calculateDistanceTravelled(route);
  189. if(newDistance < bestDistance) {
  190. route = newRoute;
  191. bestDistance = newDistance;
  192. improvement = true;
  193. }
  194. }
  195. }
  196. }
  197. return route;
  198. }
  199.  
  200. /**
  201. * Swaps the nodes i and k of the tour and adjusts the tour accordingly.
  202. *
  203. * Implementation note: Consider the new order of some nodes due to the
  204. * swap!
  205. *
  206. * @param route Original tour
  207. * @param i Name of the first node
  208. * @param k Name of the second node
  209. * @return The newly adjusted tour
  210. */
  211. public int[] twoOptSwap(int[] route, int i, int k) {
  212. int size = route.length; int[] newTour = new int[size];
  213. for(int p = 0; p < size;p++) {
  214. if(p < i || p > k) newTour[p] = route[p];
  215. else newTour[p] = route[k-(p-i)];
  216. }
  217. return newTour;
  218. }
  219.  
  220. /**
  221. * Returns the total distance of the given tour i.e. the sum of distances
  222. * of the given path add the distance between the final and initial node.
  223. *
  224. * @param tour List of nodes in the given order
  225. * @return Travelled distance of the tour
  226. */
  227. public double calculateDistanceTravelled(int[] tour){
  228. double distanceTurn = 0; int size = tour.length;
  229. for(int i=0;i<size;i++) distanceTurn = distanceTurn + getDistance(tour[i],tour[(i+1)%size]);
  230. return distanceTurn;
  231. }
  232.  
  233. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement