前言
本科期間學習的演算法都忘得差不多了,可是隨著眼界的開闊,漸漸意識到數學和演算法的重要性,因此早就有總結的打算。最近學習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揹包問題很難,現在總結一下覺得還挺簡單的,看來複習與總結很重要。這是新的開始,希望自己可以堅持!
動態規劃之01揹包問題
首先是問題描述 給定n種物品和一揹包,物品i的重量是wi,其價值是pi,揹包的容量是m,問如何選擇裝入揹包中的物品總價值最大?可以這樣理解 揹包的揹負有上限,因此在這個上限內盡可能多的裝東西,並且價值越多越好。在這裡我之想討論動態規劃解決這個問題的詳細過程。動態規劃是用空間換時間的一種方法的抽象。其...
動態規劃之0 1揹包問題
問題描述 現有n件物品和乙個容量為c的揹包。第i件物品的重量是重量為w i 價值是v i 已知對於一件物品必須選擇取 用1表示 或者不取 用0表示 且每件物品只能被取一次 這就是 0 1 的含義 求放置哪些物品進揹包,可使這些物品的重量總和不超過揹包容量,且價值總和最大。求解思路 0 1揹包問題的遞...
動態規劃之0 1揹包問題
問題描述 0 1揹包問題是應用動態規劃設計求解的典型例題 已知n種物品和乙個可容納c重量的揹包,物品i的重量為w i 產生的效益為p i 在裝包時物品i可以裝入,也可以不裝,但不可拆開裝。問如何裝包,所得裝包總效益最大。演算法分析 最優子結構特性 0 1揹包的最優解具有最優子結構特性。與一般揹包問題...