背包问题追踪解

102 篇文章 0 订阅
70 篇文章 0 订阅

混合背包问题通用处理如下,我们以通用状态方式处理解空间的追踪:

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("Choose 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
Choose value 14 : cost 5: how many 1
Choose value 6 : cost 7: how many 0
Choose value 11 : cost 6: how many 2
Choose value 5 : cost 13: how many 0
Choose value 7 : cost 9: how many 0
Choose value 5 : cost 3: how many 1
Choose value 2 : cost 2: how many 0
Choose value 1 : cost 11: how many 0

选与不选,就是01问题的追踪:

import numpy as np
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]:
                list[v] = list[v-C[i-1]] + W[i-1]
                track_solution[i,v] = 1
#            else:
#                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("Choose 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
            else:
                track_solution[i,v] = track_solution[i-1,v]
                
    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("Choose value {} : cost {}: how many {}".format(W[i-1],C[i-1],m))
        
        while  G[i,v] == -1:# 在i的方向上搜索
            i -=1

#%%
N = 8
V = 30
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
[[ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
   0  0  0  0  0  0  0]
 [ 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  1  1  1  1  1  1  1  1  1  1  1  1  1
   1  1  1  1  1  1  1]
 [ 0 -1  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2
   2  2  2  2  2  2  2]
 [ 0 -1 -1  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3
   3  3  3  3  3  3  3]
 [ 0 -1 -1 -1 -1 -1 -1 -1 -1  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3
   3  3  3  3  3  3  3]
 [ 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  3  3  3  3  3  3  3  3  3  3  3
   3  3  3  3  3  3  3]
 [ 0 -1 -1 -1 -1 -1  6  6  6  6  6  6  6  6  6  6  6  6  6  6  6  6  6  6
   6  6  6  6  6  6  6]
 [ 0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  6  6  6  6  6  6  6  6  6
   6  6  6  6  6  6  6]
 [ 0 -1 -1 -1 -1 -1 -1  8  8  8  8  8 -1  8  8  8  8  8  8  8  8  8  8  8
   8  8  8  8  8  8  8]]
8
Choose value 14 : cost 7: how many 4
2
Choose value 2 : cost 2: how many 1

标记函数首先是得到标记列表,又叫映射表,追踪解的过程实际就是一个双指针模型的搜索,在这里对应的就是i,v怎么收缩,编码过程,先把表画出来,确定双针移动的方式,最后确定边界条件,也就是循环的条件。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值