动态规划法求解0-1背包问题(python实现)

实验内容

给定几组数据,利用动态规划算法的思想,把 0-1 背包装满并使得其价值最 大。

实验原理

动态规划通过拆分问题,将问题拆分成许多的子问题,定义问题状态和状态之间的关系(即状态转移方程或递推公式),使得问题能够以递推(或者说分治) 的方式去解决。按顺序求解子问题,前一子问题的解,为后一子问题的求解提供了有用的信息,在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,那么最后一个子问题就是初始问题的解。

实验步骤

① 把问题分解成若干个子问题,如背包仅可以容纳 1 个物品且可以容纳的质量为一等。
② 依次求出各个子问题的最优解。
③ 每个子问题的最优解又可以从它的子问题的最优解中得到。
④ 通过各个子问题的最优解得到原问题的最优解

代码实现

backpack函数:
weight 表示背包能容纳的商品最大重量,number 表示商品数量,w 数组和 v 数组表示每件商品的重量以及对应的价值。首先初始化二维数组为 0,最后循环将数组中的每个元素进行填充:如果当前背包可容纳的重量小于当前商品的重量,那么背包中的总价值不会变化,否则,可以选择装下当前这件物品或者不装下这件物品,这就可以得到两个价值,那么其中最高的价值就是当前情况下背包能获得的最大价值。
main 函数中最后的两个for循环(用于找到选择的物品):
首先初始化一个 item 数组并全初始化为 0,然后循环遍历动态规划得到的数组,如果 result[i][j] > result[i-1][j],那么说明第 i-1 件物品肯定被选择了,那么 就将 item[i-1]设置为 1,循环结束后将 item 中为 1 的索引输出即可。

import time

def backpack(number, weight, w, v):
    #初始化二维数组,用于记录背包中个数为i,重量为j时能获得的最大价值
    result = [[0 for i in range(weight+1)] for i in range(number+1)]
    #循环将数组进行填充
    for i in range(1, number+1):
        for j in range(1, weight+1):
            if j < w[i-1]:
                result[i][j] = result[i-1][j]
            else:
                result[i][j] = max(result[i-1][j], result[i-1][j-w[i-1]] + v[i-1])
    return result


def main():
    number = 5
    weight = 10
    w = [2, 2, 6, 5, 4]
    v = [6, 3, 5, 4, 6]
    start = time.time()
    result = backpack(number, weight, w, v)
    end = time.time()
    print("共耗时:\n" + str(end - start) + " s")
    print("最优解为:" + str(result[number][weight]) + "\n")
    print("所选取的物品为:")
    item = [0 for i in range(number+1)]
    j = weight
    for i in range(1, number+1):
        if result[i][j] > result[i-1][j]:
            item[i-1] = 1
            j -= w[i-1]
    for i in range(number):
        if item[i] == 1:
            print("第" + str(i+1) + "件")
if __name__ == '__main__':
    main()

时间复杂度分析

时间消耗最大的部分就在 backpack 函数部分,而在该函数中时间消耗最大的部分又在最后的双重 for 循环中,双重 for 循环的时间复杂度即为 O(number * weight),那么整个算法的时间复杂度也是 O(number * weight)

运行结果

共耗时:
0.0 s
最优解为:15

所选取的物品为:
第1件
第2件
第5

猜你喜欢

转载自blog.csdn.net/weixin_44227192/article/details/106931543
今日推荐