In this project, you will choose and implement an algorithm to find good solutions to the traveling salesman problem (TSP) within a given time limit.
The Traveling Salesman Problem (TSP) optimization problem is defined as follows:
A complete simple tour is a path through the graph that visits every vertex in the graph exactly once and ends at the starting point; such a tour is also known as a Hamiltonian cycle or Rudrata cycle. The TSP problem is an optimization problem, since we are searching for a simple tour with minimum cost.
Whatever your design choices, it is important that you consider and understand several properties of your chosen algorithm: completeness (i.e., is your search guaranteed to find a solution when one exists?) and optimality (i.e., given sufficient time, does your algorithm find the optimal solution?).
If you choose a branch and bound state-space search, then your bounding function should be a lower bound in order to guarantee the optimality of your algorithm. If your B&B search is optimal, then it is also correct.
You may optionally team up with another class member to complete this project. At most, teams of two members are permitted. You may also complete the project alone, if you wish, but teaming up is highly encouraged. Be sure that if you team up with someone that you are both committed to sharing the load.
Complete the Whiteboard Experience with your team-mate. (Thus, teams must be formed before the whiteboard experience.)
We provide a Graphical User Interface that generates a specified number of random points (the cities) on a 2-D GDI canvas. The problems are generated randomly when you click the “new problem” button, and you can control the problem size using the “Problem Size” field, as shown in the following figure:
Figure 1. Starting screen for TSP
Clicking the “new problem” button again will generate another new problem.
Setting the “Seed” field allows you to reset the random number generator and generate a new problem from a known state of the generator. This allows you to create a problem in common with other students for the purpose of evaluation. In the following figure, the seed 17 has been specified. The GUI provides a hook (the “Run” button) which calls the method that you are going to implement, namely ProblemAndSolver.solveProblem(). The current implementation provides a random tour. The following figure also illustrates that the “Run” button has been clicked, and a random tour among the cities (vertices) has been chosen:
Figure 1. Starting screen for TSP
Also worth noting is that the “Problem” number has been incremented to “1” to indicate that this is the first problem generated after setting the seed to 17. Subsequent “new problems” will be numbered incrementally from 1. This is an important detail for generating the correct problem for your report.
A word of clarification: the GUI currently displays a message in red text as follows: “n© means this node is the nth node in the current solution and incurs cost c to travel to the next node.” The “n” indicates the node's position in the displayed tour, and the “©” is the weight on the next edge in the tour. We elected to show the edge weight next to the vertex at the head-end of the edge so that it is clear with which the weight is associated. Distances are computed using the Euclidean distance.
Furthermore, the word “node” is ill-chosen, and our GUI should use the term “vertex” instead (TODO).
Be sure that you are using the latest .NET framework: Bring up the properties of your project (can use the key-chord Alt+F7). For the property “Target framework:”, specify .NET Framework 4 (or higher).
You are developing as a problem solver. You are also learning to solve a problem before you start writing code. In this project, we require you to step up to a whiteboard after reading these instructions before writing any code. Use the whiteboard to walk through the solution with your team-mate. If operating solo, you could present to a friend, who could be another CS major, a CS 312 classmate, or another technical person with an eye for detail.
State clearly your choice of algorithm. Make sure you sketch out and understand your chosen algorithm. If it is a solution-space algorithm, understand your algorithm. In particular, for local search, understand the neighborhoods produced by your operators. If it is a branch and bound algorithm, then choose and understand your state space, your bound function, your agenda, and every other ingredient necessary to do branch and bound on the TSP (see Appendix 1). Simulate a few steps of your algorithm on the board. Think out loud and with sketches about the contents of your data structures for simple examples.
In short, make sure you understand what you are going to do before you write a stitch of code. As you will note below, including a photo of your “whiteboard experience” is a required element of your project report.
Have a “whiteboard experience” and document it with a photograph of you next to the whiteboard sketches, etc.
Prepare a whiteboard experience report as a .pdf file. It should consist of one page with the following elements:
Submit the whiteboard experience report online by the whiteboard experience deadline for this project.
Write a type-written report containing the following distinct sections as a single PDF document, and submit it by following the submission directions in the course syllabus.
(Note: you will include two copies of this table, one for your main algorithm and one for your baseline algorithm.)
Problem Specification | Performance | |||||
---|---|---|---|---|---|---|
# Cities | Seed | Problem # | Running time (sec.) | Cost of best tour found | Optimal? | Max. space usage |
10 | 17 | 1 | ||||
10 | 17 | 2 | ||||
50 | 321 | 1 | ||||
50 | 321 | 2 | ||||
50 | 321 | 3 | ||||
20 | (your choice) | (your choice) | ||||
20 | (your choice) | (your choice) | ||||
25 | (your choice) | (your choice) | ||||
25 | (your choice) | (your choice) | ||||
25 | (your choice) | (your choice) |
Problem Specification | Performance | |||||
---|---|---|---|---|---|---|
# Cities | Seed | Problem # | Running time (sec.) | Cost of best tour found | Optimal? | Max. space usage |
40 | 733 | 1 | ||||
40 | 733 | 2 | ||||
40 | 733 | 3 |
To facilitate collecting results for the hall-of-fame, it is required that each student report his or her Competition results on the five pre-specified problems via a survey, the URL for which will be sent to the Google Group. It is also required to submit results for the three pre-specified one-time problems to the One-Time Competition survey. A separate link will be sent for this second survey. The links are not posted here in order to avoid abuse by folks not in the class. It is possible to reply to the Competition survey more than once (in case a student wishes to submit improved results), but only one submission is permitted to the One-Time Competition survey. Submitting invalid results or results that are not your own (i.e., computed by your code in the assigned semester) is, of course, a breach of the honor code.
Students are eligible to win the overall competition if all results are submitted on time (by the project deadline on the course schedule).
The winner of the competition will be determined from among all eligible participants across all sections of the course in a given semester. A participant's score is based on the total score of the three larger Competition pre-specified problems (specified in the table above) plus the total score of the three larger One Time Competition pre-specified problems. Winning scores will be validated by our blue ribbon panel of TAs. A hall-of-fame will be posted in class on the last day of instruction for the semester, and bragging rights will be given to the winners to help everyone understand their methods.
Extra credit will be awarded to top 3 winners of the overall competition. Ties are permitted.
I have been asked a few questions about the contest, that I want to address for everyone’s sake:
We cover branch and bound (B&B), as well as B&B design options for the TSP, in great detail in lectures. See the class schedule for links to the lectures and some short lecture notes on B&B (in the reading column) for guidance.
In a nutshell, a branch and bound algorithm must include the following ingredients:
Optional (depending on your state expansion strategy):
In designing your algorithm, you have many options for those ingredients. In the lectures we looked at a number of possibilities for each design ingredient as follows:
In the appendices to this instructions document, we review the bounding function involving a reduced cost matrix. That bounding function is not the only possible bounding function, and it is not mandatory that you use that function, but it is a good one. We also review one promising approach to state expansion, namely the “include-exclude” approach. The “include-exclude” approach is not the only way to generate states in the state space, and it is not mandatory that you use this approach. As a further resource in designing your B&B algorithm, you should refer to the Branch and Bound notes: http://faculty.cs.byu.edu/~ringger/CS312/readings/bandb-notes.pdf
Suppose we are given the following instance of the traveling salesman problem for four cities in which the symbol “i” represents infinity.
i 5 4 3 3 i 8 2 5 3 i 9 6 4 3 i
One important element of a branch and bound solution to the problem is to define a bounding function. One possible bounding function requires that we find a reduced cost matrix. The reduced cost matrix gives the additional cost of including an edge in the tour relative to a lower bound. The lower bound is computed by taking the sum of the cheapest way to leave each city plus any additional cost to enter each city. This bounding function is a lower bound because any tour must leave and enter each city exactly once, but choosing such edges may not define a solution, as we saw in class.
Note that this is not the only possible bound function. Other relaxed versions of the TSP problem are also possible.
First, let's reduce row 1. The smallest entry in row 1 is the cheapest way to leave city A. A row is reduced by taking the smallest entry in the row, 3 in this case, and subtracting it from every other entry in the row. The smallest entry (3) is also added to the lower bound. After reducing row 1, we have a bound of 3 and the following matrix:
i 2 1 0 3 i 8 2 5 3 i 9 6 4 3 i
Next, we reduce row 2 by taking the smallest entry in row 2, 2 in this case, and subtracting 2 from each entry in row 2. We add 2 to the bound and obtain the following matrix:
i 2 1 0 1 i 6 0 5 3 i 9 6 4 3 i
The remaining two rows are reduced in similar fashion. Lowest value 3 is subtracted from row 3, and 3 is likewise subtracted from row 4. The final bound is 3 + 2 + 3 + 3 = 11, and the reduced matrix so far is:
i 2 1 0 1 i 6 0 2 0 i 6 3 1 0 i
Reducing the rows only accounts for the cheapest way to leave every city. Reducing the columns includes the cheapest way to enter every city. Column reduction is similar to row reduction. A column is reduced by finding the smallest entry in a column of the reduced cost matrix, subtracting that entry from every other entry in the column and adding the entry to the bound.
The smallest entry in the first column is 1 so we subtract 1 from each entry in column 1 and add 1 to the bound. The new bound is 11 + 1 = 12 and the new matrix is:
i 2 1 0 0 i 6 0 1 0 i 6 2 1 0 i
The remaining columns are already reduced, since they already contain a 0.
Another important element of a branch and bound solution is to define the manner in which children (or “successor”) states are expanded from a given state in the state space. In the “include-exclude” approach, we generate two children for every parent: the left child represents the inclusion of an edge in the tour and the right child represents the exclusion of that same edge. The next step is to decide which edge to include or exclude. We'll assume that we want to
Choosing an edge so as to maximize a bound on the right child can lead to more aggressive pruning; consequently, this can be a compelling approach to finding a solution.
We observe that it is advisable to avoid including edges that are non-zero in the reduced matrix. If a non-zero edge in the reduced matrix is included, then the extra cost of that edge (as contained in the reduced matrix) must be added to the bound on the left side. However, we are trying to minimize the bound on the left side.
Next, get the bounds of including or excluding an edge. In the reduced matrix above, there are 5 entries that contain 0. We'll compute a pair of bounds (one for include and one for exclude) for each 0-residual-cost edge and pick the one that has the maximum right child bound and the minimum left child bound.
Start with the 0 at entry (2,1). If the edge from city 2 to 1 is included in the solution, then the rest of row 2 and column 1 can be deleted since we will leave city 2 once and enter city 1 once. We get this matrix:
i 2 1 0 i i i i i 0 i 6 i 1 0 i
This matrix must be reduced. The cost incurred during the reduction is added to the bound on the left child. In this case, no rows or columns need to be reduced. So the bound on the left child is 12 (which is the bound on the parent).
Now for the right child. If the edge between 2 and 1 is excluded, then we just replace entry (2,1) in the matrix with an infinity. We now have:
i 2 1 0 i i 6 0 1 0 i 6 2 1 0 i
This matrix must be reduced and the bound increased by the amount reduced. Only column 1 must be reduced, and it is reduced by subtracting 1 from each entry. The bound on the right child is then 12 + 1 = 13.
Stepping back for a minute, we have now determined that the bound on including edge (2,1) is 12 and the bound on excluding edge (2,1) is 13. Can we do better using a different edge? We'll answer that question by examining all of the other 0s in the matrix.
The easy way to examine the 0s is the following. To include an edge at row i column j, look at all of the 0s in row i. If column x of row i contains a 0, look at all of the entries in column x. If the 0 in row i of column x is the only 0 in column x, then replacing row i with infinities will force a reduction in column x. So add the smallest entry in column x to the bound on including the edge at row i and column j. Perform a similar analysis for the zeros in column j. This is the bound on including an edge.
To examine the bound on excluding an edge at row i and column j, add the smallest entries in row i and in column j.
A complete examination of the 0 entries in the matrix reveals that the 0s at entries (3,2) and (4,3) give the greatest right-bound, 12+2, with the least left-bound, 12. You should verify this on your own.
So we'll split on either (3,2) or (4,3); it doesn't matter which.
After deciding which edge to split on, the next step is to do the split. Doing the split generates two new reduced matrices and bounds. These are then added to the agenda.
Following the branch-and-bound algorithm from the lectures, the next step is to extract the next node from the agenda and repeat the process. The algorithm continues until the agenda is empty or time is exhausted. If you have a state in which <math>n</math> (the number of cities in the TSP instance you're solving) edges have been included, then you have a solution. When a solution is found, check to see if that solution improves the previous best solution (so far). If so, the new solution is the best solution so far. If the new solution is now the best solution so far, then the agenda may be pruned to avoid keeping unpromising states around.
Another important aspect of the algorithm is preventing early cycles and keeping track of the best solution so far. They are related. As you add edges to a partial solution (state), you'll need to keep track of which edges are part of the solution. Since a simple tour of the graph can't visit the same city twice, you'll need to delete edges from the state’s residual cost matrix that might result in a city being visited twice. To do this, you'll need to know which cities have been included. The cities included in a partial solution will need to be stored (along with the matrix and bound) in each state on the agenda.
Here are a couple of suggestions for further exploration with Branch and Bound. They are listed without prejudice against things that are or are not on this list:
You'll probably need a constant to represent an unreachable vertex or unusable edge. Your first inclination may be to choose -1 for this constant as a stand-in for Infinity. However, when you go to use that value or compare against it, you may be thinking in terms of Infinity even though it is not. A helpful alternative is a field from the Double structure called PositiveInfinity.