基于python实现贪心算法、蛮力法、动态规划法解决分数背包问题和0-1背包问题(附完整源码下载)

news2024/11/23 21:17:21

背包问题算法设计

问题要求在一个物品集合中选择合适的物品放入背包,在放入背包中的物品总重量不超过背包容量的前提下,希望放入背包的物品总价值最大。根据是否允许部分物品放入背包的要求,背包问题可以分为【分数背包问题】和【0-1背包问题】。

1. 概要设计

  • 分数背包问题,使用贪心算法得到最优解。
  • 0-1背包问题,若求近似解,使用贪心算法;若求最优解,则分别使用蛮力法、动态规划法及记忆功能改进的动态规划法求解,对于两种动态规划法,返回最终得到的动态规划表。

算法具体功能设计流程如图:

2. 具体算法设计

  • 贪心算法

①求分数背包问题最优解,其思想是求出每个物品的单位价值,并由高至低依次选择物品放入背包,若物品重量小于等于背包容量,则放入背包;否则,将物品进行拆分,将部分物品装进背包中。当背包剩余容量为0时,停止循环,返回最优总价值。函数设计如下:

def Greedy_F(n,c):   #贪心算法求解分数背包问题最优解
    #n表示物品个数,c表示背包容量
    global opt1
    Sumvalue1 = 0  #记录背包内物品总价值
    opt1 = [0]*n  #记录选择的物品
    danwei_v = []
    for i in range(n):
        d = v[i]/w[i]    #计算物品单位价值
        danwei_v.append(d)   
    value = list(enumerate(danwei_v))  #enumerate()函数将物品序号与其对应单位价值组合为一组数对
    value.sort(key=lambda a: a[1], reverse=True)  #按物品单位价值降序排序
    while c > 0:
        for i in range(n):
            if  w[value[i][0]] <= c:
                Sumvalue1 += v[value[i][0]]
                opt1[value[i][0]] = w[value[i][0]]
                c -= w[value[i][0]]
            else:
                Sumvalue1 += c*danwei_v[value[i][0]]
                opt1[value[i][0]] = c
        else:
            break
    return Sumvalue1  #返回最优总价值

②求0-1背包问题近似解,首先求出每个物品的单位价值,利用循环语句,每次选择单位价值最高的物品装入背包,若物品重量小于等于背包容量,则放入背包,否则,比较下一个物品,直到背包剩余容量为0或已经遍历完所有物品时,停止循环,返回最优总价值。函数设计如下:

def Greedy_I(n,c):     #贪心算法求解0-1背包近似解
    global opt2
    Sumvalue2 = 0
    opt2 = [0]*n
    danwei_v = []
    for i in range(n):
        d = v[i]/w[i]
        danwei_v.append(d)
    value = list(enumerate(danwei_v))
    value.sort(key=lambda a: a[11], reverse=True)
    while c > 0:
        for i in range(n):
            if  w[value[i][0]] <= c:
                Sumvalue2 += v[value[i][0]]
                opt2[value[i][0]] = 1
                c -= w[value[i][0]]
        else:
            break
    return Sumvalue2
  • 蛮力法

求0-1背包问题最优解。首先穷举物品的全部子集,设置一个记录最大价值的变量maxvalue,遍历所有子集,计算每个子集物品的总重量,若能装入背包,且当前的背包价值大于maxvalue,则将当前值赋值给maxvalue,最后循环遍历完所有的物品组合得到最优解,函数设计如下:

def Brute(n,c):   #蛮力法求解0-1背包最优解
    a = [0,1]
    l = list(product(a,repeat=n))
    #求解[0,1]中元素的全排列组合,repeat=n表示单个元素最大重复次数
    maxvalue = 0    #记录最大价值
    global opt3
    opt3 = []
    for i in range(len(l)):   #遍历所有子集
        sumweight = 0  # 将总重量与总价值清零,计算下一子集
        sumvalue = 0
        for j in range(n):
            sumweight += l[j][i]*w[j]   #计算子集的总重量
            sumvalue += l[j][i]*v[j]
        if sumweight <= c and sumvalue > maxvalue:   #判断该子集物品能否装入背包,并与最大价值比较进行更新
            maxvalue = sumvalue
            opt3 = list(l[i])
    return maxvalue
  • 动态规划法

动态规划算法求0-1背包问题最优解,初始化动态规划表,表中所有元素为0。单元格F(i,j)表示i个物品,承重量为j的背包最优解时的物品总价值,根据递推关系式:

利用循环逐行填表,最后一个单元格的值F(n,c)即为所要求的的最大总价值,函数设计如下:

def DP(n,c):   #动态规划法求解0-1背包问题最优解
    for i in range(1,n+1):
        for j in range(1,c+1):
            if j-w[i-1] < 0:
                F1[i][j] = F1[i-2][j]   #F1为初始化动态规划表,且为全局变量
            else:
                F1[i][j] = max(F1[i-1][j],F1[i-1][j-w[i-1]]+v[i-1])
    return F1[n][c]   #最大总价值
  • 记忆功能改进动态规划算法

该算法重点在于维护一个类似自底向上动态规划算法使用的表格,初始化动态规划表,表中第一行和第一列元素均为0,其他元素为-1,表明该单元格还没有被计算过。F(i,j)表示i个物品,承重量为j的背包最优解时的物品总价值。首先检查表中单元格的值是否小于0,若小于0,根据动态规划法的递推关系式使用递归调用进行计算,将返回的结果记录在表中,否则,直接返回单元格中的值。函数设计如下:

def MFK(i,j):   #记忆功能改进动态规划法
    value = 0
    if F2[i][j] < 0:    #F2为初始化动态规划表,且为全局变量
        if j < w[i-1]:
            value = MFK(i-1,j)
        else:
            value = max(MFK(i-1,j),v[i-1]+MFK(i-1,w[i-1]))
        F2[i][j] = value  #注意缩进
    return F2[i][j]
  • 回溯表格单元求最优子集的组成元素

利用while循环及条件判断语句,从最后一个单元格开始,若F[i][j]>F[i-1][j],表明物品i以及F[i-1][j-w[i]]的一个最优子集包括在最优解中;否则,物品i不是最优子集的一部分,比较F[i-1][j]与F[i-2][j],当回溯至背包剩余容量为0时,返回最优解。函数设计如下:

def show(F,n,c):   #F为动态规划表
    global opt4
    opt4 = [0]*n   #记录物品选择状态
    i = n
    j = c
    while c > 0:
        if F[i][j] > F[i-1][j]:
            opt4[i-1] = 1
            j -= w[i - 1]
            c -= w[i - 1]
            i -= 1
        else:
            i -= 1
    return opt4

3. 项目测试

考虑下列数据给出的实例:

  • 分数背包问题

通过贪心算法求得最优总价值为38.333,最优解为{物品2,物品3,物品4},物品3只有2/3放入了背包。

  • 0-1背包问题

1、贪心算法求其近似解,得到最大总价值为37,近似解为{物品1,物品2,物品4}。

2、蛮力法、动态规划法、记忆功能改进的动态规划法求最优解,得到最优总价值为37,最优解为{物品1,物品2,物品4}。可以看出,动态规划表F1中每个单元格的值都进行了计算,在F2中,-1表示没有计算的值,即只计算了11个值,从而应用记忆功能改进后,动态规划法的效率得到了提高。

根据测试结果可以看出,对于该实例,用贪心算法得到的近似解与蛮力法等得到的最优解是一样的,即该近似解就是最优解,但该算法并不总是能给出最优解,反例如下:

利用贪心算法得到近似解为{物品1},总价值为40;而利用蛮力法得到最优解为{物品2,物品3},最优总价值为50,即该近似解不是最优解。

完整源码下载

基于python实现贪心算法、蛮力法、动态规划法解决分数背包问题和0-1背包问题源码+项目说明及注释.zip

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/995448.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Web Flow远程代码执行漏洞复现(CVE-2017-4971)

一、搭建环境 cd vulhub/spring/CVE-2017-4971 docker-compose up -d 影响版本:Spring Web Flow 2.4.0 ~ 2.4.4 触发条件: 1.MvcViewFactoryCreator对象的useSpringBeanBinding参数需要设置为false&#xff08;默认值&#xff09; 2. flow view对象中设置BinderConfiguration…

网页版QQ签到加速源码 QQ音乐等级加速源码 CF活动一键领取源码 QQ手游等级加速

QQ网页签到加速小工具PHP源码二次优化版 包含QQ空间功能 QQ空白昵称 QQ大会员签到 CF活动一键领取 清空QQ空间说说 QQ每日打卡加速 QQ空间删除说说 QQ手游等级加速 QQ微视等级加速 QQ音乐等级加速签到

【操作系统】24王道考研笔记——第四章 文件管理

第四章 文件管理 一、文件系统基础 1.基本概念 2.文件的逻辑结构 顺序文件&#xff1a; 索引文件&#xff1a; 索引顺序文件&#xff1a; 效率分析&#xff1a; 多级索引顺序文件&#xff1a; 总结&#xff1a; 3.文件目录 文件控制块&#xff08;FCB&#xff09; 目录的基本…

第三方软件测评报告怎么做?

第三方软件测试 总体来说&#xff0c;软件产品验收测试一般主要包括以下几个步骤&#xff1a; 1.制定测试计划&#xff0c;测试项&#xff0c;测试策略及验收通过准则&#xff0c;并经过客户参与的计划评审。 2.建立测试环境&#xff0c;设计测试用例&#xff0c;并经过评审…

华脉智联发布国标28181 Android SDK和DEMO

在目前很多行业项目中&#xff0c;客户使用的是海康、大华等监控平台的GB/28181平台&#xff0c;或者是其他的第三方的GB/28181平台。但是对于那些不具备GB/28181协议的单兵终端&#xff0c;如何接入GB/28181平台网络中呢&#xff1f; 首先&#xff0c;我们了解下GB/T28181&…

Vue中表单手机号验证与手机号归属地查询

下面是一篇关于Vue中如何进行表单手机号验证与手机号归属地查询的Markdown格式的文章&#xff0c;包含代码示例。 Vue中表单手机号验证与手机号归属地查询 手机号验证和归属地查询是许多Web应用程序中常见的功能之一。在Vue.js中&#xff0c;我们可以轻松地实现这两个功能。本…

好奇一下各个大模型对华为mate60系列的看法

目前华为Mate60系列手机已上市并获抢购&#xff0c;个人觉得很不错&#xff0c;很好奇各个AI大模型对此事的看法&#xff0c;于是对chatGPT、文心一言、讯飞星火进行了一下粗浅的测试。 题目一&#xff08;看看三个模型的综合分析能力&#xff09; “目前华为Mate60系列手机已…

CHS零壹视频恢复程序OCR使用方法

目前CHS零壹视频恢复程序监控版、专业版、高级版已经支持了OCR&#xff0c;OCR是一种光学识别系统&#xff0c;通俗说就和扫描仪带的OCR软件一样的原理&#xff1a; 分析照片->OCR获取字符串->整理字符串->输出 使用方法如下&#xff08;以CHS零壹视频恢复程序监控版…

最近

深圳近日经历了一场暴雨&#xff0c;周四夜晚&#xff0c;很多下晚班的同事因为雨水没法顺利打车回家。有个朋友&#xff0c;因为打车的等待时间太长&#xff0c;索性直接在公司过夜了。 早上因为磅礴的大雨我搁浅在家&#xff0c;也是因为下雨&#xff0c;本来要和龙哥一起去广…

html禁止用户复制内容方法

要禁止复制内容&#xff0c;可以使用以下几种方法&#xff1a; 使用CSS属性&#xff1a;可以通过设置user-select属性为none&#xff0c;这样用户就无法选中和复制内容。例如&#xff1a; body {-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user…

用栈实现队列,用队列实现栈(JAVA)

用两个栈实现队列 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 class CQueue {Stack<Integer>innew Stack<>();Stack<Integer>outnew Stack<>();public CQueue() {Stack<Integer>innew Stack<>();Stack<…

SpringBoot集成Apache RocketMQ详解

文章目录 0. 前言1. Spring Boot 集成Apache RocketMQ详细步骤1.1.添加依赖1.2.配置RocketMQ1.3.创建消息生产者&#xff08;Producer&#xff09;1.4.创建消息消费者&#xff08;Consumer&#xff09; 2. 测试验证3. 常见报错4. 参考文档5. 源码地址 0. 前言 上个章节我们学习…

下载Ubantu镜像文件、创建虚拟机以及ubantu安装详细教程

目录 前言 Ubantu是什么&#xff1f;它有什么作用&#xff1f; 一、Ubantu镜像文件下载步骤 1.第一步安装VMware Workstation 2.第二步下载Ubuntu的镜像文件 镜像文件下载官网网址入下&#xff1a; 二、创建虚拟机和安装Ubantu的步骤 1.打开VMware Workstation并点击创…

反射与注解

【今日】 人生只有一次 不妨大胆一点 目录 一 反射 1.访问构造方法 1.Constructor的使用 2.反射一个类中的所有构造方法 3.用Constructor创建并返回实列对象 2.访问成员变量 1Field的使用方法 2.反射一个类中的所有成员变量 3.获取修改成员变量的值 3.访问成员方…

javaee springMVC model的使用

项目结构图 pom依赖 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org…

【LeetCode75】第五十一题 最大子序列的分数

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们两个长度一样的数组&#xff0c;让我们再num1中找出一个长度为k的子序列&#xff0c;然后把这个子序列累加的和乘上在nums2中对…

74 QML ProgressBar显示进度数字

1 引言 由于目前使用的是qt.5.14版本&#xff0c;Qt Quick Controls 已经从1.0版本 变为2.0版本了&#xff0c;如果继续使用的Qt Quick Controls 1 的style:方式&#xff0c;改变进度条的样式已经不行了&#xff0c;其会报错&#xff1a;Invalid property name "style&quo…

Langchain的一些问题和替代选择

Langchain因其简化大型语言模型(llm)的交互方面的到关注。凭借其高级的API可以简化将llm集成到各种应用程序中的过程。 但是Langchain乍一看似乎是一个方便的工具&#xff0c;但是它有时候否更像是一个语言迷宫&#xff0c;而不是一个直截了当的解决方案。在本文中&#xff0c…

mysql 增量备份与恢复使用详解

目录 一、前言 二、数据备份策略 2.1 全备 2.2 增量备份 2.3 差异备份 三、mysql 增量备份概述 3.1 增量备份实现原理 3.1.1 基于日志的增量备份 3.1.2 基于时间戳的增量备份 3.2 增量备份常用实现方式 3.2.1 基于mysqldump增量备份 3.2.2 基于第三方备份工具进行增…

安装 Gin 框架

首先需要在目录下初始化一下 go 项目 go init可以看到生成了一个go.mod文件&#xff0c;然后使用以下命令安装 gin 框架 go get -u github.com/gin-gonic/gin养成一个好习惯&#xff0c;在写项目之前先初始化项目 go mod init go mod tidy如果不初始化项目的话没有第三方库补…