背包问题追踪解
混合背包问题通⽤处理如下,我们以通⽤状态⽅式处理解空间的追踪:
def pack_01_and_complete_and_multiple_Bottom_up(N,V,C,W,M):
list= np.zeros((N+1,V+1),dtype=int)
for i in range(1,N+1):
for j in range(0,V+1):
t =min(j // C[i-1],M[i-1])
result =-1000
for k in range(t+1):
A =list[i-1,j-k*C[i-1]]+ k*W[i-1]
if A > result:
result = A
list[i,j]= result
return list[N,V]
我们⽤G[i][v]来追踪解,这⾥⾯记录的是在i,v状态下取了多少件i物品
def pack_01_and_complete_and_multiple_Bottom_up(N,V,C,W,M):
list= np.zeros((N+1,V+1),dtype=int)
G = np.zeros((N+1,V+1),dtype=int)
for i in range(1,N+1):
for j in range(0,V+1):
t =min(j // C[i-1],M[i-1])
result =-1000
for k in range(t+1):
A =list[i-1,j-k*C[i-1]]+ k*W[i-1]
if A > result:
result = A
G[i,j]= k
list[i,j]= result
return list[N,V],G
然后逆向搜索解空间得到PATH
def decode_G(G,N,V,W,C):
i = N
v = V
while i >0:
print("Choo value {} : cost {}: how many {}".format(W[i-1],C[i-1],G[i,v]))
v -= G[i,v]*C[i-1]
i -=1
运⾏结果:
python
N =8
V =20
C =[11,2,3,9,13,6,7,5]
W =[1,2,5,7,5,11,6,14]
M =[10,2,9,1,19,3,4,1]
value,path = pack_01_and_complete_and_multiple_Bottom_up(N,V,C,W,M) print value
decode_G(path,N,V,W,C)
41
Choo value 14: cost 5: how many 1
Choo value 6: cost 7: how many 0
Choo value 11: cost 6: how many 2
Choo value 5: cost 13: how many 0
Choo value 7: cost 9: how many 0
Choo value 5: cost 3: how many 1
Choo value 2: cost 2: how many 0
Choo value 1: cost 11: how many 0
选与不选,就是01问题的追踪:
import numpy as np按时间顺序写的作文
belong
def pack_01_track_solution_Bottom_up(N,V,C,W):
track_solution = np.zeros((N+1,V+1),dtype =int)
list=[0]*(V+1)
for i in range(1,N+1):
for v in range(V,C[i-1]-1,-1):
if list[v]<list[v-C[i-1]]+ W[i-1]:wooyun org
list[v]=list[v-C[i-1]]+ W[i-1]
韩国网络游戏track_solution[i,v]=1
# el:
# track_solution[i,v] = 0
return list[V],track_solution
def track_solution(G,N,V,W,C):
i = N
v = V
while i >0:
print("Choo value {} : cost {}: how many {}".format(W[i-1],C[i-1],G[i,v])) v -= G[i,v]*C[i-1]
i -=1
⽆限数量,完全背包问题,标记函数:
def pack_complete_track_solution_Bottom_up(N,V,C,W):
track_solution = np.zeros((N+1,V+1),dtype =int)
track_solution[1:,1:]=-1
list=[0]*(V+1)
for i in range(1,N+1):
for v in range(C[i-1],V+1):
if list[v]<=list[v-C[i-1]]+ W[i-1]:
list[v]=list[v-C[i-1]]+ W[i-1]
track_solution[i,v]= i
el:
track_solution[i,v]= track_solution[i-1,v]迈克尔杰克逊you are not alone
return list[V],track_solution
def track_solution_standard(G,N,V,W,C):
i = N
v = V
while G[i,v]!=0:
i = G[i,v]
m =0
while G[i,v]== i:# 在v的⽅向上搜索
m +=1
v -=C[i-1]
print("Choo value {} : cost {}: how many {}".format(W[i-1],C[i-1],m))
while G[i,v]==-1:# 在i的⽅向上搜索
i -=1
#%%
N =8
V =302013年研究生国家线
C =[11,2,3,9,13,6,15,7,19]
W =[1,2,5,7,5,11,6,14]
value,path = pack_complete_track_solution_Bottom_up(N,V,C,W)
print value
print path
track_solution_standard(path,N,V,W,C)
58
[[000000000000000000000000
我自己的英文
0000000]
killer什么意思[0-1-1-1-1-1-1-1-1-1-11111111111111
1111111]
[0-12222222222222222222222
2222222]
[0-1-1333333333333333333333
3333333]
[0-1-1-1-1-1-1-1-1333333333333333
3333333]
erg[0-1-1-1-1-1-1-1-1-1-1-1-133333333333
3333333]
[0-1-1-1-1-1666666666666666666
6666666]
[0-1-1-1-1-1-1-1-1-1-1-1-1-1-1666666666
6666666]济南培训
[0-1-1-1-1-1-188888-188888888888
8888888]]
8
Choo value 14: cost 7: how many 4
2
Choo value 2: cost 2: how many 1
标记函数⾸先是得到标记列表,⼜叫映射表,追踪解的过程实际就是⼀个双指针模型的搜索,在这⾥对应的就是i,v怎么收缩,编码过程,先把表画出来,确定双针移动的⽅式,最后
确定边界条件,也就是循环的条件。