背包算法检测对象

时间:2013-01-31 08:31:21

标签: c++ algorithm knapsack-problem

这个问题有一个简单的dp解决方案:

#include <vector>
#include <limits>

int knapsack2(const std::vector<int>& wts, const std::vector<int>& cost, int W)
{
    size_t n = wts.size();
    std::vector<std::vector<int> > dp(W + 1, std::vector<int>(n+1, 0));
    for (size_t j = 1; j <= n; j++) {
        for (int w = 1; w <= W; w++) {
           if (wts[j-1] <= w) {
               dp[w][j] = std::max(dp[w][j - 1], dp[w - wts[j-1]][j - 1] + cost[j-1]);
           }
           else {
                dp[w][j] = dp[w][j - 1];
           }
        }
    }
    return dp[W][n];
}

但我怎么知道拍摄了什么物品?

3 个答案:

答案 0 :(得分:0)

您的方法的主要问题是缺乏将项目概念编码为实体。您应该创建一个类型“item”(使用classstruct关键字)来描述具有权重,成本和某种标识符(名称或编号)作为成员的项目。这样你只需要发送一个项目向量,任何解决方案都将是这些项目的列表,它可以回答你的问题。

修改

根据请求,下面是一个更实际的解释,说明如何天真地实现这一点。

创建一个类型item,其中包含单个项目的所有信息。以std::vector<item>作为输入来替换wtscost然后,可能的最小更改是更改dp,以便存储由运行成本和项目组成的对名单。这会给它类型std::vector<std::vector<std::pair<int,std::vector<item>>>>。也就是说,对于每个存储的(部分)解决方案,请跟踪其成本和提供此解决方案的项目。

dp的这种类型看起来很可怕,但是如果你让它工作,你可以稍后改进实现。例如,您可以存储指向item的指针,以避免复制。此外,一些typedef确实可以帮助澄清dp的定义。重要的是首先让它使用最简单的解决方案,然后考虑这些改进。

答案 1 :(得分:0)

您可以使用地图,一旦制作了对象,您就可以使用地图进行查询。将使用HashMap实现优化算法。

答案 2 :(得分:0)

使第二个矢量“prev”与dp具有相同的尺寸。

当你选择dp [w] [j]的最佳选项时,将前一个单元格的坐标写入prev [w] [j]

完成dp的工作后,从prev [W] [n]步行返回以获取所有使用过的单元格索引