我正在尝试实现我自己版本的贪婪算法来解决背包问题(在这个问题中,你可以添加对象的一部分,而不是作为整体的必要对象)。
我按照这个逻辑写了下面的代码:-创建了一个名为'profitPerWeight‘的数组,我在其中存储了所有对象的利润/重量的值-在一个'knapSack()’函数中,我检查哪个项目具有最大的利润价值,并使用另一个名为'getFraction()‘的函数检查对象的哪一部分适合装入袋子(在我的例子中,袋子容量是15 )。-在'getFraction()‘函数中,如果项目作为一个整体或项目的哪个部分适合,我返回1(例如:如果袋子重量当前是7,项目是2,我返回1,因为项目可以放在袋子里而不超过容量: 15。如果重量是7,项目是9,我返回9%7,因为只有项目(9)的一部分(2)可以在不超出允许容量的情况下放入袋子。-然后我将包中物品的一部分相加,我有另一个数组'bagContent[]‘,它为每个对象存储了包中包含的部分。
例如:如果bagContent = {1,1,0,0,2/3}表示我存储在包中: obj0,obj1和2/3*obj4。
这个问题的输出应该是:1*第一个2/3*第二个1*第三个0*第四个1*第五个1*第六个1*第七个
然而,当我运行我的解决方案时,我得到了一个不同的结果:1*第一个1*第二个1*第三个0*第四个1*第五个1*第六个1*第七个。
如你所见,第二个是'1‘而不是'2/3’:(.我不知道为什么我猜是小数点的东西,我需要修正。我尝试了几种方法,但都不起作用。或者可能是我的逻辑有问题。我对算法不是很有经验:( .Please,告诉我我做错了什么,我该如何纠正这一点。谢谢。代码如下:
// Knapsack problem: Greedy method
// Objects: 1, 2, 3, 4, 5, 6, 7
// Profits: 10, 5, 15, 7, 6, 18, 3
// Weights: 2, 3, 5, 7, 1, 4, 1
// Fill a 15kg knapsack with the objects(they can be divisible) so that the profit is maximum
// Output should be:
// 1*first 2/3*second 1*third 0*fourth 1*fifth 1*sixth 1*seventh
#include <iostream>
#include <iomanip>
using namespace std;
char *objects[] = {"First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh"};
int profits[] = {10, 5, 15, 7, 6, 18, 3};
int weights[] = {2, 3, 5, 7, 1, 4, 1};
double profitPerWeight[7] = {5, 1.3, 3, 1, 6, 4.5, 3};
int bagWeight = 0;
int bagCapacity = 15;
int fraction;
int bagContent[7] = {0,0,0,0,0,0,0};
int itemToAddIndex = 0;
// function that returns the index of most profitable item in 'profitPerWeight[]'
int MaxProfitItem()
{
int index = 0;
int mostPr = profitPerWeight[0];
for(int i=1; i<7; i++)
{
if(profitPerWeight[i] > mostPr)
{
mostPr = profitPerWeight[i];
index = i;
}
}
return index;
}
// function that returns true if the current fraction of an
// item can fit in the bag or false if the
// current fraction of an item cannot fit in the bag
bool itemFits(int index)
{
if(bagWeight + weights[index] <= 15)
return true;
return false;
}
// function that divides an item with a specified fraction
void divideItem(int index, double fraction)
{
weights[index] = weights[index] / fraction;
}
// function that returns which fraction of an item can fit in the bag
double getFraction(int index)
{
double fraction; // the fraction is initially 1
if(itemFits(index))
{
fraction = 1;
}
else
{
fraction = weights[index] % bagCapacity;
}
return fraction;
}
// puts fraction of item in bag and updates capacity&weight of bag
void putInBag(int itemToAddIndex, double fraction)
{
profitPerWeight[itemToAddIndex] = 0; // disegard this so it won't be seen as max next time we look for most valuable item
bagCapacity = bagCapacity - fraction * weights[itemToAddIndex];
bagWeight = bagWeight + fraction * weights[itemToAddIndex];
bagContent[itemToAddIndex] = fraction;
}
// function that solves the problem using greedy approach
void knapSack()
{
while(bagWeight<=15)
{
itemToAddIndex = MaxProfitItem(); // select the most profit/weight valuable item
fraction = getFraction(itemToAddIndex); // see which fraction of it fits in the bag
putInBag(itemToAddIndex, fraction); // put the fraction of item which fits in bag
}
for(int i=0; i<7; i++)
{
cout << *(objects+i) << "*" << bagContent[i] << " ";
}
}
int main()
{
knapSack();
}
发布于 2018-04-14 00:05:00
您的函数double getFraction(int index)
有一些缺陷。它不应该将项目的权重与bagCapacity (最大值)进行比较,而应该将权重与当前剩余容量进行比较。即bagCapacity - bagWeight。但我也不确定为什么你要做%(模数),当你应该除以得到分数的时候。此外,您要将两个整型数拆分为双精度型,并且需要为此进行强制转换。尝试将该函数更改为以下内容:
double getFraction(int index)
{
double fraction; // the fraction is initially 1
if(itemFits(index))
{
fraction = 1;
}
else
{
fraction = (double)(bagCapacity - bagWeight) / (double)weights[index];
}
return fraction;
}
编辑:而且,当你想要小数(或者实际上是小数点)时,你的数组只包含整数。将int bagContent[7] = {0,0,0,0,0,0,0};
更改为double bagContent[7] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0};
https://stackoverflow.com/questions/49820760
复制相似问题