0/1ナップザック動的プログラミングアルゴリズムのスペース最適化は、ナップザック容量と等しいサイズの1次元アレイ(例えば、A)最初のi個のアイテムが考慮され、ナップザックの容量がwであれば、A [w]は合計値を表す、各反復iで(必要であれば)A [w]を単純に上書きする。 この最適化が使用されている場合、DPアルゴリズムの各反復でいくつかの追加情報を保存することで、選択したアイテムのリストを再構築する方法はありますか?例えば、ベルマンフォードアルゴリズムでは、同様の空間最適化を実施することができ、先行ポインタのリスト、すなわち最後のホップ(または、ソース/宛先指向アルゴリズムが書かれている)。スペース最適化された0/1ナップザック実装からのアイテムリストの再構成
ここでは、ans [i] [j]が最初のi項目を考慮した合計値を示すような2-dベクトルansを構築する動的プログラミングを使用する0/1ナップザック問題のC++関数を示します。ナップザック容量j。提案された解決策と、一定の目標値について、関係アイテムのセットを得ることは事実上不可能であり、私の理解に
void knapsack(vector<int> v,vector<int>w,int cap){
//v[i]=value of item i-1
//w[i]=weight of item i-1, cap=knapsack capacity
//ans[i][j]=total value if considering 1st i items and capacity j
vector <vector<int> > ans(v.size()+1,vector<int>(cap+1));
//value with 0 items is 0
ans[0]=vector<int>(cap+1,0);
//value with 0 capacity is 0
for (uint i=1;i<v.size()+1;i++){
ans[i][0]=0;
}
//dp
for (uint i=1;i<v.size()+1;i++) {
for (int x=1;x<cap+1;x++) {
if (ans[i-1][x]>=ans[i-1][x-w[i-1]]+v[i-1]||x<w[i-1])
ans[i][x]=ans[i-1][x];
else {
ans[i][x]=ans[i-1][x-w[i-1]]+v[i-1];
}
}
}
cout<<"Total value: "<<ans[v.size()][cap]<<endl;
//reconstruction
cout<<"Items to carry: \n";
for (uint i=v.size();i>0;i--) {
for (int x=cap;x>0;x--) {
if (ans[i][x]==ans[i-1][x]) //item i not in knapsack
break;
else if (ans[i][x]==ans[i-1][x-w[i-1]]+v[i-1]) { //item i in knapsack
cap-=w[i-1];
cout<<i<<"("<<v[i-1]<<"), ";
break;
}
}
}
cout<<endl;
}
私は質問について少し混乱しています。 1次元の状態空間Aを記述しますが、実装は2次元の状態空間ansを使用しますか?したがって、基本的に_space_optimized_ implementaionは 'ans'を使用しますが、' i'の値が小さい場合はその行を破棄しますか? – Codor
@Codor 2次元ベクトルからアイテムのリストを再構成する方法を示しています。私はそれが1-dベクトルであれば、どうやってやるのか分かりません。その1-dベクトルで合計値を計算するのは簡単ですが、ans [i] [x]の代わりにans [x]を使用し、ans [x]を上書きします。項目iが含まれていない場合、ans [x]は反復のために変更されず、それ以外の場合はans [i] + v [i-1]に置き換えられます。 – kabir