背包使用动态规划

Knapsack using dynamic programming

有一种使用动态规划求解背包问题的通用算法。但是对于W=750000000是不行的,因为有bad 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];
    }

你没有显示 n,但即使我们假设它是 1,让我们看看你试图分配多少数据。所以,它将是:

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

结果是:

750000000*64*2 bits = ~11.1758Gb

我猜这比 space 您的程序允许的要多。你将需要采取一种新的方法。也许尝试将问题作为多个块来处理。上半场和下半场分开考虑,然后交换。

首先,你可以只用一维来解决背包问题。这会将您的内存从 dp[W][n] (n*W space) 减少到 dp[W] (W space)。你可以看这里:0/1 Knapsack Dynamic Programming Optimazion, from 2D matrix to 1D matrix

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

例如:

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

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

一样
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]。