前言
本科期间学习的算法都忘得差不多了,可是随着眼界的开阔,渐渐意识到数学和算法的重要性,因此早就有总结的打算。最近学习Python语言,学校也开设了《算法分析与设计》这门课,所以开始总结一下基本的算法思想并尽量用Python来实现。
问题描述
有N件物品和一个容量为V的背包。第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使价值总和最大。
基本思想
考虑使用dp问题求解,定义一个递归式 opt[i][j] 表示前i个物品,在背包容量大小为j的情况下可装入的最大价值。现定义状态转换方程:opt[i][j] = max(opt[i-1][j] , opt[i-1][j-w[i]] + v[i]),其中opt[i-1][j] 表示第i件物品不装入背包中的价值总和,而opt[i-1][j-w[i]] + v[i] 表示第i件物品装入背包中的价值总和。
代码实现
import numpy as np #引入numpy包
weight = np.array([2,2,6,5,4]) #定义每个物体的重量
value = np.array([6,3,5,4,6]) #定义每个物体的价值
max_weight = 10 #定义背包的最大容量
num = len(weight) #求物体的个数
marray = np.zeros(num*(max_weight+1)).reshape(num,-1) #构造二维数组存放opt(i,j)
j = min(weight[0], max_weight) # 初始化只有第一个物体可供选择时opt(i,j)的值,即初始化opt(1,j)的值,这里下标从0开始
while j <= max_weight:
marray[0][j] = value[0]
j = j + 1
i = 1
while i < num: # 从第二个物体遍历到最后一个物体,直到计算opt(n,V)的值
for j in range(max_weight+1):
if j < weight[i] :
marray[i][j] = marray[i-1][j]
if j >= weight[i]:
marray[i][j] = max(marray[i-1][j], marray[i-1][j-weight[i]] + value[i])
i = i + 1
# 输出marray数组,其中marray[num-1][max_weight]即为所求答案
for i in range(num):
for j in range(max_weight+1):
print marray[i][j],
print ''
本科的时候一直觉得0-1背包问题很难,现在总结一下觉得还挺简单的,看来复习与总结很重要。这是新的开始,希望自己可以坚持!