-1

For school I am supposed to use recursive backtracking to solve a Boat puzzle. The user inputs a maximum weight for the boat, the amount of item types, and a weight and value for each item type. More than one of each item type can be placed on the boat.

Our assignment states "The program should find a solution that fills the boat with selected valuable items such that the total value of the items in the boat is maximized while the total weight of the items stays within the weight capacity of the boat."

It also has pretty specific template for the recursive backtracking algorithm.

Currently I am using contiguous lists of items to store the possible items and the items on the boat. The item struct includes int members for weight, value, count (of how many times it is used) and a unique code for printing purposes. I then have a Boat class which contains data members max_weight, current_weight, value_sum, and members for each of the contiguous lists, and then member functions needed to solve the puzzle. All of my class functions seem to be working perfectly and my recursion is indeed displaying the correct answer given the example input.

The thing I can't figure out is the condition for extra credit, which is, "Modify your program so that it displays the best solution, which has the lowest total weight. If there are two solutions with the same total weight, break the tie by selecting the solution with the least items in it." I've looked at it for awhile, but I'm just not sure how I can change it make sure the weight is minimized while also maximizing the value. Here is the code for my solution:

bool solve(Boat &boat) {
    if (boat.no_more()) {
        boat.print();
        return true;
    }
    else {
        int pos;
        for (int i = 0; i < boat.size(); i++){
            if (boat.can_place(i)) {
                pos = boat.add_item(i);
                bool solved = solve(boat);
                boat.remove_item(pos);
                if (solved) return true;
            }

        }
        return false;
    }
}

All functions do pretty much exactly what their name says. No more returns true if none of the possible items will fit on the boat. Size returns the size of the list of possible items. Adding and removing items change the item count data and also the Boat current_weight and value_sum members accordingly. Also the add_item, remove_item and can_place parameter is the index of the possible item that is being used. In order to make sure maximized value is found, the list of possible items is sorted in descending order by value in the Boat's constructor, which takes a list of possible items as a parameter.

Also here is an example of what input and output look like: input and output example

Any insight is greatly appreciated!

Victoria Potvin
  • 127
  • 1
  • 11
  • 1
    This is most commonly known as the "knapsack problem" - the [Wikipedia entry](http://en.wikipedia.org/wiki/Knapsack_problem) may be of some use as a starting point. – JBentley Jun 17 '14 at 21:33

1 Answers1

1

It turned out that the above solution was correct. The only reason I was getting an incorrect answer was because of my implementation of the nomore() function. In the function I was checking if any item in the possible items list was less than the weight left on the boat. I should have been checking if they were less than or equal to the weight on the boat. A simple mistake.

The wikipedia entry was indeed of use and I enjoyed the comic :)

Victoria Potvin
  • 127
  • 1
  • 11