与えられた問題:2つの拘束を持つナップザック
0/1-ナップサックの問題で、n個のアイテムのそれぞれが重みw_iと値v_iを持ちます。重みW.
の重み付けにまとめるアイテムの最大合計値を探す。しかし2 constraitsあります
- はナップザックのすべての項目の総重量は正確に W する必要があります。
- の合計額はであり、でもでなければなりません。
両方の制約に注意を払うアルゴリズムを見つけたいと思います。私はすでに一度にどのように私がそれらの1つに注意を払うことができるかを知った。ここで
は1(正確な重量W)をconstraitに注意を払っている私の実装です:
public class KnapSackEvenAmount {
public static void main(String[] args) {
int[] weights = new int[] {4, 1, 5, 8, 3, 9, 2}; //weights
int[] values = new int[] {2, 12, 8, 9, 3, 4, 3}; //values
int n = weights.length;
int W = 10;
int[][] DP_odd = new int[n+1][W+1];
int[][] DP_even = new int[n+1][W+1];
for(int i = 0; i < n+1; i++) {
for(int j = 0; j < W+1; j++) {
DP_even[i][j] = -1;
DP_odd[i][j] = -1;
if(i == 0 || j == 0) {
DP_odd[i][j] = -1;
DP_even[i][j] = 0;
} else if(j - weights[i-1] >= 0) {
if(DP_odd[i-1][j - weights[i-1]] >= 0) {
DP_even[i][j] = Math.max(DP_even[i-1][j], DP_odd[i-1][j - weights[i-1]] + values[i-1]);
}
if(DP_even[i-1][j - weights[i-1]] >= 0) {
DP_odd[i][j] = Math.max(DP_odd[i-1][j], DP_even[i-1][j - weights[i-1]] + values[i-1]);
}
}
if(i > 0) {
DP_odd[i][j] = Math.max(DP_odd[i][j], DP_odd[i-1][j]);
DP_even[i][j] = Math.max(DP_even[i][j], DP_even[i-1][j]);
}
}
}
System.out.println("Result: " + DP_even[n][W]);
}
}
Result: 21
: public class KnapSackExactWeight {
public static void main(String[] args) {
int[] w = new int[] {4, 1, 5, 8, 3, 9, 2}; //weights
int[] v = new int[] {2, 12, 8, 9, 3, 4, 3}; //values
int n = w.length;
int W = 10; // W (max weight)
int[][] DP = new int[n+1][W+1];
for(int i = 1; i < n+1; i++) {
for(int j = 0; j < W+1; j++) {
if(i == 0 || j == 0) {
DP[i][j] = 0;
} else if (j - w[i-1] >= 0) {
DP[i][j] = Math.max(DP[i-1][j], DP[i-1][j - w[i-1]] + v[i-1]);
} else {
DP[i][j] = -Integer.MAX_VALUE;
}
}
}
System.out.println("Result: " + DP[n][W]);
}
}
Result: 22
そして、ここでは、(アイテムの量さえも)口座に2をconstraitのテイク私の実装です
私は2つのDPテーブル(DP_evenとDP_odd)を使用して、DP_oddの項目が奇数で、DP_evenの項目が均等なナップザックに最適なソリューションを保存します。
私の問題は、両方の拘束が一緒に機能するように実装する方法です。これを解決する方法はありますか?
(何が私の質問に不明である場合は、ちょうど頼む!)
2番目のアルゴリズムに問題がありますか?正しい答えが得られない例を挙げられますか?私には、既に両方の制約が組み込まれているようですね。 –
今はw [1](= 1)とw [3](= 8)を使用しているので、最初のconstraitは1 + 8 = 9!= 10のように真ではありません。 (w [0]、w [1]、w [4]、w [6]は10の重さで値は20です) – zutru