0/1背包问题

实验要求

随机生成500个0/1背包问题(问题规模可以相对较小),分别使用贪心算法和动态规划进行求解,

要求:1)统计贪心算法求得最优值的概率,

2)计算比值

3)应用贪心算法求解时,统计最坏的情况下误差有多大,

4)实验结果跟实验设置的参数(如:背包容量、物品的体积)关系很大,简要分析参数对结果的影响。

设计分析

对0-1背包问题,可以设计多种贪心策略,如:

重量最轻的物品优先的贪心策略。

价值最大的物品优先的贪心策略。

单位价值最大的物品优先的贪心策略。

随机选择物品的贪心策略。

无法数学证明某一种策略的最优性,因此使用贪心法求解0-1背包问题时,必须尽可能多地枚举各种贪心策略,并从各种贪心策略的运行结果中,找出问题的近似最优解。

算法描述

根据每个物品的单位价值(即价值/体积),将物品从高到低排序。

依次考虑每个物品,若该物品的体积小于等于背包剩余容量,则将该物品放入背包中,并更新剩余容量。

若该物品的体积大于背包剩余容量,则将该物品不放入背包,考虑下一个物品。

重复步骤2-3,直到所有物品都被考虑完毕,或者背包容量已经全部用完为止。

该贪心算法的核心思想是:每次选择单位价值最大的物品放入背包中,这样可以保证在背包容量充足的情况下,每次放入物品都能使背包价值最大化。

源码:

import random

# 生成一个背包问题
def generate_knapsack_problem(n, max_volume, max_weight):
    # 物品数量
    items = list(range(1, n+1))
    # 物品体积和价值
    volumes = [random.randint(1, max_volume) for _ in items]
    values = [random.randint(1, max_weight) for _ in items]
    # 背包容量
    capacity = random.randint(max_volume, max_volume*2)
    return items, volumes, values, capacity

# 贪心算法求解0/1背包问题
def greedy_knapsack(items, volumes, values, capacity):
    n = len(items)
    ratios = [(i, values[i-1]/volumes[i-1]) for i in items]
    ratios.sort(key=lambda x: x[1], reverse=True)
    selected_items = []
    total_value = 0
    for i, ratio in ratios:
        if volumes[i-1] <= capacity:
            selected_items.append(i)
            total_value += values[i-1]
            capacity -= volumes[i-1]
    return selected_items, total_value

# 动态规划算法求解0/1背包问题
def dp_knapsack(items, volumes, values, capacity):
    n = len(items)
    dp = [[0] * (capacity+1) for _ in range(n+1)]
    for i in range(1, n+1):
        for j in range(1, capacity+1):
            if volumes[i-1] > j:
                dp[i][j] = dp[i-1][j]
            else:
                dp[i][j] = max(dp[i-1][j], dp[i-1][j-volumes[i-1]] + values[i-1])
    selected_items = []
    j = capacity
    for i in range(n, 0, -1):
        if dp[i][j] > dp[i-1][j]:
            selected_items.append(i)
            j -= volumes[i-1]
    selected_items.reverse()
    return selected_items, dp[n][capacity]

# 随机生成500个背包问题并求解
n_problems = 500
max_volume = 100
max_weight = 100

greedy_success = 0
total_ratio = 0
worst_ratio = 0
worst_error = 0

for i in range(n_problems):
    items, volumes, values, capacity = generate_knapsack_problem(10, max_volume, max_weight)
    greedy_items, greedy_value = greedy_knapsack(items, volumes, values, capacity)
    dp_items, dp_value = dp_knapsack(items, volumes, values, capacity)

    # 统计贪心算法求解最优值的概率
    if greedy_value == dp_value:
        greedy_success += 1

    # 计算贪心算法和动态规划算法求解结果的比值
    ratio = greedy_value / dp_value
    total_ratio += ratio

    # 计算贪心算法求解最差情况下的误差
    if len(dp_items) > len(greedy_items):
        worst_ratio += 1
        worst_error += dp_value - greedy_value

# 输出统计结果
print(f"贪心算法求解最优值的概率:{greedy_success/n_problems:.2%}")
print(f"贪心算法与动态规划算法求解结果的比值:{total_ratio/n_problems:.2f}")
print(f"贪心算法求解最差情况下的误差:{worst_error/worst_ratio:.2f}")

实验结果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Postman中参数填写方式

Postman中参数填写和请求方法有关&#xff0c;一般接口用例请求方法GET与POST常用&#xff0c;所以主要是这两种请求方法请求参数填写 一、GET请求方法参数填写 1、直接在URL中填写请求参数,如直接在URL中填写&#xff1a; http://www.example.com:8089/userapi?unamelisi&…

直播原理,直播CDN及相关协议

一、直播原理 直播是一对多的完整的视频解编码原理&#xff1a; 那么直播的原理无疑也是要基于视频的解编码原理的 参考视频 二、直播CDN 什么是CDN就不多说了&#xff0c;可参考亚马逊的文章 三、相关协议 RTMP及HTTP-FLV&#xff08;都是在FLV封装格式基础上的&#xf…

串口通信(6)-C#串口通信Modbus协议完整实例

本文讲解C#基于ModbusRTU协议串口通信完整实例。 前言 关于modbus的协议从上一篇中有介绍,本篇不在阐述。 串口通信(5)-C#串口通信数据接收不完整解决方案 创建实例 添加控件和事件等 参考界面文件 namespace ModbusRTUDemo {partial class MainForm{/// <summary>…

go学习redis的学习与使用

文章目录 一、redis的学习与使用1.Redis的基本介绍2.Redis的安装下载安装包即可3.Redis的基本使用1&#xff09;Redis的启动&#xff1a;2&#xff09;Redis的操作的三种方式3&#xff09;说明&#xff1a;Redis安装好后&#xff0c;默认有16个数据库&#xff0c;初始默认使用0…

Toyota Programming Contest 2023#8(AtCoder Beginner Contest 333)

A - Three Threes 题目大意&#xff1a;给你一个整数n&#xff0c;将这个数n输出n次。 呃呃 B - Pentagon 题目大意&#xff1a;给你一个正五边形ABCDE&#xff0c;给你任意两条边&#xff0c;判断是否相等 主要问题要判断一下内边&#xff1a;AD&#xff0c;AC&#xff0c;…

深入探讨敏捷开发项目管理流程与Scrum工具:构建高效团队与卓越产品的秘诀

目录 前言 敏捷开发项目管理流程&#xff1a; 项目启动&#xff1a; Sprint规划&#xff1a; Sprint执行&#xff1a; Sprint评审&#xff1a; 回顾与持续改进&#xff1a; Scrum 工具&#xff1a; Jira&#xff1a; Trello&#xff1a; VersionOne&#xff1a; Con…

重要通知!中国电信警告:用户须关闭路由器“双频合一”功能

在网络的无尽时空里&#xff0c;一场电信官方的宣战正酝酿中&#xff0c;目标锁定在我们日常生活中不可或缺的WiFi身上~ 最新消息曝光&#xff0c;竟然是路由器内藏的一个名为“双频合一”的功能引发了这场轰轰烈烈的网络风暴。 我们时常觉得WiFi就像是隐身在我们生活中的超级英…

算法模板之单链表图文讲解

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;算法模板、数据结构 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. ⛳️使用数组模拟单链表讲解1.1 &#x1f514;为什么我们要使用数组去模拟单链表…

全国职业院校技能大赛“大数据应用开发”赛项说明

1、赛项介绍 &#xff08;1&#xff09;赛项名称 全 国 职 业 院 校 技 能 大 赛 “大数据应用开发” 赛 项 https://www.vcsc.org.cn/ 大赛组织机构介绍 全国职业院校技能大赛(以下简称大赛)是教育部发起并牵头&#xff…

关于反射机制的简单理解

1、反射的简单认识 1.1 定义 Java的反射&#xff08;reflection&#xff09;机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意方法和属性&#xff0c;既然能拿到,那么我…

低代码开发入局,同飞股份应用云表自主开发MES管理系统

近日&#xff0c;为了贯彻落实《“十四五”智能制造发展规划》&#xff0c;推动中国从制造大国向制造强国转变&#xff0c;工业和信息化部发布了2023年度“智能制造优秀场景”名单。经过省级有关部门和中央企业的推荐、专家评审、网上公示等程序&#xff0c;同飞股份凭借其“先…

Spring boot basePackages 通配符* 找不到Bean

Spring boot basePackages 通配符* 找不到Bean 今天遇到了一个关于spring boot 组件ComponentScan 中basePackages 使用通配符* 找不到Bean的问题 目录结构中BussinessPerson与Dog类中都有标注有Component注解&#xff0c;结果扫描不到。 然后删除通配符&#xff0c;结果运行成…

leetcode砍竹子1

现需要将一根长为正整数 bamboo_len 的竹子砍为若干段&#xff0c;每段长度均为正整数。请返回每段竹子长度的最大乘积是多少。 1.根据公式看出取等是在所有n相等的情况&#xff0c;可以得出只有均分 乘积最大 2.转为求下面的最大值 3.求导&#xff0c;得出驻点为e2.7左右 …

HPM6750系列--第九篇 GPIO详解(基本操作)

一、目的 在之前的博文中我们主要介绍了不同系统不同开发编译调试环境的配置和操作&#xff08;命令行方式、Visual Studio Code、Segger Embedded Studio for RISC-V&#xff09;&#xff0c;以帮助大家准备好学习环境为目的&#xff0c;但是未涉及到芯片本身以及外设的讲解。…

Linux——进程中被打开的文件

C语言中有着许多对文件操作的函数&#xff0c;包括其他语言也有&#xff0c;但是从语言来了解文件有点浅显计算机的一切都离不开操作系统&#xff0c;那么文件跟操作系统也有着密切的关系&#xff0c;所以我们从系统层面来了解文件&#xff08;在进程中打开的文件&#xff09;文…

openGauss学习笔记-162 openGauss 数据库运维-备份与恢复-导入数据-通过INSERT语句直接写入数据

文章目录 openGauss学习笔记-162 openGauss 数据库运维-备份与恢复-导入数据-通过INSERT语句直接写入数据162.1 使用openGauss数据库提供的客户端工具向openGauss数据库写入数据162.2 通过JDBC/ODBC驱动连接数据库执行INSERT语句向openGauss数据库写入数据162.2.1 函数原型162.…

在Node.js中MongoDB排序的方法

本文主要介绍在Node.js中MongoDB排序的方法。 目录 Node.js中MongoDB排序使用原生的mongodb驱动程序进行排序使用Mongoose库中的排序 Node.js中MongoDB排序 在Node.js中使用MongoDB进行排序&#xff0c;可以使用原生的mongodb驱动程序或者Mongoose库。 使用原生的mongodb驱动…

SpringBoot之响应的详细解析

2. 响应 前面我们学习过HTTL协议的交互方式&#xff1a;请求响应模式&#xff08;有请求就有响应&#xff09; 那么Controller程序呢&#xff0c;除了接收请求外&#xff0c;还可以进行响应。 2.1 ResponseBody 在我们前面所编写的controller方法中&#xff0c;都已经设置了…

我的世界合成表大全(最新完整版)

我的世界合成表配方是什么? 我的世界是一款非常有趣的高自由度的沙盒游戏&#xff0c;游戏中玩家可以根据合成配方制作各种各样的物品。今天小编就为大家带来我的世界合成表大全(最新完整版)&#xff0c;希望可以帮到大家。 我的世界合成表大全(最新完整版) 基础物品合成表&a…

力扣第2题-判断一个数值是否是回文数[简单]

题目描述 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如&#xff0c;121 是回文&am…