— Cleve ]]>

To see if your tour is optimal, I modified the TSP example to use your distance function and state capitol data. Running it takes about 2 seconds on my laptop and indeed, your solution is optimal.

Your approach of moving cities is a 2-opt heuristic. Others have extended that to swaps of 3 or more cities. Wikipedia cites the Lin-Kernighan-Johnson approach which uses swaps and includes ideas from genetic algorithms; the article says that it often gets high-quality tours on large problems.

Whether or not you need a guaranteed optimum depends on the application. For many, a high-quality heuristic tour is good enough. How do you know if you have such a heuristic? It’s ideal if you have an exact approach to compare with, as we do with the TSP. Then, as you did, try a lot of random seeds to see how often you get acceptable solutions.

About the comment on the gap: if the gap is zero, the solution has been proved optimal. The comment about small values is because intlinprog stops when the gap falls below a tolerance that by default is nonzero.

]]>Yes, the Optimization Toolbox has a TSP example. But I’m not sure it is guaranteed to find the global minimum. The description says, “The smallness of the absolute gap implies that the solution is either optimal or has a total length that is close to optimal.”

There is also a contribution to the File Exchange, number 13680, by Joseph Kirk, that uses a genetic algorithm and that is highly regarded. I haven’t used it myself. I doubt that it finds a guaranteed optimal solution.

There is a question about coordinate systems. Is the earth flat? The Optimization Toolbox example uses longitude and latitude directly without computing great circle distances. That might be why it converges to a different tour.

Some TSP models I noticed briefly on the Web claim to be using actual road mileage.

But the biggest reason I like what I have in my blog post is that the code is easy to read, understand and use. We are going to suggest it to high school kids who are participating in M3, the SIAM/MathWorks math modeling challenge. More on that later.

— Cleve

]]>https://academic.oup.com/qjmam/article/1/1/149/1883392 ]]>

The numerical tests that they (Hestenes and Stiefel) carried out led them to re-examine the escalator method of Morris. This, they concluded, was essentially the same method as their own despite considerable differences in presentation. The idea therefore of using conjugate directions to solve symmetric systems goes back at least as far as 1946 when Morris’s paper was published. ]]>

Since Morris seems to be the person who introduced us to the Wilson matrix, I also wondered who Morris was. It turns out that he had been a Captain in the RAF, so Captain Joseph Morris. Born in 1888, he served in the first world war. He wrote at least two technical books:

The Strength of Shafts in Vibration.

C Lockwood and Son, 1929.

The Escalator Method in Engineering Vibration Problems.

Chapman and Hall, 1947. (Published by John Wiley and Sons in the US.)

as well as:

The German Air Raids on Great Britain 1914-1918. It was first published in about 1925, but seems to have been republished several times, the latest I can see is 2007 by Nonsuch.

I have not yet found when he died.

— Sven

]]>>> tic; ismember(0,1:1e6); toc Elapsed time is 0.008192 seconds. >> tic; ismember(0,1:1e7); toc Elapsed time is 0.076229 seconds. >> tic; ismember(0,1:1e8); toc Elapsed time is 0.776335 seconds.

Thus, repeating the ISMEMBER call M times on an array that grows from 1 to M elements gives rise to the O(n^2) behavior. When preallocation is used, each of the M iterations through the for-loop calls ISMEMBER on an array with M elements. This is still O(n^2) but with a larger constant. Growing the array inside the for-loop is not a significant contributor to the run-time when compared with ISMEMBER.

My version of the code uses some additional memory to store a logical array to keep track of numbers that have been “used”. By avoiding the ISMEMBER call, it runs faster.

]]>if a > n && ~usedMask(a-n)

when n > a.

But after some research I found the link about “Logical Operators: Short-Circuit && ||” (Logical operations with short-circuiting). So now I understand what is going on in that “if” statement. Very interesting implementation.