双背包问题(最优解+路径)

该文章描述了一个使用动态规划解决的货物运输问题,通过两个轮船运输不同容量的货物,目标是最大化总利润。文章提供了输入输出示例,并展示了一种计算方法,包括初始化二维矩阵,更新状态并追踪最优路径,最后输出最大利润和选择的货物路径。
摘要由CSDN通过智能技术生成

题目描述


某公司有一批货物,系了2个轮船进行运输。每条轮船上可以运输不同容量的货物。由于2个轮船的发船时间不一样,同一个货物通过不同的轮船运输到终点后,利润也是不一样的,现在需要根据不同轮船的容量、货物的容量以及在不同轮船上进行运输的利润有效地分配货物,从而达到货物价值最大化。每个货物只有1件。
输入:第一行输入为A B M,A代表轮船A的容量,B代表轮船B的容量,M代表货物的个数。之后M行分别代表每个货物的容量、使用轮船A运输的利润、使用轮船B运输的利润。
输出:最大利润。
例子:
输入:
5 6 4
4 3 2
3 1 4
2 2 4
2 3 3
输出:11
解释:轮船A运输货物1或者4,利润3;轮船B运输货物2和3,利润8;所以最大的利润是11。

# -*- coding:utf-8 -*-

A, B, M = 5, 6, 4

matrix = [[0, 0, 0], [3, 10, 2], [3, 1, 4], [3, 2, 3], [2, 3, 3]]
# matrix = [[0, 0, 0], [4, 3, 2], [3, 1, 4], [2, 2, 4], [2, 3, 3]]

dp = [[[0] * (M+1) for _ in range(B + 1)] for _ in range(A + 1)]

# dp[i][j][k]表示在A船容量为i,B船容量为j,可选货物下标在0到k之间时的最大价值

path = [[[0] * (M+1) for _ in range(B + 1)] for _ in range(A + 1)]

# 初始化
for k in range(1, M + 1):
    for i in range(1, A + 1):
        dp[i][0][k] = dp[i][0][k-1]
        weight, value = matrix[k][0], matrix[k][1]
        if weight <= i:
            if dp[i][0][k-1] <= dp[i-weight][0][k-1] + value:
                dp[i][0][k] = dp[i-weight][0][k-1] + value
                path[i][0][k] = 1

for k in range(1, M + 1):
    for j in range(1, B + 1):
        dp[0][j][k] = dp[0][j][k-1]
        weight, value = matrix[k][0], matrix[k][1]
        if weight <= j:
            if dp[0][j][k-1] <= dp[0][j-weight][k-1] + value:
                dp[0][j][k] = dp[0][j-weight][k-1] + value
                path[0][j][k] = 2

for i in range(1, A + 1):
    for j in range(1, B + 1):
        for k in range(1, M + 1):
            # print('>> ', i, ' ', j, ' ', k)
            weight, value_A, value_B = matrix[k]
            if i >= weight and j >= weight:
                # dp[i][j][k] = max(dp[i][j][k-1],
                #                   dp[i - weight][j][k - 1] + value_A,
                #                   dp[i][j - weight][k - 1] + value_B)
                tmp_A = dp[i - weight][j][k - 1] + value_A
                tmp_B = dp[i][j - weight][k - 1] + value_B
                tmp = [(0, dp[i][j][k - 1]), (1, tmp_A), (2, tmp_B)]
                tmp = sorted(tmp, key=lambda x: x[1], reverse=True)
                if tmp[0][0]==1:
                    path[i][j][k] = 1
                elif tmp[0][0]==2:
                    path[i][j][k] = 2
                dp[i][j][k] = tmp[0][1]
            elif i >= weight:
                # dp[i][j][k] = max(dp[i][j][k - 1],
                #                   dp[i - weight][j][k - 1] + value_A)
                tmp_A = dp[i - weight][j][k - 1] + value_A
                tmp = [(0, dp[i][j][k - 1]), (1, tmp_A)]
                tmp = sorted(tmp, key=lambda x: x[1], reverse=True)
                if tmp[0][0] == 1:
                    path[i][j][k] = 1
                dp[i][j][k] = tmp[0][1]
            elif j >= weight:
                # dp[i][j][k] = max(dp[i][j][k - 1],
                #                   dp[i][j - weight][k - 1] + value_B)
                tmp_B = dp[i][j - weight][k - 1] + value_B
                tmp = [(0, dp[i][j][k - 1]), (2, tmp_B)]
                tmp = sorted(tmp, key=lambda x: x[1], reverse=True)
                if tmp[0][0] == 2:
                    path[i][j][k] = 2
                dp[i][j][k] = tmp[0][1]
            else:
                dp[i][j][k] = dp[i][j][k - 1]
print(dp[A][B][M])
print(dp)

print(path)

res_a = []
res_b = []

i=A
j=B
m=M

while m>0 and ((i>=0 or j>0) or (i>0 or j>=0)):
    if path[i][j][m] ==1:
        res_a.append(m)
        i = i-matrix[m][0]
    elif path[i][j][m] ==2:
        res_b.append(m)
        j = j-matrix[m][0]
    m=m-1

print(res_a)
print(res_b)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值