使用动态编程的背包

时间:2017-11-28 22:22:49

标签: c++ algorithm knapsack-problem

使用动态编程解决背包问题的常用算法。但它对W = 750000000无效,因为存在错误的alloc错误。任何想法如何为我的W值解决这个问题?

int n=this->items.size();
std::vector<std::vector<uint64_t>> dps(this->W + 1, std::vector<uint64_t>(n + 1, 0));
for (int j = 1; j <= n; j++)
    for (int k = 1; k <= this->W; k++) {
        if (this->items[j - 1]->wts <= k)
            dps[k][j] = std::max(dps[k][j - 1], dps[k - this->items[j - 1]->wts][j - 1] + this->items[j - 1]->cost);
        else
            dps[k][j] = dps[k][j - 1];
    }

2 个答案:

答案 0 :(得分:1)

首先,您只能使用一个维来解决背包问题。这将减少你从dp [W] [n](n * W空间)到dp [W](W空间)的记忆。你可以在这里查看:0/1 Knapsack Dynamic Programming Optimazion, from 2D matrix to 1D matrix

但是,即使你只使用dp [W],你的W真的很高,而且可能记忆太多了。如果您的物品很大,您可以使用一些方法来减少可能的重量。首先,要意识到你不需要W的所有位置,只需要权重[i]之和存在。

例如:

W = 500
weights = [100, 200, 400]

您永远不会使用矩阵的位置dp [473],因为这些项目只能占据p = [0, 100, 200, 300, 400, 500]个位置。很容易看出这个问题与以下时间相同:

W = 5
weights = [1,2,4]

另一个更复杂的例子:

W = 20
weights = [5, 7, 8]

使用与以前相同的方法,您不需要从0到20的所有权重,因为项目只占用位置

p = [0, 5, 7, 5 + 7, 5 + 8, 7 + 8, 5 + 7 + 8]
p = [0, 5, 7, 12, 13, 15, 20]

,你可以将矩阵从dp [20]减少到dp [p的大小] = M [7]。

答案 1 :(得分:0)

您没有显示n,但即使我们假设它是1,也可以查看您尝试分配的数据量。所以,它将是:

W*64*2 // Here we don't consider overhead of the vector

这就是:

750000000*64*2 bits = ~11.1758Gb

我猜这是你的程序允许的更多空间。您将需要采取新的方法。也许尝试将问题作为多个块来处理。考虑第一和第二半seperatley,然后交换。