Skip to content

Commit 34190e1

Browse files
authored
Update 1.3背包问题.md
1 parent 26ab073 commit 34190e1

File tree

1 file changed

+108
-1
lines changed

1 file changed

+108
-1
lines changed

1.3背包问题.md

+108-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
其中<img src="http://latex.codecogs.com/gif.latex?V(W)" title="V(W)" />表示背包已装物品重量为M时的最大价值,上述比较的两者,前者表示不装第i件物品时,背包已经承载物品的最大价值,后者表示装了第i件物品后,剩余的空间可以装载物品的最大价值与第i件物品价值的和。两者取最大,则可保证最后的方案是最优的。
2424

2525
解题思路图示:
26-
[!image](https://github.com/Anfany/Algorithm-Example-by-Python3/blob/master/0-1pack.png)
26+
![image](https://github.com/Anfany/Algorithm-Example-by-Python3/blob/master/0-1pack.png)
2727

2828
基于Python3的代码
2929
```
@@ -73,7 +73,114 @@ print(ZeroOnePack_Simple(weight, value, maxweight))
7373
* **完全背包**
7474

7575
+ 有N件物品,背包的最大承重为M,**每件物品的数量无限**,价值集合为V,重量集合为W,计算该背包可以承载的物品的最大价值。
76+
77+
这个和0-1背包的最大区别在于:每计算一次V值,就立即更新。其状态转移方程和0-1背包相同,因为有实时的更新V值,就相当于同一个物品可以多次选取。
78+
79+
下面给出基于Python3的代码
80+
```
81+
weight = [4, 3, 2, 6, 5]
82+
value = [3, 4, 6, 7, 9]
83+
maxweight = 8
84+
85+
# 只输出最大价值
86+
def CompletePack_Simple(W, V, MW):#完全背包
87+
#存储最大价值的一维数组
88+
valuelist = [0] * (MW + 1)
89+
#开始计算
90+
for ii in range(len(W)):#从第一个物品
91+
for jj in range(MW + 1):#从重量0
92+
if jj >= W[ii]:#如果重量大于物品重量
93+
valuelist[jj] = max(valuelist[jj - W[ii]] + V[ii], valuelist[jj])#选中第ii个物品和不选中,取大的
94+
return '最大价值:', valuelist[-1]
95+
96+
# 也输出选择物品的编号以及个数
97+
def CompletePack(W, V, MW):#完全背包
98+
#存储最大价值的一维数组
99+
valuelist = [0] * (MW + 1)
100+
#存储物品编号的字典
101+
codedict = {i: [] for i in range(0, MW + 1)}
102+
#开始计算
103+
for ii in range(len(W)):#从第一个物品
104+
copyvalue = valuelist.copy()
105+
copydict = codedict.copy()
106+
for jj in range(MW + 1):#从重量0
107+
if jj >= W[ii]:#如果重量大于物品重量
108+
cc = copyvalue[jj]
109+
copyvalue[jj] = max(copyvalue[jj - W[ii]] + V[ii], copyvalue[jj])#选中第ii个物品和不选中,取大的
110+
#输出被选中的物品编号
111+
if copyvalue[jj] > cc:
112+
copydict[jj] = [ii]
113+
for hh in copydict[jj - W[ii]]:
114+
copydict[jj].append(hh)
115+
codedict = copydict.copy()#更新
116+
valuelist = copyvalue.copy()#更新
117+
result = ''
118+
for hcode in sorted(list(set(copydict[MW]))):
119+
result += '物品:%d :%d个' % (hcode + 1, copydict[MW].count(hcode))
120+
print(result)
121+
return '最大价值:', valuelist[-1]
122+
123+
print(CompletePack_Simple(weight, value, maxweight))
124+
```
76125

77126
* **多重背包**
78127

79128
+ 有N件物品,背包的最大承重为M,**每件物品的数量集合为C**,价值集合为V,重量集合为W,计算该背包可以承载的物品的最大价值。
129+
这个和完全背包的最大区别在于:完全背包因为没有物品数量的限制,因此可以无限叠加。因此需要加上对数量的限制语句。
130+
131+
下面是基于Python3的代码
132+
```
133+
weight = [4, 3, 2, 6, 5]
134+
value = [3, 4, 6, 7, 9]
135+
count = [3, 2, 1, 1, 0]
136+
maxweight = 8
137+
138+
# 只输出最大价值
139+
def MultiplePack_Simple(W, V, C, MW): # 多重背包
140+
# 存储最大价值的一维数组
141+
valuelist = [0] * (MW + 1)
142+
# 开始计算
143+
for ii in range(len(W)): # 从第一个物品
144+
copyvalue = valuelist.copy()
145+
for jj in range(MW + 1): # 从重量0
146+
if jj >= W[ii]: # 如果重量大于物品重量
147+
for gg in range(C[ii] + 1): # 限制=数量
148+
if gg * W[ii] <= jj:
149+
copyvalue[jj] = max(valuelist[jj - gg * W[ii]] + gg * V[ii], copyvalue[jj])
150+
valuelist = copyvalue.copy() # 更新
151+
return '最大价值:', valuelist[-1]
152+
153+
# 也输出编号以及个数
154+
def MultiplePack(W, V, C, MW): # 多重背包
155+
# 存储最大价值的一维数组
156+
valuelist = [0] * (MW + 1)
157+
# 存储物品编号的字典
158+
codedict = {i: [] for i in range(0, MW + 1)}
159+
# 开始计算
160+
for ii in range(len(W)): # 从第一个物品
161+
copyvalue = valuelist.copy()
162+
copydict = codedict.copy()
163+
# 存储物品所用数量的一维数组
164+
number = [0] * (MW + 1)
165+
for jj in range(MW + 1): # 从重量0
166+
if jj >= W[ii]: # 如果重量大于物品重量
167+
for gg in range(C[ii] + 1): # 限制数量
168+
cc = copyvalue[jj]
169+
if gg * W[ii] <= jj:
170+
copyvalue[jj] = max(valuelist[jj - gg * W[ii]] + gg * V[ii], copyvalue[jj])
171+
if copyvalue[jj] > cc:
172+
number[jj] += 1
173+
copydict[jj] = number[jj] * [ii]
174+
for hh in codedict[jj - number[jj] * W[ii]]:
175+
copydict[jj].append(hh)
176+
codedict = copydict.copy() # 更新
177+
valuelist = copyvalue.copy() # 更新
178+
result = ''
179+
for hcode in sorted(list(set(copydict[MW]))):
180+
result += '物品:%d: %d个。' % (hcode + 1, copydict[MW].count(hcode))
181+
print(result)
182+
return '最大价值:', valuelist[-1]
183+
184+
185+
print(MultiplePack_Simple(weight, value, count, maxweight))
186+
```

0 commit comments

Comments
 (0)