背包问题-查找采取了哪些物品

时间:2018-11-16 14:17:29

标签: c++ algorithm knapsack-problem

我需要找到背包问题的所有最佳解决方案。 这是我的代码

Hello World!
358 [main] INFO yahoofinance.quotes.query1v7.QuotesRequest - Sending request: https://query1.finance.yahoo.com/v7/finance/quote?symbols=GOOG
3687 [main] INFO yahoofinance.histquotes2.HistQuotes2Request - Sending request: https://query1.finance.yahoo.com/v7/finance/download/GOOG?period1=1510830000&period2=1542366000&interval=1d&crumb=FlUQht4hFF9
3756 [main] INFO yahoofinance.histquotes2.HistQuotes2Request - Parsing CSV line: 2017-11-16,1022.520020,1035.920044,1022.520020,1032.500000,1032.500000,1129700
3758 [main] INFO yahoofinance.histquotes2.HistQuotes2Request - Parsing CSV line: 2017-11-17,1034.010010,1034.420044,1017.750000,1019.090027,1019.090027,1397100
3758 [main] INFO yahoofinance.histquotes2.HistQuotes2Request - Parsing CSV line: 2017-11-20,1020.260010,1022.609985,1017.500000,1018.380005,1018.380005,953500

输入数据为:

void knapSack(int W, int wt[], int val[], int n)
{
   int i, w;
   int K[W+1][n+1];
   for (w = 0; w <= W; w++)
   {
    for(i=0;i<=n;i++){
        if(i==0)
            K[w][i]=0;

        if(w<wt[i-1] && i!=0)
            K[w][i]=K[w][i-1];

        if(w>=wt[i-1] && i!=0)
            K[w][i]=max(K[w][i-1],K[w-wt[i-1]][i-1]+val[i-1]);

       }
   }

   i=n;
  int j=W;
   while(i,j>0){
    if(K[j][i]!=K[j][i-1]){
        cout<<"Item "<<i<<" is in the bag"<<endl;
        i=i-1;
        j=j-wt[i-1];
    }
    else
        i=i-1;
   }
}

输出应该是这样的:

4 6 //n W
2 1 //p1 w1
3 2 //p2 w2
3 4 //p3 w3
4 5 //p4 w4

我的代码的第一部分是包装袋,效果很好,但是我试图找出被拿走的物品的第二部分却给了我答案:项目3,项目2,项目1错误,因为有2种解决方案:您采用第1项和第4项,或者第2项或第3项。我该如何解决?

下图是带有包装表溶液的表

enter image description here

1 个答案:

答案 0 :(得分:1)

我将使用与您用来最大化值的公式相同,以查看选择了哪些项目,即

if (K[w][i] == K[w-wt[i-1]][i-1] + val[i-1]) 然后选择项目i,否则不选择该项目,然后转到上一个项目i-1

另外,可能会有多于1套的物品,当它们被拾取时可以产生最大值。

在这种情况下,请在数组K[W][..]中查找每个这样的值以获取最大值K[W][n],然后从该点开始遍历数组以获取所选择的项目。

代码是:

void knapSack(int W, int wt[], int val[], int n)
{
   int i, w;
   int K[W+1][n+1];
   for (w = 0; w <= W; w++)
   {
    for(i=0;i<=n;i++){
        if(i==0)
            K[w][i]=0;

        if(w<wt[i-1] && i!=0)
            K[w][i]=K[w][i-1];

        if(w>=wt[i-1] && i!=0)
            K[w][i]=max(K[w][i-1],K[w-wt[i-1]][i-1]+val[i-1]);

       }
   }

   cout << "\n" << "Maximum value obtained is : " << K[W][n] << "\n";
   int j;
   for ( j=1; j<=n; j++ ) {
     if (K[W][j] == K[W][n]) {
       int w = W;
       int i = j;
       while(i>0 && w>0){
          if (K[w][i] == K[w-wt[i-1]][i-1] + val[i-1]) {
            cout << "Item " << i << " is in the bag" << "\n";
            w = w - wt[i-1];
            i--;
          } else {
            i--;
          }
        }
      cout<< "\n";
     }
   }

}