我有一个问题,我有一个具有以下结构的元素数组:
struct Band
{
int index;
int length;
int cost;
};
现在,我需要选择单个元素或元素组合,其中每个元素都具有唯一索引,即没有元素可以具有相同的索引。这些元素组合的长度总和应该等于 N ,如果有多个这样的组合,那么我需要选择成本最低的组合。
有什么想法吗?我目前的解决方案不起作用,所以我不确定我是否应该在这里分享。谢谢!
编辑:这就是我现在所拥有的。 selected是所选元素的索引集,startI是起始索引,ranageMax是结束索引(全局)。 L是所需的长度,M是我们拥有的最大金额,因此成本必须低于它。void knapsack(struct Band rubber[], int currLen, int cost, int startI, set<int> selected)
{
if(startI == rangeMax)
{
/*&root[startI].length = currLen;
root[startI].cost = cost;*/
cout << "\n";
return;
}
if(cost > M || currLen > L)
{
cout<< "\n";
return;
}
if(currLen == L)
{
//cout << "Candidate : " << cost << endl;
cout << "\n";
if(cost < minv)
minv = cost;
return;
}
for(int i=startI; i<rangeMax; ++i)
{
//knapsack(rubber, currLen, cost, startI+1, selected);
if(selected.find(rubber[i].index) == selected.end())
{
selected.insert(rubber[i].index);
cout << rubber[i].length << " ";
int tempCurrLen = currLen + rubber[i].length;
int tempCost = cost + rubber[i].cost;
/*root[i].length = currLen;
root[i].cost = cost;*/
knapsack(rubber, tempCurrLen, tempCost, i+1, selected);
selected.erase(rubber[i].index);
}
}
}
答案 0 :(得分:2)
在关于knapsack problem的维基百科文章中,有一个动态编程算法的描述,该算法将权重组合在一起,以便最大化利润。要解决原始问题中描述的问题,必须组合长度以优化成本。我们使用如下的二维状态空间。
C[i,j] is defined as the minimum cost attainable for a selection of items
with indices in {1,...,i} of total length exactly j
or positive infinity if there is no such selection
基于该定义,我们获得以下递归关系。
C[i,j] = min{ C[i-1,j-weight[i]] + cost[i], C[i-1,j] }
这种递归关系是正确的,因为推理最小值中的第一项对应于选择索引为i
的项目到解决方案中,而第二项对应于选择索引为i
不进入解决方案。除了对应于单个项目的选择的状态之外,状态空间必须用正无穷大值初始化。然后可以通过增加i
外部循环并迭代
{0,....,N}
在内循环中。评估后,可以在C[n,N]
中找到最低费用。如果需要选择所需的项目,则必须使用回溯或辅助数据结构来生成它。
请注意,在上面的演示文稿中,如果任何参数为正无穷大,我们假设添加值为正无穷大。