return应该放在背包JAVA中的最佳项目集

时间:2018-04-22 10:06:30

标签: java algorithm knapsack-problem

我目前正在处理背包问题,以返回最佳解决方案的集合。

这是我的方法:

public static int knapsackArray(int val[], int wt[], int W) {
    //Get the total number of items. 
    int N = wt.length;

    //Create a matrix. 
    int[][] V = new int[N + 1][W + 1]; 

    //all columns at row 0 to be 0
    for (int col = 0; col <= W; col++) {
      V[0][col] = 0;
    }

    //Fill the first row with 0
    for (int row = 0; row <= N; row++) {
      V[row][0] = 0;
    }

    for (int item=1;item<=N;item++){
      for (int weight=1;weight<=W;weight++){
        if (wt[item-1]<=weight){
          V[item][weight]=Math.max (val[item-1]+V[item-1][weight-wt[item-1]], V[item-1][weight]);
        }
        else {
          V[item][weight]=V[item-1][weight];            
        }
      }
    }

    //Printing the matrix
    for (int[] rows : V) {
      for (int col : rows) {
        System.out.format("%5d", col);
      }
      System.out.println();
    }

    return V[N][W];
  }

我有另一种方法,它将Item集和预算作为参数,并为此问题返回一组最佳解决方案:

public static Set<Item> knapsack(Set<Item> items, int budget) {
    //create array of wieghts
    int[] weights = new int[items.size()];
    //create array of values
    int[] values = new int[items.size()];

    int i = 0;
    for (Item x : items){
      weights[i] = x.getWeight();
      values[i] = x.getValue(); 
      //System.out.println(x);
      i++;
    }
    /*int N = weights.length;
    int[][] V = new int[N + 1][budget + 1];*/

    int j = knapsackArray(values, weights, budget);
    System.out.println(j);
    return null;
  }

我的问题是如何将此矩阵设置为最佳项目集。这是 - 我的方法 - 甚至是解决这个问题的好方法吗?

1 个答案:

答案 0 :(得分:0)

除了您创建的值矩阵,在knapsackArray内,您还可以创建第二个矩阵来跟踪您到达该点的方式。 (即你采取的最后一个元素)这样,一旦你完成了你的DP解决方案,你就可以追溯你在路上获得的所有元素。另外,为了能够将值传递回knapsack,您需要将设置参数传递给knapsackArray

以下是我概述的方法的粗略演示。

public static int knapsackArray(int val[], int wt[], int W, Set<int> itemIndices) {
    // ...

    // Create a matrix. 
    int[][] V = new int[N + 1][W + 1]; 
    int[][] G = new int[N + 1][W + 1]; 

    // ...

    for (int item=1;item<=N;item++) {
        for (int weight=1;weight<=W;weight++) {
            if (wt[item-1]<=weight) {
                int candidate = val[item-1] + V[item-1][weight-wt[item-1]];
                if(candidate > V[item-1][weight]) {
                    V[item][weight] = candidate;
                    G[item][weight] = item - 1;
                }
                else {
                    V[item][weight] = V[item-1][weight];
                    G[item][weight] = -1;
                }
            }
            else {
                V[item][weight]=V[item-1][weight];
                G[item][weight] = -1;
            }
        }
    }

    int currentItem = N;
    int currentWeight = W;
    while(currentItem >= 1) {
        if(G[currentItem][currentWeight] >= 0) {
            itemIndices.add(currentItem - 1);
            currentWeight = currentWeight - wt[currentItem - 1];
            currentItem = G[currentItem][currentWeight] + 1;
        }
        else {
            currentItem = currentItem - 1;
        }
    }

    // ...

    return V[N][W];
}

执行此操作后,您可以实际处理该参数Set<int> itemIndices中的索引,并在Set<Item> items方法中填充knapsack,如下所示。

public static Set<Item> knapsack(Set<Item> items, int budget) {
    // ...

    Set<Item> itemsToAdd;
    Set<int> itemIndices;
    int j = knapsackArray(values, weights, budget, itemIndices);
    int i = 0;
    for (Item x : items) {
        if(itemIndices.contains(i)) {
            itemsToAdd.add(x);
        }
        i++;
    }

    return itemsToAdd;
}