20-CS-122-001 Computer Science II Spring 2012
Knapsack Problem

Virtual functions, classes, inheritance, lists, queues, stacks, applications

Prev      Next      All Lectures      Source

Knapsack Problem:

Given: A collection of items, each with a value and a size. A "knapsack" of specified size, say S.

Find: A subset of items whose sizes sum to S (that is, precidely fill the knapsack) and whose sum of values is greatest among all subsets filling the knapsack.

In the solution below data is input via file with first line specifying S and each remaining line specifying the size and value of each item.

#include <fstream>
#include <iostream>
#include <stdlib.h>
using namespace std;

class Answer;

class Item {
friend class Answer;
   int size, value;
   Item *next;

 public:
   Item (int size, int value, Item *next) {
      this->size = size;
      this->value = value;
      this->next = next;
   }
   Answer *profit (int s);   
};

class Answer {
friend class Item;
   Item *item;
   int profit;
   Answer *answer;
   
 public:
   Answer (Item *item, int profit, Answer *answer) {
      this->item = item;
      this->profit = profit;
      if (answer != NULL) this->profit += answer->profit;
      this->answer = answer;
   }

   ~Answer() {
      if (answer != NULL) delete answer;
   }

   int printResult () {
      cout << "[" << item->value << "," << item->size << "] ";
      if (answer != NULL) return item->value + answer->printResult();
      return item->value;
   }
};

Answer *Item::profit (int s) {
   if (s < 0) return NULL;
   if (next == NULL) {
      if (size == s) {
         return new Answer(this, value, NULL);
      } else return NULL;
   }
   Answer *p1 = next->profit(s - size);
   Answer *p2 = next->profit(s);
   if (p1 == NULL) return p2;
   if (p2 == NULL) return new Answer(this, value, p1);
   if (p1->profit+value < p2->profit) { delete p1; return p2; }
   else { delete p2; return new Answer(this, value, p1); }
}

int main (int argc, char **argv) {
   Item *items = NULL;
   Answer *result;
   int S, size, value;

   if (argc != 2) {
      cout << "Usage: " << argv[0] << " \n";
      exit (0);
   }

   fstream fin(argv[1],ios::in);
   fin >> S;
   while (fin >> size >> value) items = new Item(size, value, items);
   fin.close();

   if ((result = items->profit(S)) == NULL) {
      cout << "No Solution\n";
      exit(0);
   }
   cout << "\nProfit: " << result->printResult() << "\n";
}