序文:
0-1ナップザック問題について書いたのはかなり前であまり覚えていませんが、今後の自分自身の参考のためにこの記事を書きました。時間。
文章
0-1 ナップザック問題は、容量が Capacity であるナップザックがあると仮定した場合のような問題です。地面には n 個のアイテムの山があり、各アイテムには重さ w と値 v の 2 つのプロパティがあります。
要件は、重量が最大容量以下で、値が最大になるようなアイテムの組み合わせを見つけることです。
動的計画法の考え方は、0-1 ナップザック問題を解決します。
まず、2 次元配列 dp を作成します。ここで、dp[i][j] は、最初の i 個のアイテムのみが使用される場合に、ナップサックの容量が j のときに取得できる最大値を表します。つまり、最初の i 個のアイテムからいくつかのアイテムを選択し、これらのアイテムの合計重みは j 以下ですが、それらの値の合計が最大となり、この最大値の合計が dp[ として記録されます。 i][j]。
dpの行幅はnで合計n個のアイテムがあることを示し、列幅はcapacityでバックパックの最大容量がcapacityであることを示します。
おおよそ次のようになります。
n 個のアイテムがあり、各アイテムに 1 ~ n の番号が付けられているとします。wi、vi はそれぞれ i 番目のアイテムの重さと価値を表します。
そして、1行目のj列は、アイテム1のみを使用し、バックパックの容量がjの場合に、バックパックに入れることができる最大値を示します。
したがって、最初の行では次のようになります。
(1) w1 > j の場合、ナップザックの容量 j は最初のアイテムの重量を収容できないため、この時点では 0 を記入する必要があります。
(2) w1 <= j の場合、バックパックの容量は最初のアイテムの重量に対応できるため、この時点で v1 を入力する必要があります。
したがって、最初の行の要素には 0 または v1 のみを入れることができ、前半は 0、後半は v1 になります。
n==10 とすると、ナップザックの容量は 3 (最終容量) となります。
1、2、3(各項目の番号)
2,7,1(各アイテムの重量)
1,2,3(各項目の値)
w1==7 と仮定すると、最初の行は次のようになります。
i>1 とすると、i 番目の行の j 番目の列は次のように入力されます。
(1) wi > j のとき、バックパックに積んだ物をすべて空にしても、i 番目の物が入りません。
この時点で dp[i][j] = dp[i-1][j] となります。つまり、最初の i 項目を考慮すると、最初の i-1 項目と同じ結果になります。
(2) wi <= j の場合、i 番目の項目を に入れることを検討できます。
(2-1) i 番目の項目を入れる場合、i 番目の項目は wi の容量を占有することになりますが、残りの容量はどれくらいの値を保持できますか? dp[m][n] は、容量が制限されている場合、最初の m 個のアイテムのみをロードできることを意味するため、dp[i-1][j-wi] の値は最大でロードできる必要があることに疑いの余地はありません。 n は の最大値です。つまり、dp[i][j] = dp[i-1][j-wi] + vi となります。
(2-2) i 番目の項目が入力されない場合、合計値は変更されません。つまり、 dp[i][j] = dp[i-1][j] となります。
(2-3)
それで、i 番目の項目をその中に入れますか? 入れられるんだから入れればいいじゃないかという人もいるかもしれない。
入れたらさらに価値が上がるんじゃないでしょうか?実際、必ずしもそうとは限りませんが、ここで述べたことは、バックパックに入れるという意味なので、
入れたものが空になったら、i 番目のアイテムを入れることができます。ただし、i 番目の項目を強制的に入れた後は、可能です
その結果、せっかく入れたものの一部がはみ出してしまい、置くスペースがなくなってしまい、合計金額が下がってしまう可能性があります。
したがって、 wi <= j の場合、 dp[i][j] = max{dp[i-1][j-wi] + vi , dp[i-1][j]}
最終的な形式は次のようになります。
したがって、表からわかるように、バックパックの容量が 3、アイテムの数が 3 の場合、
各項目番号は 1、2、3 です。
各アイテムの重量は次のとおりです: 2,7,1
各項目の値が1、2、3の場合、
バックパックに入れることができる最大値は 4 (フォームの右下の数字) です。
練習する:
この写真はリコウで話題になっていますが、0-1ナップザック問題でもあります