ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## 3.6 The Traveling Salesperson Problem Suppose a salesperson is planning a sales trip that includes 20 cities. Each city is connected to some of the other cities by a road. To minimize travel time, we want to determine a shortest route that starts at the salesperson's home city, visits each of the cities once, and ends up at the home city. This problem of determining a shortest route is called the Traveling Salesperson problem. An instance of this problem can be represented by a weighted graph, in which each vertex represents a city. As in [Section 3.2](LiB0026.html#265), we generalize the problem to include the case in which the weight (distance) going in one direction can be different from the weight going in another direction. Again we assume that the weights are nonnegative numbers. [Figures 3.2](LiB0026.html#267) and [Figures 3.16](#ch03fig16) show such weighted graphs. A ***tour*** (also called a *Hamiltonian circuit*) in a directed graph is a path from a vertex to itself that passes through each of the other vertices exactly once. An ***optimal tour*** in a weighted, directed graph is such a path of minimum length. The Traveling Salesperson problem is to find an optimal tour in a weighted, directed graph when at least one tour exists. Because the starting vertex is irrelevant to the length of an optimal tour, we will consider *v*1 to be the starting vertex. The following are the three tours and lengths for the graph in [Figure 3.16](#ch03fig16): ![](https://box.kancloud.cn/48c00f619f96ce31ee2eff4cf3db61c4_260x87.jpg) [![Click To expand](https://box.kancloud.cn/bf9cb46cce672a1fd3da9a8ea43d40b7_259x264.jpg)](fig3-16_0.jpg) Figure 3.16: The optimal tour is \[*v1*, *v3*, *v4*, *v2*, *v1*\]. The last tour is optimal. We solved this instance by simply considering all possible tours. In general, there can be an edge from every vertex to every other vertex. If we consider all possible tours, the second vertex on the tour can be any of *n* − 1 vertices, the third vertex on the tour can be any of *n* − 2 vertices, …, the *n*th vertex on the tour can be only one vertex. Therefore, the total number of tours is ![](https://box.kancloud.cn/acc3033be45d1d4fcc5e7c84e1f50acc_276x25.jpg) which is worse than exponential. Can dynamic programming be applied to this problem? Notice that if *vk* is the first vertex after *v*1 on an optimal tour, the subpath of that tour from *vk* to *v*1 must be a shortest path from *vk* to *v*1 that passes through each of the other vertices exactly once. This means that the principle of optimality applies, and we can use dynamic programming. To that end, we represent the graph by an adjacency matrix *W*, as was done in [Section 3.2](LiB0026.html#265). [Figure 3.17](#ch03fig17) shows the adjacency matrix representation of the graph in [Figure 3.16](#ch03fig16). Let ![](https://box.kancloud.cn/787eb5799e08fef5bc36b1424cf22600_400x82.jpg) [![Click To expand](https://box.kancloud.cn/40746ef9a8be5d65889335ed2f921d04_230x231.jpg)](fig3-17_0.jpg) Figure 3.17: The adjacency matrix representation *W* of the graph in [Figure 3.16](#ch03fig16). Example 3.10**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**For the graph in [Figure 3.16](#ch03fig16), ![](https://box.kancloud.cn/95f81a11728a1503a0275dddad8d581a_178x25.jpg) Notice that {*v*1, *v*2, *v*3, *v*4} uses curly braces to represent a set, whereas \[*v*1, *v*2, *v*3, *v*4\] uses square brackets to represent a path. If *A* = {*v*3}, then ![](https://box.kancloud.cn/4700535dc68d127313fa58a90d8839d3_259x57.jpg) If A = {*v*3, *v*4}, then ![](https://box.kancloud.cn/172b57d5d060500d51870258655decbf_400x38.jpg) **![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)** Because *V* − {*v*1, *vj*} contains all the vertices except *v*1 and *vj* and the principle of optimality applies, we have ![](https://box.kancloud.cn/42d165f43228bcebbd8030b9074ed3da_400x24.jpg) and, in general for *i* ≠ 1 and *vi* not in *A*, ![](https://box.kancloud.cn/dc3192d00e56fdfef4ce1a75b6cfd88f_400x57.jpg) We can create a dynamic programming algorithm for the Traveling Salesperson problem using Equality 3.7. But first, let's illustrate how the algorithm would proceed. Example 3.11**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**Determine an optimal tour for the graph represented in [Figure 3.17](#ch03fig17). First consider the empty set: ![](https://box.kancloud.cn/a62d7db04701d84504ec4b010c94bf39_132x87.jpg) Next consider all sets containing one element: ![](https://box.kancloud.cn/857b5aec179fca4f0b2a140ede5d93c9_400x62.jpg) Similarly, ![](https://box.kancloud.cn/c30453d6bfd32348800bf8926b6df569_249x149.jpg) Next consider all sets containing two elements: ![](https://box.kancloud.cn/b681e0c53a08b7a1020eee72fb54c032_400x65.jpg) Similarly, ![](https://box.kancloud.cn/03a44ce0f3956689ecb188ff65f6941f_400x51.jpg) Finally, compute the length of an optimal tour: ![](https://box.kancloud.cn/22ad9e87d1d7b51af9c6fc1fb8fa27ae_400x108.jpg) **![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)** The dynamic programming algorithm for the Traveling Salesperson problem follows. Algorithm 3.11: The Dynamic Programming Algorithm for the Traveling Salesperson Problem**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**Problem: Determine an optimal tour in a weighted, directed graph. The weights are nonnegative numbers. Inputs: a weighted, directed graph, and *n*, the number of vertices in the graph. The graph is represented by a two-dimensional array *W*, which has both its rows and columns indexed from 1 to *n*, where *W* \[*i*\] \[*j*\] is the weight on the edge from *i*th vertex to the *j*th vertex. Outputs: a variable *minlength*, whose value is the length of an optimal tour, and a two-dimensional array *P* from which an optimal tour can be constructed. *P* has its rows indexed from 1 to *n* and its columns indexed by all subsets of *V* − {*v*1}. *P* \[*i*\] \[*A*\] is the index of the first vertex after *vi* on a shortest path from *vi* to *v*1 that passes through all the vertices in *A* exactly once. ``` void travel (int n, const number W [] [], index P [] [], number & minlength) { index i, j, k; number D [1 .. n] [subset of V - {v1}]; for (i = 2; i <= n; i++) D [i] [⊘] = W[i] [1]; for (k = 1; k <= n - 2; k++) for (all subsets A ⊆ V - {v1} containing k vertices) for (i such that i ≠ 1 and vi is not in A){ D [i] [A] = minimum (W [i] [j] + D [j [A - {vj}]); j: [vj ∊ A P[i] [A] = value of j that gave the minimum; } D [1] [V - {v1}] = minimum (W[1] [j] + D[j] [V - {v1, vj}]); 2 ≤ j ≤ n P[1] [V - {v1}] = value of j that gave the minimum; minlength = D[1] [V - {v1}]; } ``` **![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)** Before showing how an optimal tour can be obtained from the array *P*, we analyze the algorithm. First we need a theorem: Theorem 3.1**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**For all *n* ≤ 1 ![](https://box.kancloud.cn/3836553667c193dbb7ee6e4778168a02_152x54.jpg) Proof: It is left as an exercise to show that ![](https://box.kancloud.cn/20bbbd2b5b256a0d99091c6083e7e0b5_158x47.jpg) Therefore, ![](https://box.kancloud.cn/ef28fa533c6b97a1f33dc4d44f4a87ee_202x142.jpg) The last equality is obtained by applying the result found in [Example A.10](LiB0099.html#1326) in [Appendix A](LiB0093.html#1281). **![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)** The analysis of [Algorithm 3.11](#ch03ex22) follows. **![Start Sidebar](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**Analysis of Algorithm 3.11 Every-Case Time and Space Complexity (The Dynamic Programming Algorithm for the Traveling Salesperson Problem)Basic operation: The time in both the first and last loops is insignificant compared to the time in the middle loop because the middle loop contains various levels of nesting. Therefore, we will consider the instructions executed for each value of *vj* to be the basic operation. They include an addition instruction. Input size: *n*, the number of vertices in the graph. For each set *A* containing *k* vertices, we must consider *n* − 1 − *k* vertices, and for each of these vertices, the basic operation is done *k* times. Because the number of subsets *A* of *V* − {*v*1} containing *k* vertices is equal to ![](https://box.kancloud.cn/31806ded683946fa614cf8647ad4c74f_48x26.jpg), the total number of times the basic operation is done is given by ![](https://box.kancloud.cn/548e48d27bc86f115d4cbfbeb9e58bdc_400x55.jpg) It is not hard to show that ![](https://box.kancloud.cn/e9dfe3927b2033efc159af4ab3550b0a_314x46.jpg) Substituting this equality into Equality 3.8, we have ![](https://box.kancloud.cn/797e415294ad3fd2607c357877bdb2c2_236x56.jpg) Finally, applying [Theorem 3.1](#ch03ex23), we have ![](https://box.kancloud.cn/e3ad072eef20d3d8bff22ada1ac53e17_321x26.jpg) Because the memory used in this algorithm is also large, we will analyze the memory complexity, which we call *M* (*n*). The memory used to store the arrays *D* \[*vi*\] \[*A*\] and *P* \[*vi*\] \[*A*\] is clearly the dominant amount of memory. So we will determine how large these arrays must be. Because *V* − {*v*1} contains *n* − 1 vertices, we can apply the result in [Example A.10](LiB0099.html#1326) in [Appendix A](LiB0093.html#1281) to conclude that it has 2*n*−1 subsets *A.* The first index of the arrays *D* and *P* ranges in value between 1 and *n.* Therefore, ![](https://box.kancloud.cn/8b2f505bfa5fd3a63979cb2dc8522cc2_294x24.jpg) **![End Sidebar](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)** At this point you may be wondering what we have gained, because our new algorithm is still Θ (*n*22*n*). The following example shows that even an algorithm with this time complexity can sometimes be useful. Example 3.12**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**Ralph and Nancy are both competing for the same sales position. The boss tells them on Friday that, starting on Monday, whoever can cover the entire 20-city territory faster will get the position. The territory includes the home office, and they must return to the home office when they are done. There is a road from every city to every other city. Ralph figures he has the whole weekend to determine his route; so he simply runs the brute-force algorithm that considers all (20 − 1)! tours on his computer. Nancy recalls the dynamic programming algorithm from her algorithms course. Figuring she should take every advantage she can, she runs that algorithm on her computer. Assuming that the time to process the basic instruction in Nancy's algorithm is 1 microsecond, and that it takes 1 microsecond for Ralph's algorithm to compute the length of each tour, the time taken by each algorithm is given approximately by the following: ![](https://box.kancloud.cn/088931ec8527c83df52d56756ee5da14_343x20.jpg) Dynamic programming algorithm: (20 − 1) (20 − 2) 220−3μs = 45 seconds. We see that even a Θ (*n*22*n*) algorithm can be useful when the alternative is a factorial-time algorithm. The memory used by the dynamic programming algorithm in this example is ![](https://box.kancloud.cn/0a7606ab89590358eb9660921fad188d_271x24.jpg) Although this is quite large, it is feasible by today's standards. Using the Θ (*n*22*n*) algorithm to find the optimal tour is practical only because *n* is small. If, for example, there were 60 cities, that algorithm, too, would take many years. **![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)** Let's discuss how to retrieve an optimal tour from the array *P.* We don't give the algorithm; rather, we simply illustrate how it would proceed. The members of the array *P* needed to determine an optimal tour for the graph represented in [Figure 3.16](#ch03fig16) are: ![](https://box.kancloud.cn/67524de9ce3bcd2026e4e0438a3d48b9_400x51.jpg) We obtain an optimal tour as follows: ![](https://box.kancloud.cn/405e65491f30d744c6f05fab479fb94f_337x163.jpg) The optimal tour is, therefore, ![](https://box.kancloud.cn/250c1b4e28529282fca66bf7badc3ed1_134x22.jpg) No one has ever found an algorithm for the Traveling Salesperson problem whose worst-case time complexity is better than exponential. Yet no one has ever proved that such an algorithm is not possible. This problem is one of a large class of closely related problems that share this property and are the focus of [Chapter 9](LiB0074.html#880).