gpt4 book ai didi

c - 背包——节省时间和内存力

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:13:57 31 4
gpt4 key购买 nike

根据维基百科和我浏览过的其他资源,您需要矩阵m[n][W]n - 元素数量和 W - 背包的总容量。这个矩阵变得非常大,有时大到无法在 C 程序中处理。我知道动态规划的基础是节省内存时间,但是,有什么解决方案可以节省时间和内存吗?

Knapsack problem: 的伪代码

// Input:
// Values (stored in array v)
// Weights (stored in array w)
// Number of distinct items (n)
// Knapsack capacity (W)
for j from 0 to W do
m[0, j] := 0
end for
for i from 1 to n do
for j from 0 to W do
if w[i] <= j then
m[i, j] := max(m[i-1, j], m[i-1, j-w[i]] + v[i])
else
m[i, j] := m[i-1, j]
end if
end for
end for

比方说,W = 123456789 和 n = 100。在这种情况下,我们得到非常大的矩阵 m[100][123456789]。我在考虑如何实现这一点,但我脑子里最好的办法就是用一位 (0/1) 保存选择了哪些项目。这可能吗?或者有没有其他方法可以解决这个问题?

int32 -> 32 * 123456789 * 100 bits
one_bit -> 1 * 123456789 * 100 bits

我希望这不是一个愚蠢的问题,感谢您的努力。

编辑 - 工作 C 代码:

    long int i, j;
long int *m[2];
m[0] = (long int *) malloc(sizeof(long int)*(W+1));
m[1] = (long int *) malloc(sizeof(long int)*(W+1));
for(i = 0; i <= W; i++){
m[0][i] = 0;
}

int read = 0;
int write = 1;
int tmp;

long int percent = (W+1)*(n)/100;
long int counter = 0;

for(i = 1; i <= n; i++){
for(j = 0; j <= W; j++){
if(w[i-1] <= j){
m[write][j] = max(m[read][j],(v[i-1]) + m[read][j-(w[i-1])]);
}else{
m[write][j] = m[read][j];
}
counter++;
if(counter == percent){
printf("."); //printing dot (.) for each percent
fflush(stdout);
counter = 0;
}
}
tmp = read;
read = write;
write = tmp;
}

printf("\n%ld\n", m[read][W]);

free(m[0]);
free(m[1]);

最佳答案

背包问题可以用O(W)空间来解决。
在迭代的每个步骤中,您只需要 2 行 - 数组 m[i]m[i + 1] 的当前状态。

current = 1
int m[2][W]
set NONE for all elements of m # that means we are not able to process this state
m[0][0] = 0 # this is our start point, initially empty knapsack

FOR i in [1..n] do
next = 3 - current; /// just use 1 or 2 based on the current index
for j in [0...W] do
m[next][j] = m[current][j]
FOR j in [w[i]..W] do
if m[current][j - w[i]] is not NONE then # process only reachable positions
m[next][j] = max(m[next][j], m[current][j - w[i]] + v[i]);
current = next; /// swap current state and the produced one


也可以只使用 1 个数组。这是伪代码

FOR i in [1..n] do
FOR j in [w[i]..W] do
m[j] = max(m[j], m[j - w[i]] + v[i]);

关于c - 背包——节省时间和内存力,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23777255/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com