根据维基百科和我去通过其他来源,则需要矩阵m[n][W]
; n
-物品和数量W
背包的总容量- 。 这个矩阵得到真正的大,有时太大,处理它的C程序。 我知道,动态编程基于节省时间的记忆,但仍然是有你在那里可以节省时间和内存中的任何解决方案?
对于伪代码背包问题:
// 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]);