【回溯算法】【Python实现】0-1背包

文章目录

    • @[toc]
      • 问题描述
        • 形式化描述
      • 回溯法
      • 时间复杂性
      • `Python`实现

问题描述

  • 给定 n n n种物品和一背包,物品 i i i的重量是 w i w_{i} wi,其价值为 v i v_{i} vi,背包的容量为 c c c
  • 如何选择装入背包中的物品,使得装入背包中物品的总价值最大
形式化描述
  • 给定 c > 0 c > 0 c>0 w i > 0 w_{i} > 0 wi>0 v i > 0 ( 1 ≤ i ≤ n ) v_{i} > 0 (1 \leq i \leq n) vi>0(1in),找出一个 n n n 0 − 1 0-1 01向量 ( x 1 , x 2 , ⋯ , x n ) (x_{1} , x_{2} , \cdots , x_{n}) (x1,x2,,xn) x i ∈ { 0 , 1 } ( 1 ≤ i ≤ n ) x_{i} \in \set{0 , 1} (1 \leq i \leq n) xi{0,1}(1in),使得 ∑ i = 1 n w i x i ≤ c \displaystyle\sum\limits_{i = 1}^{n}{w_{i} x_{i}} \leq c i=1nwixic,而且 ∑ i = 1 n v i x i \displaystyle\sum\limits_{i = 1}^{n}{v_{i} x_{i}} i=1nvixi达到最大
  • 0 − 1 0-1 01背包问题是一个特殊的整数规划问题

max ⁡ ∑ i = 1 n v i x i { ∑ i = 1 n w i x i ≤ c x i ∈ { 0 , 1 } ( 1 ≤ i ≤ n ) \max\displaystyle\sum\limits_{i = 1}^{n}{v_{i} x_{i}} \kern{2em} \begin{cases} \displaystyle\sum\limits_{i = 1}^{n}{w_{i} x_{i} \leq c} \\ x_{i} \in \set{0 , 1} (1 \leq i \leq n) \end{cases} maxi=1nvixi i=1nwixicxi{0,1}(1in)


回溯法

  • 0 − 1 0-1 01背包问题是子集选取问题,解空间可用子集树表示,解 0 − 1 0-1 01背包问题的回溯法与解装载问题的回溯法十分相似
  • 在搜索解空间树时,只要其左儿子结点是一个可行结点,搜索就进入其左儿子,当右子树中有可能包含最优解时才进入右子树搜索,否则将右子树剪去
  • r r r是当前剩余物品价值总和, c p cp cp是当前价值, b e s t p bestp bestp是当前最优价值,当 c p + r ≤ b e s t p cp + r \leq bestp cp+rbestp时,可剪去右子树,计算右子树中解的上界的更好方法是,将剩余物品以其重量价值排序,然后依次装入物品,直至装不下时,再装入该物品的一部分而装满背包,由此得到的价值是右子树中解的上界
  • 为了便于计算上界,可先将物品依其单位重量价值从大到小排序,此后只要按顺序考察各物品即可

时间复杂性

  • 计算上界需要 O ( n ) O(n) O(n)时间,在最坏情况下有 O ( 2 n ) O(2^{n}) O(2n)个右儿子结点需要计算上界
  • 所以解 0 − 1 0-1 01背包问题的回溯算法所需的计算时间为 O ( n 2 n ) O(n 2^{n}) O(n2n)

Python实现

def backtrack_knapsack(values, weights, capacity):n = len(values)# 计算物品的单位重量价值unit_values = [v / w for v, w in zip(values, weights)]# 根据单位重量价值对物品进行降序排序sorted_items = sorted(range(n), key=lambda k: unit_values[k], reverse=True)best_solution = []best_value = 0def constraint(weight):# 约束函数: 检查当前解是否满足容量限制return weight <= capacitydef bound(weight, value, index):# 限界函数: 计算当前解的价值总和加上剩余物品价值作为上界, 用于剪枝bound = valueremaining_capacity = capacity - weightfor item in range(index + 1, n):if remaining_capacity >= weights[sorted_items[item]]:remaining_capacity -= weights[sorted_items[item]]bound += values[sorted_items[item]]else:bound += remaining_capacity * values[sorted_items[item]] / weights[sorted_items[item]]breakreturn bounddef backtrack(solution, weight, value, index):nonlocal best_solution, best_valueif index == n:# 已经遍历完所有物品if value > best_value:# 如果当前解的价值更大, 更新最优解best_solution = solutionbest_value = valuereturn# 尝试选择当前物品weight += weights[sorted_items[index]]value += values[sorted_items[index]]if constraint(weight):# 如果满足约束函数, 继续探索下一个物品backtrack(solution + [1], weight, value, index + 1)# 恢复回溯之前状态weight -= weights[sorted_items[index]]value -= values[sorted_items[index]]# 尝试不选择当前物品if bound(weight, value, index) >= best_value:# 如果当前解的上界仍然可能更好, 继续探索下一个物品backtrack(solution + [0], weight, value, index + 1)backtrack([], 0, 0, 0)return best_solution, best_valuevalues = [60, 100, 120]
weights = [10, 20, 30]
capacity = 50best_solution, best_value = backtrack_knapsack(values, weights, capacity)print(f'最优解: {best_solution}')
print(f'最优值: {best_value}')
最优解: [0, 1, 1]
最优值: 220

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

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

相关文章

《云原生安全攻防》-- 构建云原生攻防场景

在本节课程中&#xff0c;我们将学习云原生攻防场景的构建。为了研究云原生安全攻击案例&#xff0c;我们需要搭建一个云原生攻击测试环境&#xff0c;以便进行攻防研究和攻击手法的复现。 在这个课程中&#xff0c;我们将学习以下内容&#xff1a; 构建云原生攻防场景&#xf…

Jetpack Compose 初探

官方文档永远是第一学习渠道。 Jetpack Compose 初探 前言命令式UI与声明式UIJetpack Compose 的优势开始使用Jetpack Compose创建支持 Compose 的新应用可组合函数布局Material Design列表和动画前言 Jetpack Compose 是用于构建原生 Android 界面的新工具包。它使用更少的代…

创建和选择数据库

如果管理员在设置权限时为您创建了数据库&#xff0c;您可以开始使用它。否则&#xff0c;您需要自己创建&#xff1a; mysql> CREATE DATABASE menagerie; 在Unix系统下&#xff0c;数据库名称区分大小写&#xff08;与SQL关键词不同&#xff09;&#xff0c;因此您必须始…

ModuleNotFoundError: No module named ‘openpyxl‘的解决方案

问题描述&#xff1a; ModuleNotFoundError: No module named ‘openpyxl’ 这个错误表示你的 Python 环境中没有安装 openpyxl 这个模块。openpyxl 是一个用于读写 Excel 2010 xlsx/xlsm/xltx/xltm 文件的 Python 库。 解决方案&#xff1a; 要解决这个问题&#xff0c;你需…

深入理解MySQL三大日志:redo log、binlog、undo log

前言 MySQL是一个功能强大的关系型数据库管理系统&#xff0c;它的高可靠性、高性能和易用性使得它成为众多企业和开发者的首选。在MySQL内部&#xff0c;为了保证数据的完整性、恢复能力和并发性能&#xff0c;设计了一套复杂的日志系统。其中&#xff0c;redo log、bin log和…

云服务器和物理机该怎样分别呢

随着网络的不断发展&#xff0c;服务器的类型也在以不同的方式更新。现在云服务器的兴起占据了很大一部分市场&#xff0c;物理机的市场份额受到了很大的冲击。物理机和云服务器有什么区别&#xff1f;如何选择适合自己需求的&#xff1f;虽然物理服务器和云服务器都是服务器&a…

hvigor ERROR: Task PreviewBuild,--watch not found in hvigor node: entry.”

harmony deveco 配置问题处理 这是第三次配置 harmony&#xff0c;以为会一切顺利&#xff0c;不想会遇到这个问题。环境都安装好后创建一个 demo 后预览失效&#xff0c;虚拟机启动运行正常。 通常遇到失败的情况直接把 devtool 的命令直接拿到命令行中执行一遍就能看到错误…

618洗地机如何选?洗地机哪个牌子好?洗地机详解

快节奏的生活方式使得清洁工作成为许多人难以应付的任务。不过&#xff0c;洗地机的出现为这个问题提供了完美的解决方案。洗地机以其强劲的吸力和高效的清洁功能&#xff0c;能够快速清理地面的污渍和灰尘&#xff0c;极大地提升了清洁效率。不仅如此&#xff0c;洗地机的操作…

MySQL--增、删、改、查,

数据库的概述、发展、现状、历史、分类 MySQL关系型数据库、架构&#xff08;C/S&#xff09; window系统安装MySQL数据库 Linux系统【选学】 数据库对象——数据库&#xff08;database&#xff09; show、create、drop命令 数据库对象——表&#xff08;table&#xff…

OFDM 802.11a的FPGA实现(十六)长训练序列:LTS(含Matlab和verilog代码)

目录 1.前言2.原理3.Matlab生成长训练序列4.硬件实现5.ModelSim仿真6.和Matlab仿真结果对比 原文链接&#xff08;相关文章合集&#xff09;&#xff1a; OFDM 802.11a的xilinx FPGA实现 1.前言 在之前已经完成了data域数据的处理&#xff0c;在构建整个802.11a OFDM数据帧的时…

Linux初学1

Unix unix和LInux的关系 LInux的吉祥物tux Nginx Directoryhttps://mirror.iscas.ac.cn/centos/7/isos/x86_64/redhat7 网络连接 桥接模式&#xff1a;虚拟系统可以和外部系统通讯&#xff0c; 你自家里折腾当然桥接没问题&#xff0c;如果一个教室里全都用桥接&#xff1…

fread fwrite fseek ftell使用

第一个案例 #include <stdio.h> #include <string.h>int main() {FILE *fp;char c[] "Thisisrunoob1";char buffer[20];/* 打开文件用于读写 */fp fopen("C:/Users/ACER/Desktop/rr.txt", "w"); /* 写入数据到文件 */fwrite(c, s…

2024年CSPM考试时间线梳理!

最近后台有朋友在问今年CSPM的考试安排&#xff0c;给大家整理一下&#xff0c;需要的朋友认真查看&#xff0c;不要错过考试。2024年5月12日举行了本年度第二次CSPM3级考试~接下来的考试安排如下&#xff1a; 1&#xff09;2024年CSPM考试安排 本次考试出成绩时间——2024年6…

go get和go get -u

在 Go&#xff08;Golang&#xff09;编程中&#xff0c;go get 和 go get -u 是用于管理依赖项和模块的命令。以下是每个命令的详细解释&#xff1a; go get 目的&#xff1a;go get 命令用于下载和安装 Go 项目所需的软件包和依赖项。它会获取指定的软件包及其依赖项。行为…

【大数据】计算引擎MapReduce

目录 1.概述 1.1.前言 1.2.大数据要怎么计算&#xff1f; 1.3.什么是MapReduce&#xff1f; 2.架构 3.工作流程 4.shuffle 4.1.map过程 4.2.reduce过程 1.概述 1.1.前言 本文是作者大数据系列专栏的其中一篇&#xff0c;专栏地址&#xff1a; https://blog.csdn.ne…

特征提取与深度神经网络DNN

OpenCV中的深度神经网络&#xff08;DNN&#xff09;模块&#xff0c;现在已经支持图像风格迁移、图像分类、对象检测、语义分割、实例分割、图像变换等。 只支持推理&#xff0c;不支持训练 支持主流的深度学习框架生成模型 推荐使用pytorch/onnx/tensorflow ResNet18的图像…

无代码无国界:我们正在走向软件安全的狂野西部吗?

我们使用的几乎所有东西都是基于代码构建的&#xff0c;从汽车到智能冰箱再到门铃。在企业中&#xff0c;无数的应用程序保持设备、工作流程和操作的运行。因此&#xff0c;当早期的无代码开发平台于 2010 年推出时&#xff0c;承诺为公民开发人员提供更易于访问的应用程序开发…

Redis加入系统服务,开机自启

vi /etc/systemd/system/redis.service i [Unit] Descriptionredis-server Afternetwork.target [Service] Typeforking #使用&#xff08;/usr/local/bin/redis-server&#xff09;运行&#xff08;/usr/local/src/redis-6.2.6/redis.conf&#xff09; ExecStart/usr/local/…

解决GitHub提交后不显示自己的头像 显示另一个没见过的账号?

问题说明 最近换了几台电脑开发项目&#xff0c;提交到github&#xff0c;看了下提交记录&#xff0c;怎么冒出来不是我的账号头像&#xff1f; 什么鬼i 原因分析 github是按照你注册时候填的邮箱来查找账号&#xff0c;并显示在提交记录上面的。如果账号找不到头像就出不来…

【Day3:JAVA运算符、方法的介绍】

目录 1、运算符1.1 赋值运算符1.2 比较运算符1.3 逻辑运算符1.3.1 逻辑运算符概述1.3.2 逻辑运算符分类1.3.3 短路的逻辑运算符 1.4 三元运算符1.5 运算符优先级 2、方法2.1 方法介绍2.2 方法的定义和调用格式2.2.1 方法的调用2.2.2 带参数方法的调用2.2.3 带返回值方法的调用2…