fbpx
Wikipedia

2-opt

In optimization, 2-opt is a simple local search algorithm for solving the traveling salesman problem. The 2-opt algorithm was first proposed by Croes in 1958,[1] although the basic move had already been suggested by Flood.[2] The main idea behind it is to take a route that crosses over itself and reorder it so that it does not. A complete 2-opt local search will compare every possible valid combination of the swapping mechanism. This technique can be applied to the traveling salesman problem as well as many related problems. These include the vehicle routing problem (VRP) as well as the capacitated VRP, which require minor modification of the algorithm.

2-opt

Pseudocode edit

Visually, one swap looks like:

 - A B - - A - B - × ==> - C D - - C - D - 

In pseudocode, the mechanism by which the 2-opt swap manipulates a given route is as follows. Here v1 and v2 are the first vertices of the edges that are to be swapped when traversing through the route:

procedure 2optSwap(route, v1, v2) { 1. take route[0] to route[v1] and add them in order to new_route 2. take route[v1+1] to route[v2] and add them in reverse order to new_route 3. take route[v2+1] to route[start] and add them in order to new_route return new_route; } 

Here is an example of the above with arbitrary input:

  • Example route: A → B → E → D → C → F → G → H → A
  • Example parameters: v1=1, v2=4 (assuming starting index is 0)
  • Contents of new_route by step:
    1. (A → B)
    2. A → B → (C → D → E)
    3. A → B → C → D → E → (F → G → H → A)

This is the complete 2-opt swap making use of the above mechanism:

repeat until no improvement is made { best_distance = calculateTotalDistance(existing_route) start_again: for (i = 0; i <= number of nodes eligible to be swapped - 1; i++) { for (j = i + 1; j <= number of nodes eligible to be swapped; j++) { new_route = 2optSwap(existing_route, i, j) new_distance = calculateTotalDistance(new_route) if (new_distance < best_distance) { existing_route = new_route best_distance = new_distance goto start_again } } } } 

The particular nodes or depots that are at the start and at the end of the path should be removed from the search as an eligible candidates for swapping, as reversing the order would cause an invalid path.

For example, with depot at A:

 A → B → C → D → A 

Swapping using node[0] and node[2] would yield

 C → B → A → D → A 

which is not valid (does not leave from A, the depot).

Efficient implementation edit

Building the new route and calculating the distance of the new route can be a very expensive operation, usually   where n is the number of vertices in the route. This can be skipped in the symmetrical case (where the distance between two nodes is the same in each opposite direction) by performing an   operation. Since a 2-opt operation involves removing 2 edges and adding 2 different edges we can subtract and add the distances of only those edges.

lengthDelta = - dist(route[v1], route[v1+1]) - dist(route[v2], route[v2+1]) + dist(route[v1+1], route[v2+1]) + dist(route[v1], route[v2]) 

If lengthDelta is negative that would mean that the new distance after the swap would be smaller. Once it is known that lengthDelta is negative, then we perform a 2-opt swap. This saves us a lot of computation.

Also using squared distances there helps reduce the computation by skipping a square root function call. Since we only care about comparing two distances and not the exact distance, this will help speed things up. It's not much, but it helps with large datasets that have millions of vertices

C++ code edit

#include <algorithm> #include <random> #include <stdio.h> #include <vector> using namespace std; class Point {  public:  int x, y;  Point(int x, int y) {  this->x = x;  this->y = y;  }  Point() {  this->x = 0;  this->y = 0;  }  // Distance between two points squared  inline int dist2(const Point &other) const {  return (x - other.x) * (x - other.x) + (y - other.y) * (y - other.y);  } }; // Calculate the distance of the whole path (Squared Distances between points) int pathLengthSq(vector<Point> &path) {  int length = 0;  for (int i = 0; i < path.size(); i++) {  length += path[i].dist2(path[(i + 1) % path.size()]);  }  return length; } // Perform a 2-opt swap void do2Opt(vector<Point> &path, int i, int j) {  reverse(begin(path) + i + 1, begin(path) + j + 1); } // Print the path.  void printPath(string pathName, vector<Point> &path) {  printf("%s = [", pathName.c_str());  for (int i = 0; i < path.size(); i++) {  if (i % 10 == 0) {  printf("\n ");  }  if (i < path.size() - 1) {  printf("[ %3d, %3d], ", path[i].x, path[i].y);  }  else {  printf("[ %3d, %3d]", path[i].x, path[i].y);  }  }  printf("\n];\n"); } // Create a path of length n with random points between 0 and 1000 vector<Point> createRandomPath(int n) {  vector<Point> path;  for (int i = 0; i < n; i++) {  path.push_back(Point(rand() % 1000, rand() % 1000));  }  return path; } int main() {  vector<Point> path = createRandomPath(100);  printPath("path1", path);  int curLength = pathLengthSq(path);  int n = path.size();  bool foundImprovement = true;  while (foundImprovement) {  foundImprovement = false;  for (int i = 0; i <= n - 2; i++) {  for (int j = i + 1; j <= n; j++) {  int lengthDelta = -path[i].dist2(path[(i + 1) % n]) - path[j].dist2(path[(j + 1) % n]) + path[i].dist2(path[j]) + path[(i + 1) % n].dist2(path[(j + 1) % n]);  // If the length of the path is reduced, do a 2-opt swap  if (lengthDelta < 0) {  do2Opt(path, i, j);  curLength += lengthDelta;  foundImprovement = true;  }  }  }  }  printPath("path2", path);  return 0; } 

Output edit

path1 = [  [ 743, 933], [ 529, 262], [ 508, 700], [ 256, 752], [ 119, 256], [ 351, 711], [ 705, 843], [ 393, 108], [ 366, 330], [ 932, 169],  [ 847, 917], [ 868, 972], [ 223, 980], [ 592, 549], [ 169, 164], [ 427, 551], [ 624, 190], [ 920, 635], [ 310, 944], [ 484, 862],  [ 301, 363], [ 236, 710], [ 431, 876], [ 397, 929], [ 491, 675], [ 344, 190], [ 425, 134], [ 30, 629], [ 126, 727], [ 334, 743],  [ 760, 104], [ 620, 749], [ 932, 256], [ 613, 572], [ 509, 490], [ 405, 119], [ 49, 695], [ 719, 327], [ 824, 497], [ 649, 596],  [ 184, 356], [ 245, 93], [ 306, 7], [ 754, 509], [ 665, 352], [ 738, 783], [ 690, 801], [ 337, 330], [ 656, 195], [ 11, 963],  [ 42, 427], [ 968, 106], [ 1, 212], [ 480, 510], [ 571, 658], [ 814, 331], [ 564, 847], [ 625, 197], [ 931, 438], [ 487, 18],  [ 187, 151], [ 179, 913], [ 750, 995], [ 913, 750], [ 134, 562], [ 547, 273], [ 830, 521], [ 557, 140], [ 726, 678], [ 597, 503],  [ 893, 408], [ 238, 988], [ 93, 85], [ 720, 188], [ 746, 211], [ 710, 387], [ 887, 209], [ 103, 668], [ 900, 473], [ 105, 674],  [ 952, 183], [ 787, 370], [ 410, 302], [ 110, 905], [ 996, 400], [ 585, 142], [ 47, 860], [ 731, 924], [ 386, 158], [ 400, 219],  [ 55, 415], [ 874, 682], [ 6, 61], [ 268, 602], [ 470, 365], [ 723, 518], [ 106, 89], [ 130, 319], [ 732, 655], [ 974, 993] ]; path2 = [  [ 743, 933], [ 750, 995], [ 847, 917], [ 868, 972], [ 974, 993], [ 913, 750], [ 920, 635], [ 874, 682], [ 726, 678], [ 732, 655],  [ 830, 521], [ 900, 473], [ 893, 408], [ 931, 438], [ 996, 400], [ 932, 256], [ 952, 183], [ 968, 106], [ 932, 169], [ 887, 209],  [ 760, 104], [ 746, 211], [ 720, 188], [ 656, 195], [ 625, 197], [ 624, 190], [ 585, 142], [ 557, 140], [ 487, 18], [ 306, 7],  [ 245, 93], [ 187, 151], [ 169, 164], [ 106, 89], [ 93, 85], [ 6, 61], [ 1, 212], [ 119, 256], [ 130, 319], [ 184, 356],  [ 301, 363], [ 337, 330], [ 366, 330], [ 410, 302], [ 344, 190], [ 393, 108], [ 405, 119], [ 425, 134], [ 386, 158], [ 400, 219],  [ 529, 262], [ 547, 273], [ 470, 365], [ 509, 490], [ 597, 503], [ 710, 387], [ 665, 352], [ 719, 327], [ 814, 331], [ 787, 370],  [ 824, 497], [ 754, 509], [ 723, 518], [ 649, 596], [ 571, 658], [ 613, 572], [ 592, 549], [ 480, 510], [ 427, 551], [ 268, 602],  [ 134, 562], [ 55, 415], [ 42, 427], [ 30, 629], [ 49, 695], [ 103, 668], [ 105, 674], [ 126, 727], [ 47, 860], [ 11, 963],  [ 110, 905], [ 179, 913], [ 223, 980], [ 238, 988], [ 310, 944], [ 256, 752], [ 236, 710], [ 334, 743], [ 351, 711], [ 491, 675],  [ 508, 700], [ 431, 876], [ 397, 929], [ 484, 862], [ 564, 847], [ 620, 749], [ 690, 801], [ 738, 783], [ 705, 843], [ 731, 924] ]; 

Visualization edit

 
2-opt Swap Path Visualization

See also edit

References edit

  1. ^ G. A. Croes, A method for solving traveling salesman problems. Operations Res. 6 (1958), pp., 791-812.
  2. ^ M. M. Flood, The traveling-salesman problem. Operations Res. 4 (1956), pp., 61-75.
  • G. A. CROES (1958). A method for solving traveling salesman problems. Operations Res. 6 (1958), pp., 791-812.
  • M. M. FLOOD (1956). The traveling-salesman problem. Operations Res. 4 (1956), pp., 61-75.

External links edit

  • The Traveling Salesman Problem: A Case Study in Local Optimization
  • Improving Solutions: 2-opt Exchanges

optimization, simple, local, search, algorithm, solving, traveling, salesman, problem, algorithm, first, proposed, croes, 1958, although, basic, move, already, been, suggested, flood, main, idea, behind, take, route, that, crosses, over, itself, reorder, that,. In optimization 2 opt is a simple local search algorithm for solving the traveling salesman problem The 2 opt algorithm was first proposed by Croes in 1958 1 although the basic move had already been suggested by Flood 2 The main idea behind it is to take a route that crosses over itself and reorder it so that it does not A complete 2 opt local search will compare every possible valid combination of the swapping mechanism This technique can be applied to the traveling salesman problem as well as many related problems These include the vehicle routing problem VRP as well as the capacitated VRP which require minor modification of the algorithm 2 opt Contents 1 Pseudocode 2 Efficient implementation 2 1 C code 2 2 Output 2 3 Visualization 3 See also 4 References 5 External linksPseudocode editVisually one swap looks like A B A B gt C D C D In pseudocode the mechanism by which the 2 opt swap manipulates a given route is as follows Here v1 and v2 are the first vertices of the edges that are to be swapped when traversing through the route procedure 2optSwap route v1 v2 1 take route 0 to route v1 and add them in order to new route 2 take route v1 1 to route v2 and add them in reverse order to new route 3 take route v2 1 to route start and add them in order to new route return new route Here is an example of the above with arbitrary input Example route A B E D C F G H A Example parameters v1 1 v2 4 assuming starting index is 0 Contents of new route by step A B A B C D E A B C D E F G H A This is the complete 2 opt swap making use of the above mechanism repeat until no improvement is made best distance calculateTotalDistance existing route start again for i 0 i lt number of nodes eligible to be swapped 1 i for j i 1 j lt number of nodes eligible to be swapped j new route 2optSwap existing route i j new distance calculateTotalDistance new route if new distance lt best distance existing route new route best distance new distance goto start again The particular nodes or depots that are at the start and at the end of the path should be removed from the search as an eligible candidates for swapping as reversing the order would cause an invalid path For example with depot at A A B C D A Swapping using node 0 and node 2 would yield C B A D A which is not valid does not leave from A the depot Efficient implementation editBuilding the new route and calculating the distance of the new route can be a very expensive operation usually O n displaystyle O n nbsp where n is the number of vertices in the route This can be skipped in the symmetrical case where the distance between two nodes is the same in each opposite direction by performing an O 1 displaystyle O 1 nbsp operation Since a 2 opt operation involves removing 2 edges and adding 2 different edges we can subtract and add the distances of only those edges lengthDelta dist route v1 route v1 1 dist route v2 route v2 1 dist route v1 1 route v2 1 dist route v1 route v2 If lengthDelta is negative that would mean that the new distance after the swap would be smaller Once it is known that lengthDelta is negative then we perform a 2 opt swap This saves us a lot of computation Also using squared distances there helps reduce the computation by skipping a square root function call Since we only care about comparing two distances and not the exact distance this will help speed things up It s not much but it helps with large datasets that have millions of vertices C code edit include lt algorithm gt include lt random gt include lt stdio h gt include lt vector gt using namespace std class Point public int x y Point int x int y this gt x x this gt y y Point this gt x 0 this gt y 0 Distance between two points squared inline int dist2 const Point amp other const return x other x x other x y other y y other y Calculate the distance of the whole path Squared Distances between points int pathLengthSq vector lt Point gt amp path int length 0 for int i 0 i lt path size i length path i dist2 path i 1 path size return length Perform a 2 opt swap void do2Opt vector lt Point gt amp path int i int j reverse begin path i 1 begin path j 1 Print the path void printPath string pathName vector lt Point gt amp path printf s pathName c str for int i 0 i lt path size i if i 10 0 printf n if i lt path size 1 printf 3d 3d path i x path i y else printf 3d 3d path i x path i y printf n n Create a path of length n with random points between 0 and 1000 vector lt Point gt createRandomPath int n vector lt Point gt path for int i 0 i lt n i path push back Point rand 1000 rand 1000 return path int main vector lt Point gt path createRandomPath 100 printPath path1 path int curLength pathLengthSq path int n path size bool foundImprovement true while foundImprovement foundImprovement false for int i 0 i lt n 2 i for int j i 1 j lt n j int lengthDelta path i dist2 path i 1 n path j dist2 path j 1 n path i dist2 path j path i 1 n dist2 path j 1 n If the length of the path is reduced do a 2 opt swap if lengthDelta lt 0 do2Opt path i j curLength lengthDelta foundImprovement true printPath path2 path return 0 Output edit path1 743 933 529 262 508 700 256 752 119 256 351 711 705 843 393 108 366 330 932 169 847 917 868 972 223 980 592 549 169 164 427 551 624 190 920 635 310 944 484 862 301 363 236 710 431 876 397 929 491 675 344 190 425 134 30 629 126 727 334 743 760 104 620 749 932 256 613 572 509 490 405 119 49 695 719 327 824 497 649 596 184 356 245 93 306 7 754 509 665 352 738 783 690 801 337 330 656 195 11 963 42 427 968 106 1 212 480 510 571 658 814 331 564 847 625 197 931 438 487 18 187 151 179 913 750 995 913 750 134 562 547 273 830 521 557 140 726 678 597 503 893 408 238 988 93 85 720 188 746 211 710 387 887 209 103 668 900 473 105 674 952 183 787 370 410 302 110 905 996 400 585 142 47 860 731 924 386 158 400 219 55 415 874 682 6 61 268 602 470 365 723 518 106 89 130 319 732 655 974 993 path2 743 933 750 995 847 917 868 972 974 993 913 750 920 635 874 682 726 678 732 655 830 521 900 473 893 408 931 438 996 400 932 256 952 183 968 106 932 169 887 209 760 104 746 211 720 188 656 195 625 197 624 190 585 142 557 140 487 18 306 7 245 93 187 151 169 164 106 89 93 85 6 61 1 212 119 256 130 319 184 356 301 363 337 330 366 330 410 302 344 190 393 108 405 119 425 134 386 158 400 219 529 262 547 273 470 365 509 490 597 503 710 387 665 352 719 327 814 331 787 370 824 497 754 509 723 518 649 596 571 658 613 572 592 549 480 510 427 551 268 602 134 562 55 415 42 427 30 629 49 695 103 668 105 674 126 727 47 860 11 963 110 905 179 913 223 980 238 988 310 944 256 752 236 710 334 743 351 711 491 675 508 700 431 876 397 929 484 862 564 847 620 749 690 801 738 783 705 843 731 924 Visualization edit nbsp 2 opt Swap Path VisualizationSee also edit3 opt local search optimization Lin Kernighan heuristicReferences edit G A Croes A method for solving traveling salesman problems Operations Res 6 1958 pp 791 812 M M Flood The traveling salesman problem Operations Res 4 1956 pp 61 75 G A CROES 1958 A method for solving traveling salesman problems Operations Res 6 1958 pp 791 812 M M FLOOD 1956 The traveling salesman problem Operations Res 4 1956 pp 61 75 External links editThe Traveling Salesman Problem A Case Study in Local Optimization Improving Solutions 2 opt Exchanges Retrieved from https en wikipedia org w index php title 2 opt amp oldid 1216337937, wikipedia, wiki, book, books, library,

article

, read, download, free, free download, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, picture, music, song, movie, book, game, games.