0-1背包问题
作者:互联网
title: 0-1背包问题
date: 2022-05-11 11:02:33
tags: 算法
0-1背包问题
蛮力枚举法
依次列出所有可能情况
n表示有n个商品, C表示容量
其中颜色相同的是需要重复计算的
带备忘的递归
为了解决这个问题->需要大量计算重复的过程,这个时候我们可以引进一个“备忘录”,如果遇到需要重复计算的式子的话,我们可以直接重备忘录中获取。
伪代码的实现:
KnapsackMR(i, c)
输入:商品集合{1,...,i},背包容量c
输出:最大总价格P[i, c]
if(c < 0) then 容量为零 返回负无穷
return 负无穷
end
if i ≤ 0 then 如果商品的个数小于零的话,返回零
return 0
end
if P[i, c] ≠ NULL then 如果备忘录中有这个的话就不用计算 直接返回即可
return P[i, c]
end
P1 = KnapsackMR(i-1, c-vi)
P2 = KnapasckMR(i-1, c)
p[i, c] <= max{P1 + pi, P2}
return P[i, c]
计算顺序:
为了能够不递推,直接求解P[i,c],这就需要我们事先把备忘录表,全部填写上去
p[i,c]确定的方法需要让p[i-1, c]和p[i-1,c-vi]+pi 相比较,选取其中较大的哪一个
代码实现
# 背包问题
# 第一个参数为商品数量
# 第二个参数为背包容量
# 第三个参数为价格表容量表
def memo_rec_matrix(num_commodity, size_knapsack, Price):
# 创建备忘录格式
memo = [ [ [] for i in range(size_knapsack+1)] for m in range(num_commodity+1)]
# 创建追踪表格 0 表示不选择该商品,1表示选择该商品
rec = [ [ [] for i in range(size_knapsack+1)] for m in range(num_commodity+1)]
# 初始化备忘录 和 追踪表格
for m in range(size_knapsack+1):
memo[0][m] = 0
rec[0][m] = 0
for m in range(num_commodity+1):
memo[m][0] = 0
rec[m][0] = 0
# 当我们商品数量为1 - num_commodity 的时候各种情况
for i in range(1, num_commodity+1):
# 当背包容量为1-size_knapsck的时候的各种情况
for m in range(1, size_knapsack+1):
# 如果背包容量小于第i个商品的体积的话,
# 就让memo数组对应的 商品数量i行 和 背包容量m列的位置 等于上一行的这一列的容量,
# 因为上一行这一列的容量是 这个容量是没有i个商品的容量最大值, 并且设置rec[i][m]这个位置为零
if m < Price[0][i-1]:
memo[i][m] = memo[i-1][m]
rec[i][m] = 0
# 如果背包容量大于第i个商品的体积的话,需要进行判断
else:
# 如果加上第i个商品之后的价值 小于没有加上该商品的价值的话,
# 那么就把该位置设置成没有加上第i个商品的时候价值
# 把rec该位置的坐标赋值为0 因为没有选择了该商品
if memo[i-1][m] > memo[i-1][m-Price[0][i-1]]+Price[1][i-1]:
memo[i][m] = memo[i-1][m]
rec[i][m] = 0
# 如果大于的话直接赋值就行
# 把rec该位置的坐标赋值为1 因为选择了该商品
else:
memo[i][m] = memo[i-1][m-Price[0][i-1]]+Price[1][i-1]
rec[i][m] = 1
return memo, rec
# 追踪数组
def track(rec, price):
rec_num_line = len(rec)-1
rec_num_column = len(rec[0])-1
while(True):
# 循环条件 商品数量为0
if rec_num_line == 0:
break
elif rec[rec_num_line][rec_num_column] == 0:
rec_num_line -= 1
else:
print(rec_num_line)
rec_num_line -= 1
rec_num_column -= price[0][rec_num_line]
price = [
[10,3,4,5,4], # 体积
[24,2,9,10,9] # 价格
]
# 商品数量
num_commodity = 5
# 背包容量
size_knapsack = 13
memo, rec = memo_rec_matrix(num_commodity,size_knapsack,price)
标签:背包,容量,memo,问题,num,rec,size 来源: https://www.cnblogs.com/zjhnuil/p/16258304.html