Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 双包背包算法_C++_Algorithm_Knapsack Problem - Fatal编程技术网

C++ 双包背包算法

C++ 双包背包算法,c++,algorithm,knapsack-problem,C++,Algorithm,Knapsack Problem,我已经找到了为2个背包的背包算法提供伪代码的方法。 我试着用C++实现它,但它并不像假定的那样工作。以下是代码: #include <cstdio> #define MAX_W1 501 #define MAX_W2 501 int maximum(int a, int b, int c) { int max = a>b?a:b; return c>max?c:max; } int knapsack[MAX_W1][MAX_W2] = {0}; in

我已经找到了为2个背包的背包算法提供伪代码的方法。 我试着用C++实现它,但它并不像假定的那样工作。以下是代码:

#include <cstdio>
#define MAX_W1 501
#define MAX_W2 501

int maximum(int a, int b, int c) {
    int max = a>b?a:b;
    return c>max?c:max;
}

int knapsack[MAX_W1][MAX_W2] = {0};

int main() {
    int n, s1, s2, gain, weight; // items, sack1, sack2, gain, cost

    scanf("%d %d %d", &n, &s1, &s2);

    // filing knapsack
    for (int i = 0; i < n; i++) {
        scanf("%d %d", &gain, &weight);

        for (int w1 = s1; w1 >= weight; w1--) {
            for (int w2 = s2; w2 >= weight; w2--) {
                knapsack[w1][w2] = maximum(
                    knapsack[w1][w2],                 // we have best option
                    knapsack[w1 - weight][w2] + gain, // put into sack one
                    knapsack[w1][w2 - weight] + gain  // put into sack two
                );
            }
        }
    }

    int result = 0;

    // searching for result
    for (int i = 0; i <= s1; i++) {
        for (int j = 0; j <= s2; j++) {
            if (knapsack[i][j] > result) {
                result = knapsack[i][j];
            }
        }
    }

    printf("%d\n", result);

    return 0;
}
我有以下输出:

13
显然这是错误的,因为我可以把所有的东西(1,2放在第一个袋子里,剩下的放在第二个袋子里)加起来是16。 如果能解释一下伪代码的错误,我将不胜感激

我几乎没有更新,因为有些人在理解输入格式方面有问题:

  • 第一行包含3个数字,如下所示:物品数量、一袋容量、二袋容量
  • 后面有n行,每行包含2个数字:增益,第i项的成本
  • 假设袋子不能大于500

  • <>你使用的算法看起来不正确,因为它只考虑对象在两个袋子中恰好匹配的情况。我对您的代码进行了以下更改,现在它运行正常:

    #include <algorithm>
    
    using std::max;
    
    int max3(int a, int b, int c) {
        return max(a, max(b, c));
    }
    

    下面是对代码的修改,以使其正常工作:-

    #include <cstdio>
    #define MAX_W1 501
    #define MAX_W2 501
    
    int maximum(int a, int b, int c) {
        int max = a>b?a:b;
        return c>max?c:max;
    }
    
    int knapsack[MAX_W1][MAX_W2] = {0};
    
    int main() {
        int n, s1, s2, gain, weight; // items, sack1, sack2, gain, cost
    
        scanf("%d %d %d", &n, &s1, &s2);
    
        // filing knapsack
        for (int i = 0; i < n; i++) {
            scanf("%d %d", &gain, &weight);
        // need to fill up all the table cannot stop if one sack is full because item might fit in other
            for (int w1 = s1; w1 >= 0; w1--) {
                for (int w2 = s2; w2 >= 0; w2--) {
                     int val1=0,val2=0;
                     if(weight<=w1)
                       val1 = knapsack[w1 - weight][w2] + gain;
                     if(weight<=w2)
                       val2 = knapsack[w1][w2 - weight] + gain;
    
                     knapsack[w1][w2] = maximum(
                        knapsack[w1][w2],                   // we have best option
                         val1,              // put into sack one
                         val2               // put into sack two
                      );
    
    
                }
            }
        }
    
    
        // No need to search for max value it always be Knapsack[s1][s2]
        printf("%d\n", knapsack[s1][s2]);
    
        return 0;
    }
    
    #包括
    #定义最大值W1 501
    #定义最大值2 501
    最大整数(整数a、整数b、整数c){
    int max=a>b?a:b;
    返回c>max?c:max;
    }
    int背包[MAX_W1][MAX_W2]={0};
    int main(){
    int n,s1,s2,增益,重量;//物品,袋1,袋2,增益,成本
    scanf(“%d%d%d”、&n、&s1和&s2);
    //档案袋
    对于(int i=0;i=0;w1--){
    对于(int w2=s2;w2>=0;w2--){
    int val1=0,val2=0;
    
    if(weight)感谢您的回答,因为它第一次是正确的,并解释算法不正确的原因。事实上,当我想到它时,我真的很怀念这种情况。当所有sack都没有足够的容量(尽管>0)时会发生什么为了适应重量。我认为需要考虑这种情况。+1用于在数组中查找答案的优化。关于代码正在执行的操作的一些解释是非常可取的。您如何能够跟踪放入每个袋子中的项目?0-1问题使用第一维来跟踪n,但在这种情况下,它是replac我尝试了一个3d数组,但我不确定如何将n合并到上述算法中。@Bendrix您需要在数组中添加另一个索引,以保存n乘以w1乘以w2中的所有前n个项目,因为最初的问题只是获取最大值,而不管选择的项目是什么,它通过替换以前的选择来工作,因为我们只需要注意最后n-1项的最大值。在您的情况下,您可以在每次外循环迭代后增加i,并使用上述逻辑计算背包[i][w1][w2],在检索答案时,您必须从背包[n-1][w1][w2]向后工作,如果背包[i-1][w1-w[i][w2]或背包[i-1][w1][w2-w[i]+w[i]>背包[i-1][w1],则选择i[w2]。
    for (int w1 = s1; w1 >= 0; w1--) {
        for (int w2 = s2; w2 >= 0; w2--) {
            if (w1 >= weight && w2 >= weight) // either sack has room
            {
                knapsack[w1][w2] = max3(
                    knapsack[w1][w2],                 // we have best option
                    knapsack[w1 - weight][w2] + gain, // put into sack one
                    knapsack[w1][w2 - weight] + gain  // put into sack two
                );
            }
            else if (w1 >= weight) // only sack one has room
            {
                knapsack[w1][w2] = max(
                    knapsack[w1][w2],                 // we have best option
                    knapsack[w1 - weight][w2] + gain  // put into sack one
                );
            }
            else if (w2 >= weight) // only sack two has room
            {
                knapsack[w1][w2] = max(
                    knapsack[w1][w2],                 // we have best option
                    knapsack[w1][w2 - weight] + gain  // put into sack two
                );
            }
        }
    }
    
    #include <cstdio>
    #define MAX_W1 501
    #define MAX_W2 501
    
    int maximum(int a, int b, int c) {
        int max = a>b?a:b;
        return c>max?c:max;
    }
    
    int knapsack[MAX_W1][MAX_W2] = {0};
    
    int main() {
        int n, s1, s2, gain, weight; // items, sack1, sack2, gain, cost
    
        scanf("%d %d %d", &n, &s1, &s2);
    
        // filing knapsack
        for (int i = 0; i < n; i++) {
            scanf("%d %d", &gain, &weight);
        // need to fill up all the table cannot stop if one sack is full because item might fit in other
            for (int w1 = s1; w1 >= 0; w1--) {
                for (int w2 = s2; w2 >= 0; w2--) {
                     int val1=0,val2=0;
                     if(weight<=w1)
                       val1 = knapsack[w1 - weight][w2] + gain;
                     if(weight<=w2)
                       val2 = knapsack[w1][w2 - weight] + gain;
    
                     knapsack[w1][w2] = maximum(
                        knapsack[w1][w2],                   // we have best option
                         val1,              // put into sack one
                         val2               // put into sack two
                      );
    
    
                }
            }
        }
    
    
        // No need to search for max value it always be Knapsack[s1][s2]
        printf("%d\n", knapsack[s1][s2]);
    
        return 0;
    }