How to find the valid subsets and the best valid subset?

Tim Chaffin :

I'm trying to solve the The 2-dimensional 0-1 Full-Knapsack problem, using a brute force method of generating all possible subsets and picking the one with the most value. However, I have been unsuccessful in being able to find the valid subsets, as well as the best choice from among those valid subsets.

I created an Item class, with variables of value, size, and weight, as well as getters and setters.

I have also figured out how to generate all the subsets.

The subset's total weight and size must be equal to the knapsack's weight and size, otherwise the packing should not work.

But for the life of me I can't figure out how to choose the winning subset. I know that first, all the subsets that are valid (the total size and weight are equal to the knapsacks size and weight) have to be found, and then among those the one with the most value is the chosen packing.

To see if a subset is valid, I assume there has to be an if statement like

if (subsetSize == knapsackSize && subsetWeight == knapsackWeight)
      subset is valid

But I can't figure out the best way to do this.

I also can't figure out if I should be storing the subset values into a list somewhere to compare them, or if there is a better method that I'm not seeing.

For example, here is one of my failures to find the subset's values, size and weight.

for(int i = 0; i <setOfSubsets.size(); i ++) {
                for (int j = 0; j < setOfSubsets.get(i).size(); j ++) {



                    subsetSizeList.add(setOfSubsets.get(i).get(j).getSize());
                    subsetWeightList.add(setOfSubsets.get(i).get(j).getWeight());
                    subsetValueList.add(setOfSubsets.get(i).get(j).getValue());


Here is what the rest of the code looks like.

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class FullKnapsack2D {


    public static void main(String[] args) {

        Scanner s = new Scanner(System.in);
        ArrayList<Item> itemList = new ArrayList<Item>();
        List<ArrayList<Item>> setOfSubsets = new ArrayList<ArrayList<Item>>();

        System.out.println("Enter the knapsack weight and size capacity (separate by space): ");
        int knapsackWeight = s.nextInt();
        int knapsackSize = s.nextInt();

        System.out.println("How many items?");
        int numberOfItems = s.nextInt();

        for (int i = 0; i < numberOfItems; i ++) {
            System.out.println("Enter the value, size, and weight for item " + (i + 1));
            Item newItem = new Item(s.nextInt(), s.nextInt(), s.nextInt());
            itemList.add(newItem);
        }

        System.out.println("Running...");

        long startTime = System.currentTimeMillis();

        for(int i = 0; i < itemList.size(); i ++) {

            List<ArrayList<Item>> setCopy = new ArrayList<ArrayList<Item>>();

            // Make a setCopy of all existing subsets
            for(ArrayList<Item> subset : setOfSubsets) {
                setCopy.add(new ArrayList<Item>(subset));
            }

            //Add the new element to each of the existing subsets
            for(ArrayList<Item> subset : setCopy) {
                subset.add(itemList.get(i));
            }

            //Add the new element as a standalone set
            ArrayList<Item> standalone = new ArrayList<Item>();
            standalone.add(itemList.get(i));
            setCopy.add(standalone);

            setOfSubsets.addAll(setCopy);
        }

            //Print out all subsets
            for(ArrayList<Item> subset : setOfSubsets) {
                System.out.println(subset);
            }


        //if the sum total of a subset's value is higher than every other subset's value &&
        // the sum total of a subset's weight and size is equal to the knapsack's
        // weight and size, then 

        //System.out.println("Found an optimal packing:");

        //for(Item item : subset){
        // System.out.println(item.toString());
        //}
            ```




wxker :

Seems like a straightforward logical problem. Since you have already obtained all possible combinations, what you need to do is:

For each subset,

  1. Calculate the total size, weight and value of all items.
  2. If the total size is equal to the knapsack size and total weight is equal to the knapsack weight, check if the total value is the greatest so far
  3. If it is, store it as the best subset so far
ArrayList<Item> bestSubset = null;
int bestValue = 0;
for(ArrayList<Item> subset : setOfSubsets){
    int totalSize = 0;
    int totalWeight = 0;
    int totalValue = 0;
    for(Item i : subset){
        totalSize += i.getSize();
        totalWeight += i.getWeight();
        totalValue += i.getValue();
    }
    if(totalSize == knapsackSize && totalWeight == knapsackWeight && totalValue > bestValue){
        bestSubset = subset;
        bestValue = totalValue;
    }
} 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=31428&siteId=1