Imagine that you have N old textbooks with integer weights Wi, for i from 1 to N. You also have a backpack with an integer weight capacity of C. There's a used book store down the street that will give you Pi dollars for book i. How much money can you make in one trip?
That's the 0-1 knapsack problem in a nutshell. The obvious solution of trying every possible combination is silly. A slightly better method is known as branch-and-bound; you run a breadth-first search of the combination space, but prune branches that cannot lead to optimal solutions.
A much, much better solution follows from expressing the problem as a recurrence relation and taking a dynamic programming approach. For the non-CS people (and the CS people who have forgotten), dynamic programming algorithms store common subproblems in a table and fill the table until they reach the solution.
The table T for this problem is indexed by a book and a capacity. Entry Ti, j is the maximum profit that can be obtained with a capacity j and books 1 through i. The capacities range from 1 to C, and the books range from 1 to N. Entry Ti, j is calculated by comparing the profit at capacity j without book i to the profit at capacity j - Wi with book i. More formally:
Ti, j = max { Ti-1, j , Ti - 1, j - Wi + Pi }
So what does that do? Assume that if you're examining book i and capacity j, you already know the maximum profit for all the capacities less than j for all the books less than i. Including book i decreases your remaining capacity by Wi, so you need to fill up capacity j - Wi in a way that maximizes the profit. Luckily, that's already in entry Ti-1, j-Wi. The total profit possible from including book i is thus Ti-1, j-Wi + Pi. Not including book i simply maintains the status quo, the profit of which is already in entry Ti-1, j. The larger of the two amounts will decide inclusion of i.
If those two amounts are the same, be a packrat and don't include i. You may find someone who's willing to pay more for that book later.
There are a few corner cases to flesh out... What if j - Wi is negative? Then item i doesn't fit at all, and the choice has been made for you. And what if i is 1? That is, how do you bottom out the recursion? The entries in the first row are determined simply by whether or not book i fits in capacity 1. (You may want to start with the smallest weight.)
After all this, the total profit is in entry TN, C. You can find the books that achieve that profit by backtracking over the choices.
Write a parallel program both to solve the 0-1 knapsack problem using the dynamic programming algorithm described above. Also report the contents of the backpack. You can use MPI, UPC, or Titanium. Analyze and model the performance of the algorithm you implement. Use the NoW, the Millennium cluster, or the T3E.
For the backtracking phase, you need to use more than one processor in some way. Do not simply send the entire table to one processor and have it do the backtracking. You don't have to be excessively clever, but think about making the back solve efficient.
Your group should put together a web page describing your implementation and its performance. Mail me a URL to a tar file containing the page, the programs, and any necessary or useful additional information.
Justify the design choices in your program, and explain any interesting performance effects you see. Explanations that are based on a well-understood system model (PRAM, LogP, etc.) are the most convincing.
The computations in this problem's forward solve are easy to model in an abstract way (the amount of computational work is proportional to the size of the table, etc.), so spend some time predicting how your implementation will perform. The interesting bit will be in communication. The amount of communication will depend on the input weight set. Predict how different weight distributions will affect your performance.
The page should include appropriate speed-up plots or other pretty pictures (traces for low-level, systemic effects; distribution plots for weight effects; etc.) to justify your conclusions.
For using more than 16 or so processors on the T3E, you'll need to use the batch system. NERSC has a batch tutorial available.
I swiped the problem from Dr. Culler's CS258 class. You might find other useful tips there. It's a fun little problem.
Some (quickly skimmed) references to parallel, knapsack-ish problems follow. The two papers are on the general knapsack problem, but some of the observations on the back-solve carry over. In particular, check the first one.
I keep saying that I've seen things relating the backsolve to shortest path algorithms, but I'm wrong. They can be related to longest path algorithms...
Main CS267 page, and the TA's CS267 page
E. Jason Riedy