C++ 双包背包算法
我已经找到了为2个背包的背包算法提供伪代码的方法。 我试着用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
#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。
如果能解释一下伪代码的错误,我将不胜感激
我几乎没有更新,因为有些人在理解输入格式方面有问题:
<>你使用的算法看起来不正确,因为它只考虑对象在两个袋子中恰好匹配的情况。我对您的代码进行了以下更改,现在它运行正常:
#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;
}