当前位置: 首页 > news >正文

python 实现knapsack背包问题算法

knapsack背包问题算法介绍

Knapsack背包问题是一种常见的动态规划问题,旨在求解在给定的重量限制下,如何选择一组物品使得它们的总价值最大化。背包问题有多种变体,其中最常见的是01背包问题和完全背包问题。以下是这两种背包问题的算法概述:

1. 01背包问题

在01背包问题中,每个物品只有一个,可以选择放入背包或不放入背包。解决01背包问题通常使用动态规划算法。

算法步骤:

状态定义:设dp[i][j]表示在前i个物品中,选择若干物品放入容量为j的背包时,能得到的最大价值。
状态转移方程:
如果不选第i个物品,则 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j] = dp[i-1][j] dp[i][j]=dp[i1][j]
如果选第i个物品,则 d p [ i ] [ j ] = d p [ i − 1 ] [ j − w e i g h t s [ i ] ] + v a l u e s [ i ] dp[i][j] = dp[i-1][j-weights[i]] + values[i] dp[i][j]=dp[i1][jweights[i]]+values[i](前提是 j > = w e i g h t s [ i ] j >= weights[i] j>=weights[i],即背包容量足够)。
因此,状态转移方程为: d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − w e i g h t s [ i ] ] + v a l u e s [ i ] ) dp[i][j] = max(dp[i-1][j], dp[i-1][j-weights[i]] + values[i]) dp[i][j]=max(dp[i1][j],dp[i1][jweights[i]]+values[i])
初始化: d p [ 0 ] [ j ] = 0 dp[0][j] = 0 dp[0][j]=0(没有物品时,背包价值为0),对于所有的j。
结果: d p [ n ] [ c ] dp[n][c] dp[n][c]即为所求的最大价值,其中n是物品数量,c是背包容量。

2. 完全背包问题

在完全背包问题中,每种物品都有无限个,可以选择放入背包中的任意数量(只要不超过背包容量)。

算法步骤:

状态定义:与01背包相同,设dp[i][j]表示在前i个物品中,选择若干物品放入容量为j的背包时,能得到的最大价值。
状态转移方程:
对于完全背包问题,由于物品可以无限选择,所以状态转移方程略有不同: d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − w e i g h t s [ i ] ] + v a l u e s [ i ] ) dp[i][j] = max(dp[i-1][j], dp[i][j-weights[i]] + values[i]) dp[i][j]=max(dp[i1][j],dp[i][jweights[i]]+values[i])(注意这里是 d p [ i ] [ j − w e i g h t s [ i ] ] dp[i][j-weights[i]] dp[i][jweights[i]]而不是 d p [ i − 1 ] [ j − w e i g h t s [ i ] ] ) dp[i-1][j-weights[i]]) dp[i1][jweights[i]]
初始化和结果与01背包相同。

注意

对于空间优化,背包问题常使用滚动数组来减少空间复杂度,即将二维数组dp[i][j]优化为一维数组dp[j],并调整遍历顺序以避免覆盖未计算的状态。
背包问题是组合优化的经典问题之一,也是NP完全问题的一种。对于大规模数据,可能需要采用更高效的算法或启发式方法来求解。

knapsack背包问题算法python实现样例

以下是一个Python实现的knapsack背包问题算法:

def knapsack(values, weights, capacity):# 创建一个二维数组,用于存储每个子问题的最优解dp = [[0] * (capacity + 1) for _ in range(len(values) + 1)]# 填充二维数组,计算每个子问题的最优解for i in range(1, len(values) + 1):for j in range(1, capacity + 1):# 如果当前物品的重量大于背包容量,则不能放入背包,继承上一个子问题的最优解if weights[i - 1] > j:dp[i][j] = dp[i - 1][j]else:# 如果可以放入背包,选择放入物品或不放入物品的最大值dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weights[i - 1]] + values[i - 1])# 返回最终的最优解return dp[len(values)][capacity]# 测试
values = [60, 100, 120]
weights = [10, 20, 30]
capacity = 50
print(knapsack(values, weights, capacity))

上述代码中, values 列表存储每个物品的价值, weights 列表存储每个物品的重量, capacity 表示背包的容量。 knapsack 函数使用动态规划的方法解决了knapsack背包问题。它创建了一个二维数组 dp,并且通过遍历每个子问题的范围来填充数组。最后,返回最终的最优解。在上述测试中,输出结果为220,表示背包可以装入价值为220的物品。


http://www.mrgr.cn/news/40789.html

相关文章:

  • Egg.js 系列(1):Egg是什么、快速入门、目录结构
  • C++入门(有C语言基础)
  • SpringMVC——REST
  • 车辆重识别(2020NIPS去噪扩散概率模型)论文阅读2024/9/27
  • MySQL表的约束
  • JS+HTML基础
  • 性能微基准测试JMH
  • windows系统控制面板里面卸载软件的时候,出现invalid uninstall control file错误怎么办
  • 初始C语言(五)
  • 基础算法--双指针【概念+图解+题解+解释】
  • Qt界面优化——QSS
  • Nginx基础详解4(location模块、nginx跨域问题的解决、nginx防盗链的设计原理及应用、nginx模块化解剖)
  • 【Python报错已解决】KeyError: ‘key‘
  • 计算机网络:计算机网络概述:网络、互联网与因特网的区别
  • 数据结构-3.8.栈在括号匹配中的应用
  • 数据结构-3.10.队列的应用
  • 前端BOM常用操作
  • 知识图谱入门——2:技术体系基本概念:知识表示与建模、知识抽取与挖掘、知识存储与融合、知识推理与检索
  • 【EXCEL数据处理】000011 案列 EXCEL带有三角形图标的单元格转换
  • 【React】入门Day01 —— 从基础概念到实战应用