0-1背包问题

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

0/1背包问题
一、问题描述
已知一个容量为M的背包和n件物品,物品编号为0~n-1,第i件物品的重量为w i,若将其装入背包将获益p i。

这里w i>0, p i >0(0≤i<n)。

所谓的0/1背包问题,是指在物品只能整件装入或不装入的情况下,求一种使得总效益最大的装载方案。

上述问题可形式化描述为:给定M>0,w i>0, p i>0(0≤i<n),求一个n元向量x=(x0,x1,…,x n-1),x i∈{0,1}(0≤i<n)使得

<≤n
i
0w i x i≤M且∑
<
≤n
i
p i x i最大。

为了叙述方便将该
问题简记为KNAP(0,n-1,M)。

二、递归法求解
1.分析
已知x i∈{0,1},0≤i<n,假定对x i 作决策的次序是x=(x n-1,x n-2,…,x0),在对x n-1作出决策时存在以下两种情况:
(1)x n-1=1,将编号为n-1的物品装入包中,接着求解子问题KNAP(0,n-2,M-w n-1);
(2)x n-1=0,不将编号为n-1的物品装入
包中,接着求解子问题KNAP(0,n-2,M)。

设f(j,X)是当背包容量为X ,可供选择的物品为0,1,…,j 时的最优解(即最大总效益),那么f(n-1,M)可表示为:
f(n-1,M)=max{f(n-2,M),f(n-2,M-w n-1)+p n-1}
对于任意的j ,0≤j <n,有
f(j,X)=max{f(j-1,X),f(j-1,X-w j )+p j } 若将物品j 装入包中,则
f(j,X)= f(j-1,X-w j )+p j
反之
f(j,X)= f(j-1,X)
2.算法
(1)f(-1,X)=⎩⎨⎧≥<∞-)0(0)0(X X ;
(2)f(j,X)= max{f(j-1,X),f(j-1,X-w j )+p j } 其中0≤j <n 。

3.考虑以下背包问题,n=3, (w 0,w 1,w 2)=
(2,3,4),(p 0,p 1,p 2)=(1,2,5)和M=6。

利用上述算法求解过程如下:
f(2,6)=max{f(1,6),f(1,2)+5}
f(1,6)=max{f(0,6),f(0,3)+2}
f(1,2)=max{f(0,2)}
f(0,6)=max{f(-1,6),f(-1,4)+1} f(0,3)=max{f(-1,3),f(-1,1)+1} f(0,2)=max{f(-1,2),f(-1,0)+1} f(-1,6)=0
f(-1,4)=0
f(-1,3)=0
f(-1,0)=0
f(-1,2)=0
f(-1,1)=0
f(0,2)=1
f(0,3)=1
f(0,6)=1
f(1,2)=1
f(1,6)=3
f(2,6)=6
即最优解为:f(2,6)=6
以上问题的递归树为:
4. 递归法的局限性
递归法虽然简单,但其缺点也是不言而喻的。

由以上递归树可知递归法在最坏情况下的时间复杂度为O(2n),也不能求出背包问题的解向量,而且当w i和M为实数时,递归法已不再适用。

三、动态规划法求解
1.实例分析
同样,先考虑以下背包问题,n=3, (w0,w1,w2)= (2,3,4),(p0,p1,p2)=(1,2,5)和M=6。

利用式
f(j,X)=max{f(j-1,X),f(j-1,X-w j )+p j } (0≤j <n)
递推求解过程如下:
f(-1,X)=
⎩⎨⎧≥<∞-000X X f(0,X)=⎪⎩
⎪⎨⎧≥=+<≤=+-∞<∞-21}10,0max{200}1,0max{
0X X X f(1,X)=⎪⎪⎪⎩⎪⎪⎪⎨⎧≥=+<≤=+<≤<≤<∞-53}21,1max{532}20,1max{3
212000X X X X X
f(2,X)=⎪⎪⎪⎪⎩⎪⎪⎪⎪⎨⎧>=+<≤=+<≤=+<≤=<≤<≤<98}53,3max{977}52,3max{766}51,3max{645}5,3,2max{
43232120X X X X X X X
所以f(2,6)=6
上述求解过程容易用如下图示表示:
从上图可见函数f是阶梯形非递减曲线,可以由一组阶跃点来描述。

现作如下标
记:
S j={(P i,W i)|函数曲线f(j,X)的全部阶跃点} (-1≤j≤n-1),并设S-1={(0,0)
S j1={(P i,W i)|函数曲线f(j-1,X-w j)+p j的全部阶跃点}(0≤j≤n-1)
的步骤如下:
则计算所有S j和S j
1
(1)S-1={(0,0)};
={(P+p j,W+w j)|(P,W)∈S j-1,0≤j≤(2)S j
1
n-1};
并舍弃其中被支配的阶跃点(3)S j= S j-1∪S j
1
和所有W>M的阶跃点。

设(P1,W1)和(P2,W2)是两个阶跃点,如果P1>P2且W1<W2,则称(P1,W1)支配(P2,W2),或(P2,W2)被(P1,W1)所支配。

我们再来考虑以下背包问题:n=3, (w0,w1,w2)= (2,3,4),(p0,p1,p2)=(1,2,5)和M=6,试生成其各个序偶集合。

S-1={(0,0)}
S01={(0+p0,0+w0)}={(1,2)}
={(0,0),(1,2)}
S0=S-1∪S0
1
S11={(0+p1,0+w1),(1+p1,2+w1)}={(2,3)
,(3,5)}
S 1=S 0∪S 11={(0,0),(1,2),(2,3),
(3,5)}
S 21={(0+p 2,0+w 2),(1+p 2,2+w 2),(2+p 2,
3+w 2),(3+p 2,5+w 2)}
={(5,4),(6,6),(7,7),(8,9)}
S 2= S 1∪S 21={(0,0),(1,2),(2,3),
(5,4),(6,6)}(阶跃点
(5,4)支配(3,5),所以舍弃(3,5);另外还要舍弃W >M 的阶跃点(7,7)和(8,9))
由阶跃点集S 2可知当W=M=6时,最大收
益P=6。

求完所有序偶对后就可以求解向量了。

我们利用回溯法。

从(P,W)=(P,M)开始,判
断(P,W)是A=S n-2和B=S n n 12--哪一个集合中的阶
跃点。

若(P,W)∈A ,则相应地x n-1=0;若(P,W)∈B ,则令x n-1=1且(P,W)=(P-p n-1,M-w n-1),
A=S (n-2)-1,B=S n n 1)1(1)2(----,重复上述过程直到全部解求完为止。

如对上述例子。

(6,6)∈S 21,故x 2=1;继
续回溯,(6-p 2,6-w 2)=(1,2)∈S 0,故x 1=0;再
回溯,(1,2)∈S 0
1
,故x 0=1。

因此本例的最
优解为(x0,x1,x2)=(1,0,1)。

2.算法
在描述算法前我们先定义程序中用到的几个数据结构:
(1)结构体CDoublePoint作为序偶(P,W)的
载体。

(2)使用由阶跃点序偶(P,W)组成的一维数
组point依次存储集合S0,S1,…,S n-1中的
序偶。

(3)使用一维数组mark[i](0≤i<n)指示集
合S i在数组point中的起始序偶的下标。

如下图所示:
有了以上定义后我们就来描述解决此
问题的算法,具体如下:
(1)按以下规则生成所有序偶对。

I.S-1={(0,0)};
II.S j
={(P+p j,W+w j)|(P,W)∈S j-1,0≤j
1
≤n-1};
III.S j= S j-1∪S j
并舍弃其中被支配的阶
1
跃点和所有W>M的阶跃点。

从S0开始,以递推的方式计算所有的S i(0≤i≤n-1)。

在从S i-1生成S i时,对S i-1中的一个序偶
(point[j].profit,point[j].weight)
需执行以下操作:
i.生成S i
中的一个序偶
1
(pp,ww)=(point[j].profit+p[i],poin
t[j].weight+w[i]);
ii.将S i-1中所有W<ww的序偶都加入S i中,这些序偶都不应删除;
iii.当point[k].weight=ww时,(point[k].profit,point[k].weight)
是S i-1中的序偶,则以point[k].profit 和pp中的较大者作为pp的新值,并考察序偶(pp,ww)是否被已加入S i中的序偶所支配,若是则舍弃之,反之将其加入S i中;
iv.舍弃S i-1中所有在此时已能确定被支配的序偶。

(2)返回最大效益值。

(3)回溯法求解向量,算法如前所述。

3.编程实现。

相关文档
最新文档