动态规划问题

本文通过一个户外旅行的背包问题,介绍了如何使用动态规划来解决物品选取以达到最大价值的问题。对比了简单算法的时间复杂度,并详细解释了动态规划方法的步骤和填充规则,最终找到在背包承重限制下价值最高的物品组合。

本文参考书籍《图解算法》

举例说明动态规划问题
考虑一个场景:周末准备一场户外旅行,要准备一些物品,你有一个可承载8kg背包和一些物品,物品也有重量和需求值,全部物品重量超过背包承重,因此无法全部携带,如何去选取价值总量最高的物品组合呢?

物品名重量价值
water1kg10
food2kg8
tent3kg9
camera1kg6
book1kg3
jacket2kg5

一、最简单的算法如下:尝试各种可能的商品组合,并找出价值最高的组合。6件商品共有64种集合方式,时间为O(2^n),也就是随着待选物品的增多,需要计算的组合呈幂次方 增加。
代码如下

import numpy
from itertools import combinations

bag = 5  # 购物袋能承受的最大承载值

#定义重量
weight={}
weight["water"]=1
weight["book"]=1
weight["food"]=2
weight["jacket"]=2
weight["camera"]=1
weight["tent"]=3

#定义价值
worth={}
worth["water"]=10
worth["book"]=3
worth["food"]=8
worth["jacket"]=5
worth["camera"]=6
worth["tent"]=9


goods_list = ["water", "book", "food", "jacket", "camera", "tent"]       # 物品列表

com_lists = list()
for i in range(1, len(goods_list)+1):
    com_lists += list(combinations(goods_list, i))                       # 获得所有物品的所有排列组合,非重复

best_worth = 0                                                           # 存最佳值
for one_list in com_lists:                                                
    one_weight = 0
    one_worth = 0
    for goods in one_list:
        one_weight += weight[goods]
        one_worth += worth[goods]

    if one_weight <= 5:                                                  # 当总重量小于5时,并且比best_worth值大时,取最佳值,直到遍历所有组合
        if one_worth > best_worth:
            best_worth = one_worth
            best_com = one_list

print(best_com,best_worth)

计算结果为(‘water’, ‘book’, ‘food’, ‘camera’) 27

二、下面试一下动态规划的方法

动态规划先将背包的承载量划分为小块,第一行的记录为细分的小背包能承受的重量,竖排为物品,然后空格中填写每个小背包中能放下的物品的最大价值。当然,你只能填写本行物品和之前行的物品。
每个动态规划算法都从一个网格开始,背包问题的网格如下。

物品名/重量1kg2kg3kg4kg5kg
water
food
tent
camera
book
jacket

网格最初是空的。你将填充其中的每个单元格,网格填满后,就找到了问题的答案!

water行

物品名/重量1kg2kg3kg4kg5kg
water1010101010
food
tent
camera
book
jacket

注意填入规则:在1-6kg的背包中,选择当前行或者之前行的物品,使在承载范围内的物品价值最大。
填入的原则为:
table[i][j]= max(table[i-1][j],当前商品的价值+剩余空间价值(table[i-1][j-当前商品重量]))

物品名/重量1kg2kg3kg4kg5kg
water1010101010
food1010181818
tent1010181919
camera1016181925
book1016192427
jacket1016192427

如图所示,表格的右下方数值就是5kg背包所能承载物品的最大价值,物品组合为:water,food,camera,book。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值