用于找到用于实现给定总和的子集组合的算法,同时保持最小成本

时间:2016-10-21 15:36:46

标签: algorithm dynamic-programming knapsack-problem subset-sum

我有一个问题,我有一个具有以下结构的元素数组:

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);
        }
    }
}

1 个答案:

答案 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]中找到最低费用。如果需要选择所需的项目,则必须使用回溯或辅助数据结构来生成它。

请注意,在上面的演示文稿中,如果任何参数为正无穷大,我们假设添加值为正无穷大。