The Traveling Salesman Problem David S. Johnson Visiting Professor dstiflerj@gmail.com Seeley Mudd...

Preview:

Citation preview

The Traveling Salesman Problem

David S. JohnsonVisiting Professor

dstiflerj@gmail.comhttp://davidsjohnson.net

Seeley Mudd 523, Tuesdays and Fridays

The Traveling Salesman Problem

Given:Set of cities {c1,c2,…,cN }.

For each pair of cities {ci,cj}, a distance d(ci,cj).

Find: Permutation that

minimizes

)c,d(c)c,d(c π(1)π(N)

1N

1i1)π(iπ(i)

N}{1,2,...,N}{1,2,...,:π

N = 10

N = 10

N = 100

N = 1,000

N = 10,000

N = 100,000

Application #1

• Cities:

– Holes to be drilled in printed circuit boards

N = 2392

Application #2

• Cities:

– Wires to be cut in a “Laser Logic” programmable circuit

N = 7397

N = 33,810

N = 85,900

Other Types of Instances

• X-ray crystallography – Cities: orientations of a crystal– Distances: time for motors to rotate the crystal

from one orientation to the other

• High-definition video compression– Cities: binary vectors of length 64 identifying

the summands for a particular function– Distances: Hamming distance (the number of

terms that need to be added/subtracted to get the next sum)

Key Fact about the TSP

It is NP-Complete.

P = Set of Decision problems (ones with yes-no answers) that can be solved in polynomial time.

– O(N), O(NlogN), O(N2), O(N3), …, O(N100), …

NP = Set of Decision problems such that, if the answer is yes, there exists a proof of that fact that can be verified in polynomial time.

Example: Decision problem version of the TSP.

• Given an integer k and a TSP instance with integer distances, is there a tour of length k or less?

Definitions

Still an Open Question:

Does P = NP?

Note: If you can provide a valid proof of the answer, you will win fame and fortune ($1,000,000 from the Clay Institute)

To learn more about NP-Completeness:

Obstacle to Getting Close• Theorem [Karp, 1972]: Given a graph G = (V,E), it is

NP-hard to determine whether G contains a Hamiltonian circuit (collections of edges that make up a tour).

• Given a graph, construct a TSP instance in which

d(c,c’) =

• If Hamiltonian circuit exists, OPT = N, if not, OPT > N2N.

• A polynomial-time approximation algorithm that guaranteed a tour of length no more than 2NOPT would imply P = NP.

1 if {c,c’} is in EN2N if {c,c’} is not in E{

Saving Grace from the Real World

The Triangle Inequality

For any three cities c1, c2, and c3,

d(c1,c2) ≤ d(c1,c3) + d(c3,c2).

c1

c3

c2

Nearest Neighbor (NN):1. Start with some city.

2. Repeatedly go next to the nearest unvisited neighbor of the last city added.

3. When all cities have been added, go from the last back to the first.

NN Running Time

• To find the kth vertex, k > 1, find the shortest distance among N-k-1 candidates.

• Total time = Θ( ) = Θ(N2)

• Theorem 1 [Rosenkrantz, Stearns, & Lewis,

1977]:

There exists a constant c, such that for all N > 3, there are N-city instances I obeying the triangle inequality for which we have

NN(I) > clog(N)Opt(I).

Lower Bound Examples(Unspecified distances determined by shortest paths)

F1

:

F2:

Number N1 of vertices = 3

OPT(F1) = 3+ε

NN(F1) = 3+ε1+ε

1

1

1+ε 1 1+ε 1+ε 1

1

1+ε 1

2 2

1

1

N2 = 2N1 + 3 = 9

OPT(F1) = N2+5ε = 9+5ε

NN(F2) = 14+2ε

1+ε4+2ε

Fk: 1+ε

1 1+ε

1

2k-1

1+ε

Fk-1 without shortcut between left and right endpoints

2k-1

• Theorem 2 [Rosenkrantz, Stearns, & Lewis,

1977]:

There exists a constant c, such that if instance I obeys the triangle inequality, then we have

NN(I) ≤ clog(N)Opt(I).

Corollary. For any algorithm A, let

RN(A) = max{A(I)/OPT(I): I is an N-city instance}

Then RN(NN) = Θ(log(N)) (worst-case ratio)

Nearest Insertion (NI):1. Start with 2-city tour consisting of some city and its

nearest neighbor.

2. Repeatedly insert the non-tour city u that is closest to a tour city v into the tour edge yields the smallest increase in tour length.

• Theorem 3 [Rosenkrantz, Stearns, & Lewis,

1977]:

For all instances I that obey the triangle inequality, we have

NI(I) ≤ 2Opt(I).

and R(NI) = 2.

Exploiting Triangle Inequality Directly

• Observation 1: Any connected graph in which every vertex has even degree contains an “Euler Tour” – a cycle that traverses each edge exactly once, which can be found in linear time.

• Observation 2: If the Δ-inequality holds, then traversing an Euler tour but skipping past previously-visited vertices yields a Traveling Salesman tour of no greater length.

Obtaining the Initial Graph

• Double MST algorithm (DMST):– Combine two copies of a Minimum Spanning

Tree.

– Theorem [Folklore]: DMST(I) ≤ 2Opt(I).

• Christofides algorithm (CH):– Combine one copy of an MST with a minimum-

length matching on its odd-degree vertices (there must be an even number of them since the total sum of degrees for any graph is even).

– Theorem [Christofides, 1976]: CH(I) ≤ 1.5Opt(I).

Optimal Tour on Odd-Degree Vertices(No longer than overall Optimal Tour

by the triangle inequality)

Matching M1 Matching M2+ = Optimal Tour

Hence Optimal Matching ≤ min(M1,M2) ≤ OPT(I)/2

Results for Random Euclidean Instances

Nearest Neighbor

2-Opt

3-Opt

Smart-Shortcut Christofides

Local Optimization: 2-Opt

Determining the existence of an Improving 2-Opt move

• Naïve approach: Try all N(N-3)/2 possibilities.• More sophisticated: Observe that one of the following must

be true: d(a,b) > d(b,c) or d(c,d) > d(d,a).

Suppose we consider each ordered pair (t1,t2) of adjacent tour vertices as candidates for the first deleted edge in an improving 2-opt move. Then we may restrict our attention to candidates for the new neighbor t3 of t2 that satisfy d(t2,t3) < d(t1,t2).

If the improving move to the left is not caught when (t1,t2) = (a,b), it will be caught when (t1,t2) = (c,d).

The Neighbor-List Implementation

• Basic idea: Precompute, for each city, a list of the k ≤ N-1 closest other cities, ordered by increasing distance, and also store the corresponding distances.

• Then, when looking for 2-opt moves that break the ordered tour

edge (t1,t2), we can restrict attention to the first part of the list, up

to the last city t with d(t2,t) < d(t2,t1).

• If we set k < N-1, we save space and time at the cost of no longer guaranteeing that we end up with a solution that is 2-optimal.

• Takes Θ(N2log(k)) time and O(kN) space.

• For geometric instances, we can speed this up to O(N(logN +

logk)) using kd-trees.

• My Default: Take k = 20.

Basic SchemeFor the current choice of t1, try both possible choices for t2.

If no improving move is found, go on to the next choice of t1.

If an improving move is found, make it, and then go on to the next choice for t1.

• We go for speed, even though this is not necessarily best (or fastest) in the long run.

• Results: Averages roughly 5% above Held-Karp Bound (which itself is typically 0.5% below the optimal tour length)

N 103 104 105 106

Seconds 0.17 2.2 47.5 2754

Running Time on a 150Mhz Machine from 1994.

Tour Representations

Must maintain a consistent ordering of the tour so that the following operations can be correctly performed.

1. Next(a) and Prev(a): Return the successor/predecessor of city a in the current ordering of the tour.

Tour Representations

Must maintain a consistent ordering of the tour so that the following operations can be correctly performed.

1. Next(a) and Prev(a): Return the successor/predecessor of city a in the current ordering of the tour.

2. Flip(a,b,c,d): If b = Next(a) and c = Next(d), update the tour to reflect the 2-opt move in which the tour edges (a,b) and (c,d) are replaced by (b,c) and (a,d). Otherwise, report “Invalid Move”.

Array Representation

a b c d e f g h i j k l m n o p q r s t u v w x y zTour

Array of City Indices

City

Array of Tour Indices

Next(ci) = Tour[City[i]+1(mod N)]

Prev(ci) = Tour[City[i]-1(mod N)] (analogous)

Array Representation: Flip

a b c d e f g h i j k l m n o p q r s t u v w x y zTour

Flip(f,g,p,q)

a b c d e f p o n m l k j i h g q r s t u v w x y z

Flip(x,y,c,d)

a z y d e f p o n m l k j i h g q r s t u v w x c b

Array Representation: Costs

• Next, Prev: O(1)

• Flip:θ(N)

Speed-up trick: If the segment to be flipped is greater than N/2, flip its complement.

Problem for Arrays• For random Euclidean instances, 2-opt performs θ(N) moves and, even

if we always flip the shorter segment, the average length of the segment being flipped, grows roughly as θ(N0.7) [Bentley, 1992].

• Doubly-linked lists suffer from the same problems. Can we do better with other tour representations?

• We can in fact do much better (theoretically).

• By representing the tour using a balanced binary tree, we can reduce the (amortized) time for Between and Flip to θ(log(N)) per operation, although the times for Next and Prev increase from constant to that amount. “Splay Trees” are especially useful in this context (and will be described in the next few slides).

• Significant further improvements are unlikely, however:

• Theorem [Fredman et al., 1995]. In the cell-probe model of computation, any tour representation must, in the worst case, take amortized time Ω(log(N)/loglog(N)) per operation.

Binary Tree Representation• Cities are contained in a binary tree, with a bit at each internal node to tell

whether the subtree rooted at that node should be reversed. (Bits lower down in the tree will locally undo the effect of bits at their ancestors.)

• To determine the tour represented by such a tree, simply push the reversal bits down the tree until they all disappear. An inorder traversal of the tree will then yield the tour.

• (To push a reversal bit at node x down one level, interchange the two children of x, complement their reversal bits, and turn off the reversal bit at x.)

Splay Trees[Sleator & Tarjan, “Self-adjusting binary search trees,” J. ACM 32

(1985), 652-686]

• Every time a vertex is accessed, it is brought to the root (splayed) by a sequence of rotations (local alterations of the tree that preserve the inorder traversal).

• Each rotation causes the vertex that is accessed to move upward in the tree, until eventually it reaches the root.

• The precise operation of a rotation depends on whether the vertex is the right or left child of its parent and whether the parent is the right or left child of its own parent. The change does not depend on any global properties of the subtrees involved, such as depth, etc.

• All the standard binary tree operations can be implemented to run in amortized worst-case time O(log(N)) using splays.

• In our Splay Tree tour representation, the process of splaying is made slightly more difficult by the reversal bits. We handle these by preceding each rotation by a step that pushes the reversal bits down out of the affected area. Neither the presence of the reversal bits nor the time needed to clear them affects the amortized time bound for splaying by more than a constant factor.

Splay Tree Tour Operations

Next(a):

1. Splay a to the root of the tree.

2. Traverse down the tree (taking account of reversal bits) to find the successor of a.

3. Splay the successor to the root.

Prev(a): Handled analogously.

Splay Tree Flip(a,b,c,d)

• Splay d to the root, then splay b to the root, and push all reversal bits down out of the top three levels.

• There are two possiblities:

b

d b

d

d

d

b

b

x

x

T2R denotes subtree T2 with a reversal bit applied to its

root.

Speedups(Lose theoretical guarantees for better performance in practice)

• No splays for Next and Prev – simply do tree traversals, taking into account the reversal bits.

• Operation of Flip unchanged.

• Yields about a 30% speedup.

Advantages of Splay Trees

• Ease of implementing Flip compared to other balanced binary tree implementations.

• “Self-Organizing” properties: Cities most involved in the action stay relatively close to the root. And since typically most cities drop out of the action fairly early, this can significantly reduce the time per operation.

• Splay trees start beating arrays for random Euclidean instances on modern computers somewhere between N = 100,000 and N = 316,000. They are 40% faster when N = 1,000,000.

• For more sophisticated algorithms, like Lin-Kernighan (to be discussed later), the transition point is much earlier: Splay trees are 13 times faster when N = 100,000.

ResultsN = 103 104 105 106

2-Opt [20] % Excess over HK 4.9 5.0 4.9 4.9

150 Mhz Secs 0.34 3.8 59 940

3-Opt [20] % Excess 2.5 3.1 3.0 3.0

150 Mhz Secs 0.41 4.7 69 1080

Lin-Kernighan % Excess 2.0 2.0 2.0 2.0

150 Mhz Secs 0.77 9.8 141 2650

Iterated LK (N/10) % Excess 1.3 1.3 1.3 -

150 Mhz Secs 5.1 189 10,200 -

Iterated LK (N/3) % Excess 1.0 1.0 1.1 -

150 Mhz Secs 13.6 524 30,700 -

Iterated LK (N) % Excess 0.9 0.9 - -

150 Mhz Secs 39.7 1,570 - -

Time on 3.6 Ghz Intel Core i3 processor at N = 106:

25.4 sec (2-opt), 29.5 sec (3-opt)

Optimization: Most Under-rated Algorithm

Exhaustive Search!

Obstacle: Number of Tours

(N-1)! = 12345 … (N-2)(N-1)

(Can assume that City 1 is the first city.)

N 2 3 4 5 6 7 8 9 10 15 20 30

(N-1)! 2 6 24 120 720 5,040 40,320 362,880 3.6*106 1.3*1012 2.4*1018 2.7*1032

Program for Evaluating (N-1)! Tours

for (i = 0; i < N; i++) tour[i] = i; permute(N-1, 2*MAXDIST);

void permute(int k){ int i, len;

if (k == 1) {len = tour_length();if (len < bestlen) {

bestlen = len;for (i = 0; i < N; i++) besttour[i] =

tour[i];}}else {

for (i = 0; i < k; i++) {tour_swap(i, k-1)permute(k-1);

tour_swap(i, k-1);}

}}

standard routines for

• reading instances,

• printing output,

• computing tour lengths,

• swapping elements.

We enumerate tours as follows:

Lines of Code = 86

How this works

9

Fix City N-1 = 9 in last slot

0

1

2

3

4

5

6

7

8

0

1

2

3

4

5

6

7

8

0

1

2

3

4

5

6

7

8

0

1

2

3

4

5

6

7

8

For all as yet unfixed cities

Suppose we have 10 cities: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.

How this works

3 9

Suppose we have 10 cities: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.

Temporarily Fix City

For all as yet unfixed cities

0

1

2

4

5

6

7

8

0

1

2

4

5

6

7

8

0

1

2

4

5

6

7

8

0

1

2

4

5

6

7

8

And so on …

Results for Basic Program

Methodology:1. Construct lower triangular distance matrix M for a 100-city

random Euclidean instance.2. Instance IN consists of the first N rows of M.

Advantages:• Somewhat better correlation between results for different N

so running time growth rates are less noisy.• Fewer instances to keep track of.

Disadvantages:• Results may be too dependent on M, so should try different

M’s

Results for Basic Program

N 10 11 12 13 14 15

(N-1)! 362,880 3,628,800 39,916,800

4.8 x 108 6.2 x 109 8.7 x 1010

Seconds 0.02 0.30 2.80 42.1 624 9,353

-O2 Secs 0.00 0.09 1.08 13.5 188 2,970

Suggestions for Speedups?

Compiler Optimization: cc –O2 exhaust.c

Lines of Code, still = 86

(Running times on 3.6 Ghz Core i7 processors in an iMac with 32 Gb RAM)

Next Speedup

Don’t need to consider both tour orientations.• Only consider the orientation in which city 1 precedes city

0.• Implement this by adding an input flag to permute(), which

equals 0 unless city 0 has already been fixed.• Lines of Code = 97, an increase of 11.

N 10 11 12 13 14 15Base Secs 0.02 0.30 2.80 42.1 624 9,353-O2 Secs 0.00 0.09 1.08 13.5 188 2,970

1 before 0 0.00 0.05 0.65 8.1 110 1,604

Next SpeedupMore efficient distance calculations

void permute(int k){ int i, len;

if (k == 1) {len = tour_length();if (len < bestlen) {

bestlen = len;for (i = 0; i < N; i++) besttour[i]

= tour[i];}}else {

for (i = 0; i < k; i++) {tour_swap(i, k-1)permute(k-1);

tour_swap(i, k-1);}

}}

void permute(int k, int tourlen){ int i, len;

if (k == 1) {tourlen += dist(tour[0],tour[1]) + dist(tour[ncount-

1],tour[0]);if (tourlen < bestlen) {

bestlen = tourlen;for (i = 0; i < N; i++) besttour[i] =

tour[i];}}else {

for (i = 0; i < k; i++) {tour_swap(i, k-1)permute(k-1,

tourlen+dist(tour[k-1],tour[k])); tour_swap(i, k-1);

}}

}

if (tourlen >= bestlen) return;

O(N) factor of improvement – probably worth one additional city.

More valuable idea: Prune!

Lines of code increases from 97 to 99

Results

N 15 16 17 18 19 20 211 before 0 1604 -- -- -- -- -- --

Tourlen 0.50 1.25 3.81 40.3 280 824 4560

Next Speeduptourlen only includes the costs of edges linking the city in slot k through the city in slot N-1.

We would get more effective pruning if we could take into account the edges linking the cities that haven’t yet been fixed.

More precisely we could use a lower bound on the minimum length path involving these cities and linking the city in slot k to city N-1.

An obvious first choice is the length of a minimum spanning tree connecting all these cities.

void permute(int k, int tourlen){ int i, len;

if (k == 1) {tourlen += dist(tour[0],tour[1]) + dist(tour[ncount-

1],tour[0]);if (tourlen < bestlen) {

bestlen = tourlen;for (i = 0; i < N; i++) besttour[i] =

tour[i];}}else {

for (i = 0; i < k; i++) {tour_swap(i, k-1)permute(k-1,

tourlen+dist(tour[k-1],tour[k])); tour_swap(i, k-1);

}}

}

if (tourlen >= bestlen) return;if (tourlen + mst(k+1) >= bestlen) return

Lines of code increases from 99 to 134

Results

N 20 21 22 23 24 25 26 27 28 29 30 31Tourlen 824 4560 -- -- -- -- -- -- -- -- -- --

mst 0.15 0.20 0.54 1.44 0.76 2.79 29.5 14.0 17.1 12.3 103.5 84.1

N 32 33 34 35 36 37 38 39 40 41 42 43mst 29.3 43.2 84.6 157 290 232 824 316 225 987 2297 5866

Next Speedupbestlen isn’t so hot either, at least initially.

If we start by simply setting bestlen to the Nearest Neighbor tour length, it would seem likely to have a benefit, and it doesn’t take much coding effort --

Lines of code goes from 134 to 155.

void permute(int k, int tourlen){ int i, len;

if (k == 1) {tourlen += dist(tour[0],tour[1]) + dist(tour[ncount-

1],tour[0]);if (tourlen < bestlen) {

bestlen = tourlen;for (i = 0; i < N; i++) besttour[i] =

tour[i];}}else {

for (i = 0; i < k; i++) {tour_swap(i, k-1)permute(k-1,

tourlen+dist(tour[k-1],tour[k])); tour_swap(i, k-1);

}}

}

if (tourlen + mst(k+1) >= bestlen) return

Results

N 32 33 34 35 36 37 38 39 40 41 42 43mst 29.3 43.2 84.6 157 290 232 824 316 225 987 2297 5866

nn 2.9 8.0 24.6 1.3 4.3 4.9 26.8 101 55 407 1357 3653

Next Speedup• As we know from our earlier discussions of tour-construction

heuristics, Nearest Neighbor is a pretty lousy bound, typically 24% above optimal for random Euclidean instances.

• Question: How can we get a better bound cheaply?

• Answer: Guess low – say at (3/4)NN.

– The algorithm will presumably run faster if our initial value of bestlen is less than the optimal tour length.

– If no solution is found, we can rerun the algorithm with an incrementally increased initial value for bestlen, say 5% above the previous value.

– When our initial value eventually exceeds optimal, it will not exceed it by more than 5% (much better than 24%).

– Lines of code increases from 155 to 165.

Results

N 37 38 39 40 41 42 43 44 45 46 47 48nn 232 824 316 225 987 2297 5866 -- -- -- -- --

Iterative 19 71 12 15 33 121 149 2223 756 684 3185 4304

Next Speedup

• A large amount of our time goes into computing MST’s, and much of it may be repeated for different permutations of the same set of cities.

• Could we save time by hashing the results so as to avoid this duplication?

Results

N 46 47 48 49 50 51 52 53 54 55 56 57Iterative 684 3185 4304 -- -- -- -- -- -- -- -- --hashing 45 183 254 860 1602 3397 1402 8360 2815 589 680 4699

With more sophisticated ideas (involving more-than-elementary TSP ideas), we can be under 3600 seconds for all

N ≤ 100.But we are clearly running out of gas, and an entirely

different approach is needed.

Fortunately, one exists.

Integer Programming formulation of the TSP

Variable x{u,v} for each pair of cities {u,v} ⊆ C, with x{u,v} = 1 meaning the edge {u,v} is in the tour.

Goal: Minimize ∑{u,v}d(u,v)x{u,v}

Subject to:

1) x{u,v} ∈ {0,1} for all pairs {u,v},

2) ∑u∈C x{u,v} = 2 for all fixed cities v, and

3) ∑{u,v}: u ∈ S and v ∉ S x{u,v} ≥ 2 for all proper subsets S ⊂ C.

Linear Programming Relaxation of the TSP

Variable x{u,v} for each pair of cities {u,v} ⊆ C, with x{u,v} = 1 meaning the edge {u,v} is in the tour.

Goal: Minimize ∑{u,v}d(u,v)x{u,v}

Subject to:

1) x{u,v} ∈ [0,1] for all pairs {u,v},

2) ∑u∈C x{u,v} = 2 for all fixed cities v, and

3) ∑{u,v}: u ∈ S and v ∉ S x{u,v} ≥ 2 for all proper subsets S ⊂ C.

Solvable in polynomial time.

The solution is the “Held-Karp Lower Bound” mentioned earlier.

The Cutting Plane Approach, Illustrated

-- Points in RN(N-1)/2 corresponding to a tour.

Hyperplane perpendicular to the vector of edge lengths

Optimal Tour

Optimal Tour is a point on the convex hull of all tours.

Unfortunately, the LP relaxation of the TSP can be a very poor approximation to the convex hull of tours.

Facet

To improve it, add more constraints (“cuts”)

Note: Subtour constraints are all facets.

Branch & Cut

• Use the Cutting Plane approach, but when you get stuck or hit a point of diminishing returns, divide into subcases, such as– Edge {u,v} must be in the tour or cannot be in the tour– The total weight on edges out of a particular S ⊂ C is

either less than or equal to 2, or greater than 4.

Initial LP, UB = 100, LB = 90

LB = 92 LB = 93

X{a,b} = 0 X{a,b} = 1

LB = 92 LB = 100 LB = 98 LB = 97

X{a,c} = 0X{c,d} = 0 X{c,d} = 1 X{a,c} = 1

LB = 101 LB = 100

X{e,a} = 0 X{e,a} = 1

New Opt = 97

UB = 97

Opt = 97

N = 85,900

Current World Record (2006)

Using a parallelized version of the Concorde code, Helsgaun’s sophisticated variant on Iterated Lin-Kernighan, and 2719.5 cpu-days

Concorde • “Branch-and-Cut” approach exploiting linear programming

to determine lower bounds on optimal tour length.

• Based on 30+ years of theoretical developments in the “Mathematical Programming” community, plus some very good data structures and heuristics work from computer science.

• For surprisingly large instances, it finds an optimal tour and proves its optimality (unless it runs out of time/space).

• Executables and source code can be downloaded from http://www.math.uwaterloo.ca/tsp/

Running times (in seconds) for 10,000 Concorde runs on random 1000-city planar Euclidean instances (2.66 Ghz Intel Xeon processor in dual-processor PC, purchased late 2002).

Range: 7.1 seconds to 38.3 hours

Concorde Asymptotics[Hoos and Stϋtzle, to appear in Eur. J. Op. Res., 2014]

• Estimated median running time for random Euclidean instances.

• Based on– 1000 samples each for N = 500,600,…,2000– 100 samples each for N = 2500, 3000,3500,4000,4500– 2.4 Ghz AMD Opteron 2216 processors with 1MB L2

cache and 4 GB main memory, running Cluster Rocks Linux v4.2.1.

0.21 · 1.24194 √N

Actual median for N = 2000: ~57 minutes, for N = 4,500: ~96 hours

Where to Learn More: Books

The Traveling Salesman Problem, Lawler, Lenstra, Rinnooy Kan, and Shmoys (Editors), Wiley (1985). $377.47 (current amazon.com price, new)

The Traveling Salesman Problem and Its Variations, Gutin and Punnen (Editors), Kluwer (2002). $152.10

The Traveling Salesman Problem: A Computational Study, Applegate, Bixby, Chvatal, and Cook, Princeton University Press (2006). $57.99/$44.99 (Kindle)

In Pursuit of the Traveling Salesman, Cook, Princeton University Press (2012). $20.64/$15.37 (Kindle)

Web Resourceshttp://davidsjohnson.net/papers.html

(David Johnson’s downloadable papers on the TSP and other topics, plus slides for lectures in this year’s course on “The Traveling Salesman Problem in Theory and Practice”)

http://www.math.uwaterloo.ca/tsp/

“The Traveling Salesman Problem” (Bill Cook)

http://dimacs.rutgers.edu/Challenges/TSP/

“The 8th DIMACS Implementation Challenge: The Traveling Salesman Problem” (DSJ)

http://comopt.ifi.uni-heidelberg.de/software/TSPLIB95/

“TSPLIB” (Testbed of Instances, Gerd Reinelt)

http://en.wikipedia.org/wiki/Travelling_salesman_problem

(Wikipedia Entry -- Much Improved)

Clay Institute $1,000,000 Prize for P versus NP

http://www.claymath.org/millenium-problems/p-vs-np-problem

http://www.math.uwaterloo.ca/tsp/

Standard Shortcuts

Smart Shortcuts

Assume we have an algorithm ALB that computes a lower bound on the TSP length when

certain edges are fixed (forced to be in the tour, or forced not to be in the tour), and which, for some subproblems, may produce a tour as well.

• Start with an initial heuristic-created “champion” tour TUB, an upper bound UB =

length(TUB) on the optimal tour length, and a single “live” subproblem in which no

edge is fixed.

• While there is a live subproblem, pick one, say subproblem P, and apply algorithm ALB

to it.

– If LB < UB

1. Pick an edge e that is unfixed in P and create two new subproblems as its children, one with e forced to be in the tour, and one with e forced not to be in the tour.

2. If algorithm ALB produced a tour T, and length(T) < UB

1. Set UB = length(T) and TUB = T.

2. Delete all subproblems with current LB ≥ UB, as well as their children and their ancestors that no longer have any live children.

– Otherwise (LB ≥ UB), delete subproblem P and all its ancestors that no longer have live children.

• Halt. Our current champion is an optimal tour.

Branch & Bound for the TSP

Set Hashing• Start by creating random unsigned ints hashkey[i], 0 ≤ i < N.

• Create an initial empty hashtable MstTable, say of size hashsize = 524288 = 219. (We will double the size of MstTable whenever half of its entries become full.)

• The hash value hval(C) for a set C of cities is obtained by computing the exclusive-or of the |C| values {hashkey[i]: i ∈ C}. (The ith bit of the hash value is 1 if and only if an odd number of the ith bits of the keys equal 1.)

• Because MstTable can grow, hval(C) will actually refer to the entry with index hval(C)%hashsize (the remainder when hval(c) is divided by hashsize).

• An entry in the table will consist of two items:

– The length Bnd of the minimum spanning tree for the cities in C.

– A bitmap B of length N, with B[i] = 1 if and only if i ∈ C.

• We will handle the possibility of collisions by using “linear probing”.

Linear Probing• To add the MST value for a new set C to the hashtable, we first try

MstTable[i] for i = hval(C)%hashsize. If that location already has an entry, set i = i+1(mod hashsize) and perform the following loop to find a suitable location:

– While {MstTbl[i] is full, set i = i+1(mod hashsize)}

• In the worst case, this could take time proportional to hashsize, but there are simple tabulation-based schemes that can be shown to take amortized constant time per search [Patrascu & Thorup].

• To check to see if we have already computed the MST for C, we follow a similar scheme, where we start by setting i = hval(C)%hashsize.

– While MstTbl[i] is not empty

• If MstTbl[i].bitmap equals the bitmap for C, return MstTable[i].Bnd.

• Set i = i+1(mod hashsize).

– Return “Not Cached”.(Lines of code increases from 165 to

274)

Recommended