0/1背包问题(Python实现)

问题:给定一个载重量为m的背包,以及n个重量为wi、价值为pi的物体,1<=i<=n,要求把物体装入背包,使背包内的物体价值最大,把这类问题称为背包问题。通常称物体不可分割的背包问题为0/1背包问题。
这个问题也可以用动态规划的分阶段决策方法,来确定把哪一个物体装入背包的最优决策。类似于资源分配那样,令optp[i][j]表示在前i个物体中,能够装入载重量为j的背包中的物体的最大价值,j=1,2,…,m。可以得到下面的动态规划函数:
optp[i][0] = optp[0][j] = 0………………………………………..(1)
optp[i][j] = optp[i - 1][j] (j < wi)…………………………………(2)
optp[i][j] = max{optp[i - 1][j], optp[I - 1][j - wi] + pi}(j >= wi)…(3)
式(1)表示,把前面i物体装入载重量为0的背包,或者把0个物体装入载重量为j的背包,得到的价值都为0。(2)式表明,如果第i个物体的重量大于背包的载重量,则装入前面i个物体得到的最大价值,与装入前面i – 1个物体得到的最大价值一样(第i个物体没有装入背包)。式(3)表明,当第i个物体的重量小于背包的载重量时,如果把第i个物体装入载重量为j的背包后总价值上升,那么就装入,否则不装入。

算法实现如下(Python编写,经测试可用):

#!/usr/bin/python
# -*- coding: utf8 -*-
'''
Created on 2017-9-29
 
@author: AHAN
python 2.7.2
'''

#n个物体的重量(w[0]无用)
w = [5,8,13,27,14]
#n个物体的价值(p[0]无用)
p = [5,8,13,27,14]
#计算n的个数
n = len(w)
#背包的载重量
m = 33

dp = [[-1 for j in range(m + 1)] for i in range(n)]

for i in range(n):
    dp[i][0] = 0

for j in range(m + 1):
    if w[0] <= j:
        dp[0][j] = p[0]
    else:
        dp[0][j] = 0


def dp_fun(i, j):
    if dp[i][j] != -1:
        return dp[i][j]
    if j >= w[i]:
        dp[i][j] = max(dp_fun(i-1, j), dp_fun(i-1, j-w[i]) + p[i])
    else:
        dp[i][j] = dp_fun(i-1, j)
    return dp[i][j]

print('最大值为:' + str(dp_fun(n - 1, m)))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容