COS 126

Traveling Salesperson Problem
Programming Assignment

Due: Wednesday, 11:59pm

Given a set of N points in the plane, the goal of a traveling salesperson is to visit all of them (and arrive back home) while keeping the total distance traveled as short as possible. Write a program to compute an approximate solution to the traveling salesperson problem, and use it to find the shortest tour that you can, connecting a given set of points in the plane.

Perspective. The importance of the TSP does not arise from an overwhelming demand of salespeople to minimize their travel distance, but rather from a wealth of other applications, many of which seem to have nothing to do with the TSP at first glance. Real world application areas include: vehicle routing, circuit board drilling, VLSI design, robot control, X-ray crystallography, machine scheduling, and computational biology.

Part 1: two tour construction heuristics. The traveling salesperson problem is notoriously difficult: for large N, no one knows an efficient method that can find the shortest possible tour for any given set of points. However, many methods have been studied that seem to work well in practice, even though they are not guaranteed to produce the best possible tour. Such methods are called heuristics. Your main task is to implement the nearest neighbor and smallest increase insertion heuristics for building a tour incrementally. Start with a one-point tour (from the first point back to itself), and iterate the following process until there are no points left.

  • Nearest neighbor heuristic.   Read in the next point, and add it to the current tour after the point to which it is closest.

  • Smallest increase heuristic.   Read in the next point, and add it to the current tour after the point where it results in the least possible increase in the tour length.
  • To implement these heuristics you will create a tour ADT. The client program tsp.c reads in the points, and uses your ADT's interface functions to output a good tour:

    Point p;
    while (POINTread(&p) != EOF)
       TOURinsert(p);
    TOURshow();
    
    The above client program uses the interface in TOUR.h:
    void TOURshow(void);           // display the tour
    int  TOURdist(void);           // compute the distance of the tour
    void TOURinsert(Point p);      // insert point p into the tour
    
    Your job is to write an implementation for all three interface functions. To do this, represent the tour as a circular linked list of nodes, one for each point. Each node will contain a Point and a pointer to the next node in the list.
    typedef struct node* link;
    struct node {
       Point p;
       link next;
    };
    
    The Point data type is supplied in POINT.h and point.c.
    int  POINTdist(Point p, Point q);     // compute (integer) distance between p and q 
    int  POINTread(Point* pp);            // read in a point from stdin
    void POINTprint(Point p);             // print point to stdout
    void POINTprintScaled(Point p)        // print point to stdout, scaled to 512 x 512 box
    
    The following TOURinsert() function from tour-inorder.c. takes a Point and makes it the last city visited in the tour. Your main task is to modify this insertion function to perform the two heuristics discussed above.
    static link first = NULL;               // first node on tour
    static link last  = NULL;               // last  node on tour
    
    void TOURinsert(Point p) {
       link new = NEWnode(p, NULL); 
       if (first == NULL) {                 // degenerate case
          first = new;
          first->next = new;
          last = new;
       }
       else {                               // insert new node at end of list
          last->next = new;
          new->next = first;
          last = new;
       }
    }
    
    Before you implement the heuristics, you should first implement the functions TOURshow() (to print the points on the tour) and TOURdist() (to print its length). These both cycle around the linked list and require only a few lines of code, but it is important to think about them carefully, because debugging linked-list code is notoriously difficult and frustrating.

    Compiling and testing. Use "gcc126 tsp.c tour.c point.c" to jointly compile your files. Debug your TOURshow() and TOURdist() code by running it on a simple sequence of points, such as tsp5.txt. Make sure that TOURshow() function prints out all the points and that TOURdist() gets the distance right, including the distance back to the starting point. For more test data, use the files tsp10.txt, tsp100.txt, tsp1000.txt, and tsp13509.txt. These points represent various US cities.

    Part 2: Turtle graphics output. The second part of the assignment is much the same as in the Mandelbrot assignment: make a version of your program that outputs a turtle graphics program that draws the tour created from the smallest-increase heuristic. We have enhanced the turtle graphics language to support flying to an absolute (x, y) coordinate with the pen down. This will simplify the task of tracing out the tour. As an example, the following turtle graphics program draws a tour connecting 5 points in the plane:
    F 400.1 201.3
    G 100.4 101.6
    G  90.2 304.1
    G 200.7 240.8
    G 345.1 392.2
    G 400.1 201.3
    
    Sample TSP PostScript

    Your program should produce a program exactly like this one, except with the point coordinates on your tour as arguments to the F and G commands. To do this, replace the interface function TOURshow() so that it produces the desired turtle graphics output. Use the POINTprintScaled() function to calculate the turtle coordinates corresponding to each Point. If you save the output in a file with

    a.out < tsp10.txt | turtle > tsp10.ps
    then you can then see the tour that your program produces via your PostScript viewer as usual. Note that you will need to download and compile the latest version of turtle.c to use the G commmand.

    What to submit. Submit the files readme.txt, tour-nearest.c, tour-smallest.c, and tour-turtle.c. Your readme file should include answers to the questions from the online checklist.

    Contest and extra credit. Implement a better heuristic. For example, modify your program to check all the points not yet on the tour, and then add the one that increases the length of the tour the least. Or observe that any tour with paths that cross can be transformed into a shorter one with no crossing paths: add that improvement to your program. The checklist page contains several other ideas. We will award a special prize to whomever finds the shortest tour around the 1000-point set.

    This assignment was developed by Bob Sedgewick. Modified by Kevin Wayne.
    Copyright © 2000 Robert Sedgewick