2-opt
- 15 min read
- 2 chapters
Related on Lably
Through Mathematical optimization
Pseudocode
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:
<b id="mwFw">procedure</b> 2optSwap(route, v1, v2) { 1. take route[start] 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 <b id="mwGA">return</b> 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:
<b id="mwJw">repeat until</b> no improvement is made { best_distance = calculateTotalDistance(existing_route) start_again: <b id="mwKA">for</b> (i = 0; i <= number of nodes eligible to be swapped - 1; i++) { <b id="mwKQ">for</b> (j = i + 1; j <= number of nodes eligible to be swapped; j++) { new_route = 2optSwap(existing_route, i, j) new_distance = calculateTotalDistance(new_route) <b id="mwKg">if</b> (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).
Sign in to keep reading
One more chapter is free with a Lably account.
Efficient implementation
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. In a symmetric case (where the distance between A and B is the same as between B and A), this can be skipped by performing a 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.
C++ code
<span id="mwPQ"></span><span class="cp" id="mwPg">#include</span><span class="w" id="mwPw"> </span><span class="cpf" id="mwQA"><random></span> <span class="cp" id="mwQQ">#include</span><span class="w" id="mwQg"> </span><span class="cpf" id="mwQw"><stdio.h></span> <span class="cp" id="mwRA">#include</span><span class="w" id="mwRQ"> </span><span class="cpf" id="mwRg"><vector></span> <span class="k" id="mwRw">using</span><span class="w" id="mwSA"> </span><span class="k" id="mwSQ">namespace</span><span class="w" id="mwSg"> </span><span class="nn" id="mwSw">std</span><span class="p" id="mwTA">;</span> <span class="k" id="mwTQ">class</span><span class="w" id="mwTg"> </span><span class="nc" id="mwTw">Point</span><span class="w" id="mwUA"> </span><span class="p" id="mwUQ">{</span> <span class="k" id="mwUg">public</span><span class="o" id="mwUw">:</span> <span class="w" id="mwVA"> </span><span class="kt" id="mwVQ">float</span><span class="w" id="mwVg"> </span><span class="n" id="mwVw">x</span><span class="p" id="mwWA">,</span><span class="w" id="mwWQ"> </span><span class="n" id="mwWg">y</span><span class="p" id="mwWw">;</span> <span class="w" id="mwXA"> </span><span class="n" id="mwXQ">Point</span><span class="p" id="mwXg">(</span><span class="kt" id="mwXw">float</span><span class="w" id="mwYA"> </span><span class="n" id="mwYQ">x</span><span class="p" id="mwYg">,</span><span class="w" id="mwYw"> </span><span class="kt" id="mwZA">float</span><span class="w" id="mwZQ"> </span><span class="n" id="mwZg">y</span><span class="p" id="mwZw">)</span><span class="w" id="mwaA"> </span><span class="p" id="mwaQ">{</span> <span class="w" id="mwag"> </span><span class="k" id="mwaw">this</span><span class="o" id="mwbA">-></span><span class="n" id="mwbQ">x</span><span class="w" id="mwbg"> </span><span class="o" id="mwbw">=</span><span class="w" id="mwcA"> </span><span class="n" id="mwcQ">x</span><span class="p" id="mwcg">;</span> <span class="w" id="mwcw"> </span><span class="k" id="mwdA">this</span><span class="o" id="mwdQ">-></span><span class="n" id="mwdg">y</span><span class="w" id="mwdw"> </span><span class="o" id="mweA">=</span><span class="w" id="mweQ"> </span><span class="n" id="mweg">y</span><span class="p" id="mwew">;</span> <span class="w" id="mwfA"> </span><span class="p" id="mwfQ">}</span> <span class="w" id="mwfg"> </span><span class="n" id="mwfw">Point</span><span class="p" id="mwgA">()</span><span class="w" id="mwgQ"> </span><span class="p" id="mwgg">{</span> <span class="w" id="mwgw"> </span><span class="k" id="mwhA">this</span><span class="o" id="mwhQ">-></span><span class="n" id="mwhg">x</span><span class="w" id="mwhw"> </span><span class="o" id="mwiA">=</span><span class="w" id="mwiQ"> </span><span class="mf" id="mwig">0.0</span><span class="p" id="mwiw">;</span> <span class="w" id="mwjA"> </span><span class="k" id="mwjQ">this</span><span class="o" id="mwjg">-></span><span class="n" id="mwjw">y</span><span class="w" id="mwkA"> </span><span class="o" id="mwkQ">=</span><span class="w" id="mwkg"> </span><span class="mf" id="mwkw">0.0</span><span class="p" id="mwlA">;</span> <span class="w" id="mwlQ"> </span><span class="p" id="mwlg">}</span> <span class="w" id="mwlw"> </span><span class="c1" id="mwmA">// Distance between two points</span> <span class="w" id="mwmQ"> </span><span class="kr" id="mwmg">inline</span><span class="w" id="mwmw"> </span><span class="kt" id="mwnA">float</span><span class="w" id="mwnQ"> </span><span class="n" id="mwng">dist</span><span class="p" id="mwnw">(</span><span class="k" id="mwoA">const</span><span class="w" id="mwoQ"> </span><span class="n" id="mwog">Point</span><span class="w" id="mwow"> </span><span class="o" id="mwpA">&</span><span class="n" id="mwpQ">other</span><span class="p" id="mwpg">)</span><span class="w" id="mwpw"> </span><span class="k" id="mwqA">const</span><span class="w" id="mwqQ"> </span><span class="p" id="mwqg">{</span> <span class="w" id="mwqw"> </span><span class="kt" id="mwrA">float</span><span class="w" id="mwrQ"> </span><span class="n" id="mwrg">diffx</span><span class="w" id="mwrw"> </span><span class="o" id="mwsA">=</span><span class="w" id="mwsQ"> </span><span class="n" id="mwsg">x</span><span class="w" id="mwsw"> </span><span class="o" id="mwtA">-</span><span class="w" id="mwtQ"> </span><span class="n" id="mwtg">other</span><span class="p" id="mwtw">.</span><span class="n" id="mwuA">x</span><span class="p" id="mwuQ">;</span> <span class="w" id="mwug"> </span><span class="kt" id="mwuw">float</span><span class="w" id="mwvA"> </span><span class="n" id="mwvQ">diffy</span><span class="w" id="mwvg"> </span><span class="o" id="mwvw">=</span><span class="w" id="mwwA"> </span><span class="n" id="mwwQ">y</span><span class="w" id="mwwg"> </span><span class="o" id="mwww">-</span><span class="w" id="mwxA"> </span><span class="n" id="mwxQ">other</span><span class="p" id="mwxg">.</span><span class="n" id="mwxw">y</span><span class="p" id="mwyA">;</span> <span class="w" id="mwyQ"> </span><span class="k" id="mwyg">return</span><span class="w" id="mwyw"> </span><span class="n" id="mwzA">sqrt</span><span class="p" id="mwzQ">(</span><span class="n" id="mwzg">diffx</span><span class="w" id="mwzw"> </span><span class="o" id="mw0A">*</span><span class="w" id="mw0Q"> </span><span class="n" id="mw0g">diffx</span><span class="w" id="mw0w"> </span><span class="o" id="mw1A">+</span><span class="w" id="mw1Q"> </span><span class="n" id="mw1g">diffy</span><span class="w" id="mw1w"> </span><span class="o" id="mw2A">*</span><span class="w" id="mw2Q"> </span><span class="n" id="mw2g">diffy</span><span class="p" id="mw2w">);</span> <span class="w" id="mw3A"> </span><span class="p" id="mw3Q">}</span> <span class="p" id="mw3g">};</span> <span class="c1" id="mw3w">// Calculate the distance of the whole circuit</span> <span class="kt" id="mw4A">int</span><span class="w" id="mw4Q"> </span><span class="nf" id="mw4g">pathLength</span><span class="p" id="mw4w">(</span><span class="n" id="mw5A">vector</span><span class="o" id="mw5Q"><</span><span class="n" id="mw5g">Point</span><span class="o" id="mw5w">></span><span class="w" id="mw6A"> </span><span class="o" id="mw6Q">&</span><span class="n" id="mw6g">path</span><span class="p" id="mw6w">)</span><span class="w" id="mw7A"> </span><span class="p" id="mw7Q">{</span> <span class="w" id="mw7g"> </span><span class="kt" id="mw7w">int</span><span class="w" id="mw8A"> </span><span class="n" id="mw8Q">n</span><span class="w" id="mw8g"> </span><span class="o" id="mw8w">=</span><span class="w" id="mw9A"> </span><span class="n" id="mw9Q">path</span><span class="p" id="mw9g">.</span><span class="n" id="mw9w">size</span><span class="p" id="mw-A">();</span> <span class="w" id="mw-Q"> </span><span class="kt" id="mw-g">float</span><span class="w" id="mw-w"> </span><span class="n" id="mw_A">length</span><span class="w" id="mw_Q"> </span><span class="o" id="mw_g">=</span><span class="w" id="mw_w"> </span><span class="n" id="mwAQA">path</span><span class="p" id="mwAQE">[</span><span class="n" id="mwAQI">n</span><span class="w" id="mwAQM"> </span><span class="o" id="mwAQQ">-</span><span class="w" id="mwAQU"> </span><span class="mi" id="mwAQY">1</span><span class="p" id="mwAQc">].</span><span class="n" id="mwAQg">dist</span><span class="p" id="mwAQk">(</span><span class="n" id="mwAQo">path</span><span class="p" id="mwAQs">[</span><span class="mi" id="mwAQw">0</span><span class="p" id="mwAQ0">]);</span> <span class="w" id="mwAQ4"> </span><span class="k" id="mwAQ8">for</span><span class="w" id="mwARA"> </span><span class="p" id="mwARE">(</span><span class="kt" id="mwARI">int</span><span class="w" id="mwARM"> </span><span class="n" id="mwARQ">i</span><span class="w" id="mwARU"> </span><span class="o" id="mwARY">=</span><span class="w" id="mwARc"> </span><span class="mi" id="mwARg">0</span><span class="p" id="mwARk">;</span><span class="w" id="mwARo"> </span><span class="n" id="mwARs">i</span><span class="w" id="mwARw"> </span><span class="o" id="mwAR0"><</span><span class="w" id="mwAR4"> </span><span class="n" id="mwAR8">n</span><span class="w" id="mwASA"> </span><span class="o" id="mwASE">-</span><span class="w" id="mwASI"> </span><span class="mi" id="mwASM">1</span><span class="p" id="mwASQ">;</span><span class="w" id="mwASU"> </span><span class="n" id="mwASY">i</span><span class="o" id="mwASc">++</span><span class="p" id="mwASg">)</span><span class="w" id="mwASk"> </span><span class="p" id="mwASo">{</span> <span class="w" id="mwASs"> </span><span class="n" id="mwASw">length</span><span class="w" id="mwAS0"> </span><span class="o" id="mwAS4">+=</span><span class="w" id="mwAS8"> </span><span class="n" id="mwATA">path</span><span class="p" id="mwATE">[</span><span class="n" id="mwATI">i</span><span class="p" id="mwATM">].</span><span class="n" id="mwATQ">dist</span><span class="p" id="mwATU">(</span><span class="n" id="mwATY">path</span><span class="p" id="mwATc">[</span><span class="n" id="mwATg">i</span><span class="w" id="mwATk"> </span><span class="o" id="mwATo">+</span><span class="w" id="mwATs"> </span><span class="mi" id="mwATw">1</span><span class="p" id="mwAT0">]);</span> <span class="w" id="mwAT4"> </span><span class="p" id="mwAT8">}</span> <span class="w" id="mwAUA"> </span><span class="k" id="mwAUE">return</span><span class="w" id="mwAUI"> </span><span class="n" id="mwAUM">length</span><span class="p" id="mwAUQ">;</span> <span class="p" id="mwAUU">}</span> <span class="c1" id="mwAUY">// Replace edges path[i]->path[i+1] and path[j]->path[j+1]</span> <span class="c1" id="mwAUc">// with path[i]->path[j] and path[i+1]->path[j+1]</span> <span class="kt" id="mwAUg">void</span><span class="w" id="mwAUk"> </span><span class="nf" id="mwAUo">swap_edges</span><span class="p" id="mwAUs">(</span><span class="n" id="mwAUw">vector</span><span class="o" id="mwAU0"><</span><span class="n" id="mwAU4">Point</span><span class="o" id="mwAU8">></span><span class="w" id="mwAVA"> </span><span class="o" id="mwAVE">&</span><span class="n" id="mwAVI">path</span><span class="p" id="mwAVM">,</span><span class="w" id="mwAVQ"> </span><span class="kt" id="mwAVU">int</span><span class="w" id="mwAVY"> </span><span class="n" id="mwAVc">i</span><span class="p" id="mwAVg">,</span><span class="w" id="mwAVk"> </span><span class="kt" id="mwAVo">int</span><span class="w" id="mwAVs"> </span><span class="n" id="mwAVw">j</span><span class="p" id="mwAV0">)</span><span class="w" id="mwAV4"> </span><span class="p" id="mwAV8">{</span> <span class="w" id="mwAWA"> </span><span class="n" id="mwAWE">i</span><span class="w" id="mwAWI"> </span><span class="o" id="mwAWM">+=</span><span class="w" id="mwAWQ"> </span><span class="mi" id="mwAWU">1</span><span class="p" id="mwAWY">;</span> <span class="w" id="mwAWc"> </span><span class="k" id="mwAWg">while</span><span class="w" id="mwAWk"> </span><span class="p" id="mwAWo">(</span><span class="n" id="mwAWs">i</span><span class="w" id="mwAWw"> </span><span class="o" id="mwAW0"><</span><span class="w" id="mwAW4"> </span><span class="n" id="mwAW8">j</span><span class="p" id="mwAXA">)</span><span class="w" id="mwAXE"> </span><span class="p" id="mwAXI">{</span> <span class="w" id="mwAXM"> </span><span class="n" id="mwAXQ">Point</span><span class="w" id="mwAXU"> </span><span class="n" id="mwAXY">temp</span><span class="w" id="mwAXc"> </span><span class="o" id="mwAXg">=</span><span class="w" id="mwAXk"> </span><span class="n" id="mwAXo">path</span><span class="p" id="mwAXs">[</span><span class="n" id="mwAXw">i</span><span class="p" id="mwAX0">];</span> <span class="w" id="mwAX4"> </span><span class="n" id="mwAX8">path</span><span class="p" id="mwAYA">[</span><span class="n" id="mwAYE">i</span><span class="p" id="mwAYI">]</span><span class="w" id="mwAYM"> </span><span class="o" id="mwAYQ">=</span><span class="w" id="mwAYU"> </span><span class="n" id="mwAYY">path</span><span class="p" id="mwAYc">[</span><span class="n" id="mwAYg">j</span><span class="p" id="mwAYk">];</span> <span class="w" id="mwAYo"> </span><span class="n" id="mwAYs">path</span><span class="p" id="mwAYw">[</span><span class="n" id="mwAY0">j</span><span class="p" id="mwAY4">]</span><span class="w" id="mwAY8"> </span><span class="o" id="mwAZA">=</span><span class="w" id="mwAZE"> </span><span class="n" id="mwAZI">temp</span><span class="p" id="mwAZM">;</span> <span class="w" id="mwAZQ"> </span><span class="n" id="mwAZU">i</span><span class="o" id="mwAZY">++</span><span class="p" id="mwAZc">;</span> <span class="w" id="mwAZg"> </span><span class="n" id="mwAZk">j</span><span class="o" id="mwAZo">--</span><span class="p" id="mwAZs">;</span> <span class="w" id="mwAZw"> </span><span class="p" id="mwAZ0">}</span> <span class="p" id="mwAZ4">}</span> <span class="c1" id="mwAZ8">// Print the path.</span> <span class="kt" id="mwAaA">void</span><span class="w" id="mwAaE"> </span><span class="nf" id="mwAaI">printPath</span><span class="p" id="mwAaM">(</span><span class="n" id="mwAaQ">string</span><span class="w" id="mwAaU"> </span><span class="n" id="mwAaY">pathName</span><span class="p" id="mwAac">,</span><span class="w" id="mwAag"> </span><span class="n" id="mwAak">vector</span><span class="o" id="mwAao"><</span><span class="n" id="mwAas">Point</span><span class="o" id="mwAaw">></span><span class="w" id="mwAa0"> </span><span class="o" id="mwAa4">&</span><span class="n" id="mwAa8">path</span><span class="p" id="mwAbA">)</span><span class="w" id="mwAbE"> </span><span class="p" id="mwAbI">{</span> <span class="w" id="mwAbM"> </span><span class="n" id="mwAbQ">printf</span><span class="p" id="mwAbU">(</span><span class="s" id="mwAbY">"%s = ["</span><span class="p" id="mwAbc">,</span><span class="w" id="mwAbg"> </span><span class="n" id="mwAbk">pathName</span><span class="p" id="mwAbo">.</span><span class="n" id="mwAbs">c_str</span><span class="p" id="mwAbw">());</span> <span class="w" id="mwAb0"> </span><span class="k" id="mwAb4">for</span><span class="w" id="mwAb8"> </span><span class="p" id="mwAcA">(</span><span class="kt" id="mwAcE">int</span><span class="w" id="mwAcI"> </span><span class="n" id="mwAcM">i</span><span class="w" id="mwAcQ"> </span><span class="o" id="mwAcU">=</span><span class="w" id="mwAcY"> </span><span class="mi" id="mwAcc">0</span><span class="p" id="mwAcg">;</span><span class="w" id="mwAck"> </span><span class="n" id="mwAco">i</span><span class="w" id="mwAcs"> </span><span class="o" id="mwAcw"><</span><span class="w" id="mwAc0"> </span><span class="n" id="mwAc4">path</span><span class="p" id="mwAc8">.</span><span class="n" id="mwAdA">size</span><span class="p" id="mwAdE">();</span><span class="w" id="mwAdI"> </span><span class="n" id="mwAdM">i</span><span class="o" id="mwAdQ">++</span><span class="p" id="mwAdU">)</span><span class="w" id="mwAdY"> </span><span class="p" id="mwAdc">{</span> <span class="w" id="mwAdg"> </span><span class="k" id="mwAdk">if</span><span class="w" id="mwAdo"> </span><span class="p" id="mwAds">(</span><span class="n" id="mwAdw">i</span><span class="w" id="mwAd0"> </span><span class="o" id="mwAd4">%</span><span class="w" id="mwAd8"> </span><span class="mi" id="mwAeA">10</span><span class="w" id="mwAeE"> </span><span class="o" id="mwAeI">==</span><span class="w" id="mwAeM"> </span><span class="mi" id="mwAeQ">0</span><span class="p" id="mwAeU">)</span><span class="w" id="mwAeY"> </span><span class="p" id="mwAec">{</span> <span class="w" id="mwAeg"> </span><span class="n" id="mwAek">printf</span><span class="p" id="mwAeo">(</span><span class="s" id="mwAes">"</span><span class="se" id="mwAew">\n</span><span class="s" id="mwAe0"> "</span><span class="p" id="mwAe4">);</span> <span class="w" id="mwAe8"> </span><span class="p" id="mwAfA">}</span> <span class="w" id="mwAfE"> </span><span class="k" id="mwAfI">if</span><span class="w" id="mwAfM"> </span><span class="p" id="mwAfQ">(</span><span class="n" id="mwAfU">i</span><span class="w" id="mwAfY"> </span><span class="o" id="mwAfc"><</span><span class="w" id="mwAfg"> </span><span class="n" id="mwAfk">path</span><span class="p" id="mwAfo">.</span><span class="n" id="mwAfs">size</span><span class="p" id="mwAfw">()</span><span class="w" id="mwAf0"> </span><span class="o" id="mwAf4">-</span><span class="w" id="mwAf8"> </span><span class="mi" id="mwAgA">1</span><span class="p" id="mwAgE">)</span><span class="w" id="mwAgI"> </span><span class="p" id="mwAgM">{</span> <span class="w" id="mwAgQ"> </span><span class="n" id="mwAgU">printf</span><span class="p" id="mwAgY">(</span><span class="s" id="mwAgc">"[%.1f, %.1f], "</span><span class="p" id="mwAgg">,</span><span class="w" id="mwAgk"> </span><span class="n" id="mwAgo">path</span><span class="p" id="mwAgs">[</span><span class="n" id="mwAgw">i</span><span class="p" id="mwAg0">].</span><span class="n" id="mwAg4">x</span><span class="p" id="mwAg8">,</span><span class="w" id="mwAhA"> </span><span class="n" id="mwAhE">path</span><span class="p" id="mwAhI">[</span><span class="n" id="mwAhM">i</span><span class="p" id="mwAhQ">].</span><span class="n" id="mwAhU">y</span><span class="p" id="mwAhY">);</span> <span class="w" id="mwAhc"> </span><span class="p" id="mwAhg">}</span><span class="w" id="mwAhk"> </span><span class="k" id="mwAho">else</span><span class="w" id="mwAhs"> </span><span class="p" id="mwAhw">{</span> <span class="w" id="mwAh0"> </span><span class="n" id="mwAh4">printf</span><span class="p" id="mwAh8">(</span><span class="s" id="mwAiA">"[%.1f, %.1f]"</span><span class="p" id="mwAiE">,</span><span class="w" id="mwAiI"> </span><span class="n" id="mwAiM">path</span><span class="p" id="mwAiQ">[</span><span class="n" id="mwAiU">i</span><span class="p" id="mwAiY">].</span><span class="n" id="mwAic">x</span><span class="p" id="mwAig">,</span><span class="w" id="mwAik"> </span><span class="n" id="mwAio">path</span><span class="p" id="mwAis">[</span><span class="n" id="mwAiw">i</span><span class="p" id="mwAi0">].</span><span class="n" id="mwAi4">y</span><span class="p" id="mwAi8">);</span> <span class="w" id="mwAjA"> </span><span class="p" id="mwAjE">}</span> <span class="w" id="mwAjI"> </span><span class="p" id="mwAjM">}</span> <span class="w" id="mwAjQ"> </span><span class="n" id="mwAjU">printf</span><span class="p" id="mwAjY">(</span><span class="s" id="mwAjc">"</span><span class="se" id="mwAjg">\n</span><span class="s" id="mwAjk">];</span><span class="se" id="mwAjo">\n</span><span class="s" id="mwAjs">"</span><span class="p" id="mwAjw">);</span> <span class="p" id="mwAj0">}</span> <span class="c1" id="mwAj4">// Create a path of length n with random points between 0 and 1000</span> <span class="n" id="mwAj8">vector</span><span class="o" id="mwAkA"><</span><span class="n" id="mwAkE">Point</span><span class="o" id="mwAkI">></span><span class="w" id="mwAkM"> </span><span class="n" id="mwAkQ">createRandomPath</span><span class="p" id="mwAkU">(</span><span class="kt" id="mwAkY">int</span><span class="w" id="mwAkc"> </span><span class="n" id="mwAkg">n</span><span class="p" id="mwAkk">)</span><span class="w" id="mwAko"> </span><span class="p" id="mwAks">{</span> <span class="w" id="mwAkw"> </span><span class="n" id="mwAk0">vector</span><span class="o" id="mwAk4"><</span><span class="n" id="mwAk8">Point</span><span class="o" id="mwAlA">></span><span class="w" id="mwAlE"> </span><span class="n" id="mwAlI">path</span><span class="p" id="mwAlM">;</span> <span class="w" id="mwAlQ"> </span><span class="k" id="mwAlU">for</span><span class="w" id="mwAlY"> </span><span class="p" id="mwAlc">(</span><span class="kt" id="mwAlg">int</span><span class="w" id="mwAlk"> </span><span class="n" id="mwAlo">i</span><span class="w" id="mwAls"> </span><span class="o" id="mwAlw">=</span><span class="w" id="mwAl0"> </span><span class="mi" id="mwAl4">0</span><span class="p" id="mwAl8">;</span><span class="w" id="mwAmA"> </span><span class="n" id="mwAmE">i</span><span class="w" id="mwAmI"> </span><span class="o" id="mwAmM"><</span><span class="w" id="mwAmQ"> </span><span class="n" id="mwAmU">n</span><span class="p" id="mwAmY">;</span><span class="w" id="mwAmc"> </span><span class="n" id="mwAmg">i</span><span class="o" id="mwAmk">++</span><span class="p" id="mwAmo">)</span><span class="w" id="mwAms"> </span><span class="p" id="mwAmw">{</span> <span class="w" id="mwAm0"> </span><span class="kt" id="mwAm4">float</span><span class="w" id="mwAm8"> </span><span class="n" id="mwAnA">x</span><span class="w" id="mwAnE"> </span><span class="o" id="mwAnI">=</span><span class="w" id="mwAnM"> </span><span class="p" id="mwAnQ">(</span><span class="kt" id="mwAnU">float</span><span class="p" id="mwAnY">)</span><span class="n" id="mwAnc">rand</span><span class="p" id="mwAng">()</span><span class="w" id="mwAnk"> </span><span class="o" id="mwAno">/</span><span class="w" id="mwAns"> </span><span class="p" id="mwAnw">(</span><span class="kt" id="mwAn0">float</span><span class="p" id="mwAn4">)(</span><span class="n" id="mwAn8">RAND_MAX</span><span class="w" id="mwAoA"> </span><span class="o" id="mwAoE">/</span><span class="w" id="mwAoI"> </span><span class="mi" id="mwAoM">1000</span><span class="p" id="mwAoQ">);</span> <span class="w" id="mwAoU"> </span><span class="kt" id="mwAoY">float</span><span class="w" id="mwAoc"> </span><span class="n" id="mwAog">y</span><span class="w" id="mwAok"> </span><span class="o" id="mwAoo">=</span><span class="w" id="mwAos"> </span><span class="p" id="mwAow">(</span><span class="kt" id="mwAo0">float</span><span class="p" id="mwAo4">)</span><span class="n" id="mwAo8">rand</span><span class="p" id="mwApA">()</span><span class="w" id="mwApE"> </span><span class="o" id="mwApI">/</span><span class="w" id="mwApM"> </span><span class="p" id="mwApQ">(</span><span class="kt" id="mwApU">float</span><span class="p" id="mwApY">)(</span><span class="n" id="mwApc">RAND_MAX</span><span class="w" id="mwApg"> </span><span class="o" id="mwApk">/</span><span class="w" id="mwApo"> </span><span class="mi" id="mwAps">1000</span><span class="p" id="mwApw">);</span> <span class="w" id="mwAp0"> </span><span class="n" id="mwAp4">path</span><span class="p" id="mwAp8">.</span><span class="n" id="mwAqA">push_back</span><span class="p" id="mwAqE">(</span><span class="n" id="mwAqI">Point</span><span class="p" id="mwAqM">(</span><span class="n" id="mwAqQ">x</span><span class="p" id="mwAqU">,</span><span class="w" id="mwAqY"> </span><span class="n" id="mwAqc">y</span><span class="p" id="mwAqg">));</span> <span class="w" id="mwAqk"> </span><span class="p" id="mwAqo">}</span> <span class="w" id="mwAqs"> </span><span class="k" id="mwAqw">return</span><span class="w" id="mwAq0"> </span><span class="n" id="mwAq4">path</span><span class="p" id="mwAq8">;</span> <span class="p" id="mwArA">}</span> <span class="kt" id="mwArE">int</span><span class="w" id="mwArI"> </span><span class="n" id="mwArM">main</span><span class="p" id="mwArQ">()</span><span class="w" id="mwArU"> </span><span class="p" id="mwArY">{</span> <span class="w" id="mwArc"> </span><span class="n" id="mwArg">vector</span><span class="o" id="mwArk"><</span><span class="n" id="mwAro">Point</span><span class="o" id="mwArs">></span><span class="w" id="mwArw"> </span><span class="n" id="mwAr0">path</span><span class="w" id="mwAr4"> </span><span class="o" id="mwAr8">=</span><span class="w" id="mwAsA"> </span><span class="n" id="mwAsE">createRandomPath</span><span class="p" id="mwAsI">(</span><span class="mi" id="mwAsM">100</span><span class="p" id="mwAsQ">);</span> <span class="w" id="mwAsU"> </span><span class="n" id="mwAsY">printPath</span><span class="p" id="mwAsc">(</span><span class="s" id="mwAsg">"path1"</span><span class="p" id="mwAsk">,</span><span class="w" id="mwAso"> </span><span class="n" id="mwAss">path</span><span class="p" id="mwAsw">);</span> <span class="w" id="mwAs0"> </span><span class="kt" id="mwAs4">float</span><span class="w" id="mwAs8"> </span><span class="n" id="mwAtA">curLength</span><span class="w" id="mwAtE"> </span><span class="o" id="mwAtI">=</span><span class="w" id="mwAtM"> </span><span class="n" id="mwAtQ">pathLength</span><span class="p" id="mwAtU">(</span><span class="n" id="mwAtY">path</span><span class="p" id="mwAtc">);</span> <span class="w" id="mwAtg"> </span><span class="n" id="mwAtk">printf</span><span class="p" id="mwAto">(</span><span class="s" id="mwAts">"path1len = %.1f;</span><span class="se" id="mwAtw">\n\n</span><span class="s" id="mwAt0">"</span><span class="p" id="mwAt4">,</span><span class="w" id="mwAt8"> </span><span class="n" id="mwAuA">curLength</span><span class="p" id="mwAuE">);</span> <span class="w" id="mwAuI"> </span><span class="kt" id="mwAuM">int</span><span class="w" id="mwAuQ"> </span><span class="n" id="mwAuU">n</span><span class="w" id="mwAuY"> </span><span class="o" id="mwAuc">=</span><span class="w" id="mwAug"> </span><span class="n" id="mwAuk">path</span><span class="p" id="mwAuo">.</span><span class="n" id="mwAus">size</span><span class="p" id="mwAuw">();</span> <span class="w" id="mwAu0"> </span><span class="kt" id="mwAu4">bool</span><span class="w" id="mwAu8"> </span><span class="n" id="mwAvA">foundImprovement</span><span class="w" id="mwAvE"> </span><span class="o" id="mwAvI">=</span><span class="w" id="mwAvM"> </span><span class="nb" id="mwAvQ">true</span><span class="p" id="mwAvU">;</span> <span class="w" id="mwAvY"> </span><span class="k" id="mwAvc">while</span><span class="w" id="mwAvg"> </span><span class="p" id="mwAvk">(</span><span class="n" id="mwAvo">foundImprovement</span><span class="p" id="mwAvs">)</span><span class="w" id="mwAvw"> </span><span class="p" id="mwAv0">{</span> <span class="w" id="mwAv4"> </span><span class="n" id="mwAv8">foundImprovement</span><span class="w" id="mwAwA"> </span><span class="o" id="mwAwE">=</span><span class="w" id="mwAwI"> </span><span class="nb" id="mwAwM">false</span><span class="p" id="mwAwQ">;</span> <span class="w" id="mwAwU"> </span><span class="k" id="mwAwY">for</span><span class="w" id="mwAwc"> </span><span class="p" id="mwAwg">(</span><span class="kt" id="mwAwk">int</span><span class="w" id="mwAwo"> </span><span class="n" id="mwAws">i</span><span class="w" id="mwAww"> </span><span class="o" id="mwAw0">=</span><span class="w" id="mwAw4"> </span><span class="mi" id="mwAw8">0</span><span class="p" id="mwAxA">;</span><span class="w" id="mwAxE"> </span><span class="n" id="mwAxI">i</span><span class="w" id="mwAxM"> </span><span class="o" id="mwAxQ"><</span><span class="w" id="mwAxU"> </span><span class="n" id="mwAxY">n</span><span class="w" id="mwAxc"> </span><span class="o" id="mwAxg">-</span><span class="w" id="mwAxk"> </span><span class="mi" id="mwAxo">1</span><span class="p" id="mwAxs">;</span><span class="w" id="mwAxw"> </span><span class="n" id="mwAx0">i</span><span class="o" id="mwAx4">++</span><span class="p" id="mwAx8">)</span><span class="w" id="mwAyA"> </span><span class="p" id="mwAyE">{</span> <span class="w" id="mwAyI"> </span><span class="k" id="mwAyM">for</span><span class="w" id="mwAyQ"> </span><span class="p" id="mwAyU">(</span><span class="kt" id="mwAyY">int</span><span class="w" id="mwAyc"> </span><span class="n" id="mwAyg">j</span><span class="w" id="mwAyk"> </span><span class="o" id="mwAyo">=</span><span class="w" id="mwAys"> </span><span class="n" id="mwAyw">i</span><span class="w" id="mwAy0"> </span><span class="o" id="mwAy4">+</span><span class="w" id="mwAy8"> </span><span class="mi" id="mwAzA">2</span><span class="p" id="mwAzE">;</span><span class="w" id="mwAzI"> </span><span class="n" id="mwAzM">j</span><span class="w" id="mwAzQ"> </span><span class="o" id="mwAzU"><</span><span class="w" id="mwAzY"> </span><span class="n" id="mwAzc">n</span><span class="p" id="mwAzg">;</span><span class="w" id="mwAzk"> </span><span class="n" id="mwAzo">j</span><span class="o" id="mwAzs">++</span><span class="p" id="mwAzw">)</span><span class="w" id="mwAz0"> </span><span class="p" id="mwAz4">{</span> <span class="w" id="mwAz8"> </span><span class="kt" id="mwA0A">float</span><span class="w" id="mwA0E"> </span><span class="n" id="mwA0I">lengthDelta</span><span class="w" id="mwA0M"> </span><span class="o" id="mwA0Q">=</span> <span class="w" id="mwA0U"> </span><span class="o" id="mwA0Y">-</span><span class="n" id="mwA0c">path</span><span class="p" id="mwA0g">[</span><span class="n" id="mwA0k">i</span><span class="p" id="mwA0o">].</span><span class="n" id="mwA0s">dist</span><span class="p" id="mwA0w">(</span><span class="n" id="mwA00">path</span><span class="p" id="mwA04">[</span><span class="n" id="mwA08">i</span><span class="w" id="mwA1A"> </span><span class="o" id="mwA1E">+</span><span class="w" id="mwA1I"> </span><span class="mi" id="mwA1M">1</span><span class="p" id="mwA1Q">])</span><span class="w" id="mwA1U"> </span><span class="o" id="mwA1Y">-</span><span class="w" id="mwA1c"> </span><span class="n" id="mwA1g">path</span><span class="p" id="mwA1k">[</span><span class="n" id="mwA1o">j</span><span class="p" id="mwA1s">].</span><span class="n" id="mwA1w">dist</span><span class="p" id="mwA10">(</span><span class="n" id="mwA14">path</span><span class="p" id="mwA18">[(</span><span class="n" id="mwA2A">j</span><span class="w" id="mwA2E"> </span><span class="o" id="mwA2I">+</span><span class="w" id="mwA2M"> </span><span class="mi" id="mwA2Q">1</span><span class="p" id="mwA2U">)</span><span class="w" id="mwA2Y"> </span><span class="o" id="mwA2c">%</span><span class="w" id="mwA2g"> </span><span class="n" id="mwA2k">n</span><span class="p" id="mwA2o">])</span><span class="w" id="mwA2s"> </span><span class="o" id="mwA2w">+</span> <span class="w" id="mwA20"> </span><span class="n" id="mwA24">path</span><span class="p" id="mwA28">[</span><span class="n" id="mwA3A">i</span><span class="p" id="mwA3E">].</span><span class="n" id="mwA3I">dist</span><span class="p" id="mwA3M">(</span><span class="n" id="mwA3Q">path</span><span class="p" id="mwA3U">[</span><span class="n" id="mwA3Y">j</span><span class="p" id="mwA3c">])</span><span class="w" id="mwA3g"> </span><span class="o" id="mwA3k">+</span><span class="w" id="mwA3o"> </span><span class="n" id="mwA3s">path</span><span class="p" id="mwA3w">[</span><span class="n" id="mwA30">i</span><span class="w" id="mwA34"> </span><span class="o" id="mwA38">+</span><span class="w" id="mwA4A"> </span><span class="mi" id="mwA4E">1</span><span class="p" id="mwA4I">].</span><span class="n" id="mwA4M">dist</span><span class="p" id="mwA4Q">(</span><span class="n" id="mwA4U">path</span><span class="p" id="mwA4Y">[(</span><span class="n" id="mwA4c">j</span><span class="w" id="mwA4g"> </span><span class="o" id="mwA4k">+</span><span class="w" id="mwA4o"> </span><span class="mi" id="mwA4s">1</span><span class="p" id="mwA4w">)</span><span class="w" id="mwA40"> </span><span class="o" id="mwA44">%</span><span class="w" id="mwA48"> </span><span class="n" id="mwA5A">n</span><span class="p" id="mwA5E">]);</span> <span class="w" id="mwA5I"> </span><span class="c1" id="mwA5M">// If the length of the path is reduced, do a 2-opt swap</span> <span class="w" id="mwA5Q"> </span><span class="k" id="mwA5U">if</span><span class="w" id="mwA5Y"> </span><span class="p" id="mwA5c">(</span><span class="n" id="mwA5g">lengthDelta</span><span class="w" id="mwA5k"> </span><span class="o" id="mwA5o"><</span><span class="w" id="mwA5s"> </span><span class="mi" id="mwA5w">0</span><span class="p" id="mwA50">)</span><span class="w" id="mwA54"> </span><span class="p" id="mwA58">{</span> <span class="w" id="mwA6A"> </span><span class="n" id="mwA6E">swap_edges</span><span class="p" id="mwA6I">(</span><span class="n" id="mwA6M">path</span><span class="p" id="mwA6Q">,</span><span class="w" id="mwA6U"> </span><span class="n" id="mwA6Y">i</span><span class="p" id="mwA6c">,</span><span class="w" id="mwA6g"> </span><span class="n" id="mwA6k">j</span><span class="p" id="mwA6o">);</span> <span class="w" id="mwA6s"> </span><span class="n" id="mwA6w">curLength</span><span class="w" id="mwA60"> </span><span class="o" id="mwA64">+=</span><span class="w" id="mwA68"> </span><span class="n" id="mwA7A">lengthDelta</span><span class="p" id="mwA7E">;</span> <span class="w" id="mwA7I"> </span><span class="n" id="mwA7M">foundImprovement</span><span class="w" id="mwA7Q"> </span><span class="o" id="mwA7U">=</span><span class="w" id="mwA7Y"> </span><span class="nb" id="mwA7c">true</span><span class="p" id="mwA7g">;</span> <span class="w" id="mwA7k"> </span><span class="p" id="mwA7o">}</span> <span class="w" id="mwA7s"> </span><span class="p" id="mwA7w">}</span> <span class="w" id="mwA70"> </span><span class="p" id="mwA74">}</span> <span class="w" id="mwA78"> </span><span class="p" id="mwA8A">}</span> <span class="w" id="mwA8E"> </span><span class="n" id="mwA8I">printPath</span><span class="p" id="mwA8M">(</span><span class="s" id="mwA8Q">"path2"</span><span class="p" id="mwA8U">,</span><span class="w" id="mwA8Y"> </span><span class="n" id="mwA8c">path</span><span class="p" id="mwA8g">);</span> <span class="w" id="mwA8k"> </span><span class="n" id="mwA8o">printf</span><span class="p" id="mwA8s">(</span><span class="s" id="mwA8w">"path2len = %.1f;</span><span class="se" id="mwA80">\n</span><span class="s" id="mwA84">"</span><span class="p" id="mwA88">,</span><span class="w" id="mwA9A"> </span><span class="n" id="mwA9E">curLength</span><span class="p" id="mwA9I">);</span> <span class="w" id="mwA9M"> </span><span class="k" id="mwA9Q">return</span><span class="w" id="mwA9U"> </span><span class="mi" id="mwA9Y">0</span><span class="p" id="mwA9c">;</span> <span class="p" id="mwA9g">}</span>Output
<span id="mwA9w"></span><span class="go" id="mwA90">path1 = [</span> <span class="go" id="mwA94"> [0.0, 131.5], [755.6, 458.7], [532.8, 219.0], [47.0, 678.9], [679.3, 934.7], [383.5, 519.4], [831.0, 34.6], [53.5, 529.7], [671.1, 7.7], [383.4, 66.8], </span> <span class="go" id="mwA98"> [417.5, 686.8], [589.0, 930.4], [846.2, 526.9], [92.0, 653.9], [416.0, 701.2], [910.3, 762.2], [262.5, 47.5], [736.1, 328.2], [632.6, 756.4], [991.0, 365.3], </span> <span class="go" id="mwA-A"> [247.0, 982.6], [722.7, 753.4], [651.5, 72.7], [631.6, 884.7], [272.7, 436.4], [766.5, 477.7], [237.8, 274.9], [359.3, 166.5], [486.5, 897.7], [909.2, 60.6], </span> <span class="go" id="mwA-E"> [904.7, 504.5], [516.3, 319.0], [986.6, 494.0], [266.1, 90.7], [947.8, 73.7], [500.7, 384.1], [277.1, 913.8], [529.7, 464.4], [941.0, 50.1], [761.5, 770.2], </span> <span class="go" id="mwA-I"> [827.8, 125.4], [15.9, 688.5], [868.2, 629.5], [736.2, 725.4], [999.5, 888.6], [233.2, 306.3], [351.0, 513.3], [591.1, 846.0], [412.1, 841.5], [269.3, 415.4], </span> <span class="go" id="mwA-M"> [537.3, 467.9], [287.2, 178.3], [153.7, 571.7], [802.4, 33.1], [534.4, 498.5], [955.4, 748.3], [554.6, 890.7], [624.8, 842.0], [159.8, 212.8], [714.7, 130.4], </span> <span class="go" id="mwA-Q"> [91.0, 274.6], [3.0, 414.3], [26.9, 709.8], [937.9, 239.9], [180.9, 317.5], [887.0, 652.1], [150.3, 681.3], [385.8, 387.7], [499.7, 147.5], [587.2, 845.6], </span> <span class="go" id="mwA-U"> [590.1, 955.4], [556.1, 148.2], [983.3, 408.8], [141.8, 564.9], [252.1, 488.5], [464.0, 961.1], [126.0, 199.8], [319.2, 629.3], [126.7, 651.3], [621.6, 803.1], </span> <span class="go" id="mwA-Y"> [247.8, 476.4], [389.3, 203.3], [28.4, 901.7], [426.5, 142.0], [947.5, 410.3], [131.2, 885.6], [92.2, 162.2], [71.1, 365.3], [253.1, 135.1], [783.2, 455.3], </span> <span class="go" id="mwA-c"> [349.5, 452.3], [808.9, 931.7], [651.6, 215.2], [679.6, 908.9], [250.1, 860.9], [471.3, 506.0], [600.4, 817.6], [755.8, 462.2], [951.4, 632.7], [439.3, 824.7]</span> <span class="go" id="mwA-g">];</span> <span class="go" id="mwA-k">path1len = 55723.0;</span> <span class="go" id="mwA-o">path2 = [</span> <span class="go" id="mwA-s"> [0.0, 131.5], [91.0, 274.6], [71.1, 365.3], [3.0, 414.3], [53.5, 529.7], [92.0, 653.9], [47.0, 678.9], [15.9, 688.5], [26.9, 709.8], [28.4, 901.7], </span> <span class="go" id="mwA-w"> [131.2, 885.6], [247.0, 982.6], [277.1, 913.8], [464.0, 961.1], [486.5, 897.7], [439.3, 824.7], [412.1, 841.5], [250.1, 860.9], [150.3, 681.3], [126.7, 651.3], </span> <span class="go" id="mwA-0"> [141.8, 564.9], [153.7, 571.7], [247.8, 476.4], [252.1, 488.5], [319.2, 629.3], [416.0, 701.2], [417.5, 686.8], [534.4, 498.5], [537.3, 467.9], [529.7, 464.4], </span> <span class="go" id="mwA-4"> [516.3, 319.0], [500.7, 384.1], [471.3, 506.0], [383.5, 519.4], [351.0, 513.3], [349.5, 452.3], [385.8, 387.7], [272.7, 436.4], [269.3, 415.4], [180.9, 317.5], </span> <span class="go" id="mwA-8"> [233.2, 306.3], [237.8, 274.9], [287.2, 178.3], [389.3, 203.3], [532.8, 219.0], [736.1, 328.2], [783.2, 455.3], [755.6, 458.7], [755.8, 462.2], [766.5, 477.7], </span> <span class="go" id="mwA_A"> [846.2, 526.9], [904.7, 504.5], [868.2, 629.5], [736.2, 725.4], [761.5, 770.2], [722.7, 753.4], [632.6, 756.4], [621.6, 803.1], [600.4, 817.6], [624.8, 842.0], </span> <span class="go" id="mwA_E"> [631.6, 884.7], [591.1, 846.0], [587.2, 845.6], [554.6, 890.7], [589.0, 930.4], [590.1, 955.4], [679.3, 934.7], [679.6, 908.9], [808.9, 931.7], [999.5, 888.6], </span> <span class="go" id="mwA_I"> [955.4, 748.3], [910.3, 762.2], [887.0, 652.1], [951.4, 632.7], [986.6, 494.0], [947.5, 410.3], [983.3, 408.8], [991.0, 365.3], [937.9, 239.9], [827.8, 125.4], </span> <span class="go" id="mwA_M"> [947.8, 73.7], [941.0, 50.1], [909.2, 60.6], [831.0, 34.6], [802.4, 33.1], [671.1, 7.7], [651.5, 72.7], [714.7, 130.4], [651.6, 215.2], [556.1, 148.2], </span> <span class="go" id="mwA_Q"> [499.7, 147.5], [426.5, 142.0], [359.3, 166.5], [383.4, 66.8], [262.5, 47.5], [266.1, 90.7], [253.1, 135.1], [159.8, 212.8], [126.0, 199.8], [92.2, 162.2]</span> <span class="go" id="mwA_U">];</span> <span class="go" id="mwA_Y">path2len = 8586.2;</span>

