Newsgroups: sci.math,sci.op-research,comp.ai,comp.theory
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!ix.netcom.com!netcom.com!timin
From: timin@netcom.com (Mitchell E. Timin)
Subject: TSP CONTEST - Winners Writeups
Message-ID: <timinD02yLo.M3G@netcom.com>
Summary: Bios of TSP contest winners
Keywords: TSP contest winners
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
Date: Wed, 30 Nov 1994 12:27:24 GMT
Lines: 393
Xref: glinda.oz.cs.cmu.edu sci.math:87851 sci.op-research:2272 comp.ai:25612 comp.theory:11231


From Henning Klaskala:
I'm 29 (born on 20th January 1965 in Berlin), German, unemployed since January
1993.

I studied computer science at Technical Uniersity Munich from Nov. 1984 until
Nov. 1990.  Then I worked at the same university for 25 months.  I had planned
to write a doctoral thesis there, but found no time to do so and therefore
quit my job.

I started working on the TSP about ten years ago, now and then trying out
new ideas to solve it.  Searching for good routes is a problem that I also
dealt with in other areas, like routing electronic circuits.  For example
I designed and wire-wrapped an ECL/TTL graphics board at the university.
My thesis was the design of an integrated circuit (>40000 transistors)
which involved repeated placement and routing of cells until the whole
circuit could be squeezed into the limited chip area.  Altogether I placed
and routed the circuit about 300 times in 15 months, thus gaining some
experience with routing. :->  Later I worked at the university on real-time
applications of parallel computers which brought me again to the subject
of routing:  Routing messages through the networks of parallel computers
without causing too many collisions was an important problem here. 
However I had to waste most of my time for other projects than the real-time
project I was payed for, doing mainly system administration for constantly
crashing parallel computers, so that I got tired of walking the same boring
route to the crashed computers several times a day and I did quit this job.
Maybe I'll write a PhD thesis on the TSP instead now...

I don't want to reveal the algorithm yet, just that my program is slow
16 bit code that runs even on outdated 286 processors. (The 32 bit LINUX
version is about twice as fast as the 16 bit MSDOS contest version!)

Some more test results:  I ran my TSP program 1000 times on each of the 3
problem files and got routes with the following best/worst/average costs:

problem file:         | 47 cities | 110 cities | 111 cities
----------------------+-----------+------------+-----------
cost of best route:   |   45750   |   87385    |   86149
cost of worst route:  |   46937   |   90194    |   88954
average cost:         |   45933   |   88536    |   87660

The routes are available by e-mail from klaskala@informatik.tu-muenchen.de
--------------------------------------------------------------------------
From Jukka Honkanen:
My name is Jukka-Pekka Honkanen. E-mail address is h123592@cs.tut.fi.
I am student in Tampere University of Technology. My area is software
technology. 

Program tools:

I developed program in PC with Linux operation system and gcc 2.5.8.
I used C++ language and my own data structure templates, such as array and
linked list. I compile contest version by DJGPP 32bit DOS extender.

Program algorithms:

Program read input file in memory that class File_Buffer handle.
That allocate buffer that is enough large for input file. That class is 
inherited from class which contain regular file operations. There is example
function which parse words and numbers. Reason to this is in DJGPP which
run in such mode that i/o is slower than in straight DOS program.

Next program allocates array of class Vertex. There is number of point and
flag of usage of that point. Also program initializes new operator for class
Cost. Cost class contain cost from previous point to this point. Also there
is pointer to class Vertex which describe point number and usage flag. 

Then program read costs from start point to each other point. Cost are
deposited in dynamic array which is template class Array. For speed up array
size is set beforehand to needed size. Also costs from each point to end point
are read same way. All other cost's program read to array which contain arrays
of Cost. From these arrays is made arrays which contain information of costs
from point to other points in sorted cost order. Also there is arrays
which contain information of costs from other points to each point.
This all means that in program can determine which point can be reached with
lowest cost from each other point. Arrays are sorted by templates sort
routine, which is combination of quick sort and insertion sort method.

Path is linked list derived from template Sorted_List<Node>. Class node
contain only number of point. Path is made starting from one point, adding to
the end of path unused point with lowest cost. Then adding point which is
unused and have lowest cost to first point of path. This algorithm is used
until there is free points anymore. It gives local optimization of nearest
points. Globally there is jumps that are far away optimum.

These paths program made number of points in problem. This is one of this
which need improving in my program.

When program has made paths, it sorts them in order of current cost of path.
Program optimizes only desired numbers of paths.

Program handle optimization with two pointers. These are first point of path
and third point of path. These pointers travel path from start to end.
There is four variations of optimization that program check in every point.
Next are straight comments of program. They describe cost as length of edge.
            
            // 
            // Crossing in the path is detected by calculating delta.
            // Delta is calculated adding costs of ((first to third) and
            // (second to forth) and (second to third)) and subtracting costs
            // of (third to forth) and (first to second) and
            // (second to third). If delta is negative then there is crossing.
            // Crossing is replaced by setting (first to third) and
            // (third to second) and (second to forth).
            //                           
            //                             //                      
            //    Old path.                // New path.            
            //                             //                      
            //                           //  second       third  
            //    third        second      //  third'       second'
            //    x<-----------x           //  x----------->x      
            //     \           ^           //  ^            |      
            //      \         /            //  |            |      
            //       \       /             //  |            |      
            //        \     /              //  |            |      
            //         \   /               //  |            |      
            //          \ /                //  |            |      
            //           \                 //  |            |      
            //          / \                //  |            |      
            //         /   \               //  |            |      
            //        /     \              //  |            |      
            //       /       \             //  |            |      
            //      /         \            //  |            |      
            //     /           v           //  |            v      
            //    x first      x forth     //  x first      x forth
            //  ^            |           //  ^            |
            //  |            |           //  |            |
            //  .            .           //  .            .
            //  .            .           //  .            .
            //  .            .           //  .            .
            //                           //
            // 
            // Crossing in the path is detected by calculating delta.
            // Delta is calculated adding costs of ((first to third) and
            // (second to forth) and (all deltas of reversing path of second
            // to third)) and subtracting costs of (third to forth) and
            // (first to second). If delta is negative then there is crossing.
            // Crossing is replaced by path reversing (second to third) path
            // going (third to second) and setting (first to third) and
            // (second to forth).
            //    
            //                              //                             
            //  Old path.                   //    New path.                
            //                              //                             
            //  ..(one or more)..           //    ..(one or more)..        
            //  |               |           //  |               |        
            //  v               |           //  |               v        
            //  x third         x second    //  x second        x third  
            //   \              ^           //  ^ third'        | second'
            //    \            /            //  |               |        
            //     \          /             //  |               |        
            //      \        /              //  |               |        
            //       \      /               //  |               |        
            //        \    /                //  |               |        
            //         \  /                 //  |               |        
            //          \/                  //  |               |        
            //          /\                  //  |               |        
            //         /  \                 //  |               |        
            //        /    \                //  |               |        
            //       /      \               //  |               |        
            //      /        \              //  |               |        
            //     /          \             //  |               |        
            //    /            \            //  |               |        
            //   /              v           //  |               v        
            //  x first         x forth     //  x first         x forth  
            //  ^               |           //  ^               |        
            //  |               |           //  |               |        
            //  .               .           //  .               .        
            //  .               .           //  .               .        
            //  .               .           //  .               .        
            //                              //                           

        //                           //                       
        // Old path.               // New path.            
        //                         //                      
        // .           .           // .           .        
        // .           .           // .           .        
        // .           .           // .           .        
        // |           |           // |           |        
        // x           |           // x forth     |        
        // ^           |           // ^           |        
        //  \          |           // |           |        
        //   \         |           // |           |        
        //    \        |           // |           |        
        //     \       v           // |           v        
        //      \      x first     // |           x first  
        //       \     |           // |          /         
        //        \    |           // |         /          
        //         \   |           // |        v           
        //          x  |           // |        x second    
        //          ^  |           // |        |           
        //          |  |           // |        |           
        //          |  |           // |        v           
        //          x  |           // |        x           
        //          ^  |           // |        |           
        //          |  |           // |        |           
        //          |  |           // |        v           
        //    forth x  |           // |        x forth'    
        //          ^  |           // |         \          
        //         /   |           // |          \         
        //        /    v           // |           v        
        //       /     x second    // |           x second'
        //      /      |           // |           |        
        //     /       |           // |           |        
        //    /        |           // |           |        
        //   /         |           // |           |        
        //  /          |           // |           |        
        // x third     |           // x third     |        
        // ^           |           // ^           |
        // |           |           // |           |        
        // .           .           // .           .        
        // .............           // .............        
        // (one or more)           // (one or more)        
        //                         //                      
        //
        //                        //                     
        // Old path.              // New path.           
        //                        //                     
        // (one or more)          // (one or more)       
        // .............          // .............       
        // .           .          // .           .       
        // .           .          // .           .       
        // |           |          // |           |       
        // x           |          // x second    |       
        // ^           |          // ^           |       
        //  \          |          // |           |       
        //   \         |          // |           |       
        //    \        |          // |           |       
        //     \       v          // |           v       
        //      \      x third    // |           x third 
        //       \     |          // |          /        
        //        \    |          // |         /         
        //         \   |          // |        v          
        //          x  |          // |        x forth    
        //          ^  |          // |        |          
        //          |  |          // |        |          
        //          |  |          // |        v          
        //          x  |          // |        x          
        //          ^  |          // |        |          
        //          |  |          // |        |          
        //          |  |          // |        v          
        //   second x  |          // |        x second'  
        //          ^  |          // |         \         
        //         /   |          // |          \        
        //        /    v          // |           v       
        //       /     x forth    // |           x forth'
        //      /      |          // |           |       
        //     /       |          // |           |       
        //    /        |          // |           |       
        //   /         |          // |           |       
        //  /          |          // |           |       
        // x first     |          // x first     |       
        // ^           |          // ^           |
        // |           |          // |           |       
        // .           .          // .           .       
        // .           .          // .           .       
        // .           .          // .           .       
        //                        //                     

Optimization is so complex that I will not describe them now in writing.
If You are interested e-mail to me.

Last thing is picking path of lowest total cost and printing.

With my contest command line options paths were made number of points in
problem. Then program optimizes 30 best paths. There is also options which
made only one path and optimize that path. Of course, cost may be weaker.
When I send program to contest, I did not know was cost reached by program
good enough.

If this write-up is obscure, blame my language.

E-mail to me, if You are interesting in sources of program. I am interesting
how my templates work with other compilers. There is also hash-table, queue
and heap. They are inherited from template Class Array.

Jukka-Pekka Honkanen.
----------------------------------------------------------------------------
From Frank Sven Nestel:
Frank Sven Nestel, 29, PhD Student of Applied Mathematics, 
working on numerical problems, big fan of programming contests.

Algorithm of my program?? There where 5 different greedy start
methods (like use the shortest connection you ever find etc.)
and about 7 local improvement steps (like move a block of cities
or reverse a sequence or etc.) There is an string driven
interpreter for which allowed various combinations of such
methods and even even a primitve backtracking between differnt
local steps. The final method sent used three different combinations
for security. If I had known the programs where all so bad and
there are only three test cases it would have been easy to find
a solution 3 to 10 times faster. But in the automatical
generated Testproblems (which were modelled after the examples
given) there were problems which my algorithm did not solve in
a 10% gap compared to the best solution in our set of methods.
Unfortunately this best method wasn't the same every time :-)

My email: nestel@am.uni-erlangen.de
----------------------------------------------------------------- 
From Randy Saint:
I am a 30 year old Systems Analyst with 10 years of programming 
experience.  I'm currently working for Loral Space Information Systems at 
the NASA mission control center at Johnson Space Center, Houston, 
Texas.

I wrote my TSP program in C.  The algorithm starts with an initial route and 
then tries to improve the route.  It does this by testing all possible 
combinations of swapping two cities, reversing a string of cities, or inserting 
one city somewhere else along the route.  When all possible comibnations 
have been tested, they are sorted by cost savings, and the one that will 
save the most distance is performed first.  The algorithm then goes through 
the rest of the combinations and performs the next best one that was not 
affected by the first alteration.  Once it has gone through the list of 
combinations and performed all the ones it can, the algorithm starts over 
testing all possible combinations of swapping, reversing, or inserting.  It 
repeats this loop until there are no swaps, reverses, or inserts that shorten 
the route.

I found out that the initial route used for this algorithm affects
the final path that it finds, so the algorithm 
is started with three different routes: greedy, 
reverse greedy, and greedy starting from both ends.  A greedy algorithm  
simply selects the next city to be the closest city out of the remaining cities.

I also found that if one initial path resulted in the best path of the three, 
then usually it also came up with a slightly better path if I alter the original 
algorithm to test swapping groups of cities, reversing strings of cities, or 
inserting a group of cities somewhere else in the list.  So the algorithm uses 
the best initial path as it's seed, and starts with n=2.  It then tests all 
possible combinations of swapping 1 to n cities with 1 to n cities, or 
reversing a string of cities, or inserting 1 to n cities somewhere else in the 
path.  If n=2 results in a better path than the first, I increase n and re-run 
the algorithm until we don't get a better path.

My email address is: rsaint@freenet.fsu.edu
Randy Saint, Houston, TX, USA
-------------------------------------------------------------------------
From Chad Hurwitz:
Chad Hurwitz is just a small time TSP bard that hopes to some day contribute
to the field.  He is currently starting a GNU TspSolve project which will be
released sometime next year with full parallizability of tsp algorithms for
symmetric and asymmetric TSPs.  He is also looking for contributors that have
the opportunity to release their code into the public domain via the TspSolve
project.  If you are interested in TspSolve, send mail to churritz@cts.com

The algorithm used for Chad's contest entry was a mixture of 4 different
algorithms: one to find an origonal tour named dispersion, a second to perform
an asymmetric 3-opt operation, a third to improve with a k=14 kswaping
procedure, and a fourth to clean up with k=3 kswapping.  All of the above
and much more for symmetric and euclidean tsps will be included in tsp_solve.

I live and work in San Diego CA, U.S.A.

born in Souix City, Iowa, U.S.A.

The professor that
started me on the TSP was Dr. Clint Staley.
---------------------------------------------------------------------------
From the Koeln group:
We are Harald Minrath and Thomas Gabel. We are students at the University 
of Cologne, Germany. Our subject is business and computer science (german: 
Wirtschaftsinformatik).

Our addresses are:
Thomas Gabel, Gustavstrasse 13, D-50937 Koeln, Germany, Tel: 0049 - 
221-444655
e-mail: a2420643@smail.rrz.uni-koeln.de

Harald Minrath, Tuebinger Strasse 12, D-50739 Koeln, Germany, Tel: 0049 - 
221-174619
e-mail: a2424762@smail.rrz.uni-koeln.de

Our professor in Traveling Salesman Problem is Mr Michael Juenger, 
Institution of Computer Science, University of Cologne. 
We have had some courses in TSP and are interested in this field of 
computer science.

Some facts about program:

We used the following algorithms:
1. savings-algorithm (modified, originally used in vehicle routing 
problem; used to create a valid solution)
2. two_opt (modified; to optimize the existing solution by elimination of 
cross-pathes)
3. node_insertion (to look for a better position for every node in the 
existing circle)

Please send us a message if you want to have the source code (in Turbo 
Pascal).

We are very interested in further information about the TSP and other 
competitions in similar competitions. 
---------------------------------------------------------------------------
