分支限界笔记
文章目录
- 概要
- 整体架构流程
- 基本概念
- 分支限界法的定义
- 核心思想
- 简单问题介绍
- 问题:简单背包问题
- 思考:暴力解法
- 聪明的解法:分支限界法
- 直观理解分支限界法的步骤
- 0-1背包问题
- 问题描述
- 问题建模
- 问题分析
- 1. 定义问题的解空间,确定易于搜索的解空间结构
- 2. 设计限界函数,确定目标函数值的估算方法
- 3. 基于限界函数的广度优先搜索
- 实例
- 伪代码
- 简单例子
- 旅行商问题
- 问题描述
- 问题建模
- 分支界限法解决问题
- 小结
概要
分支限界笔记
整体架构流程
基本概念
分支限界法的定义
分支限界法是一种广度优先搜索问题解空间树的方法,它结合了限界函数以提高搜索效率。
核心思想
- 分支:基于广度优先策略,逐步生成所有子结点。
- 限界函数:
- 为每个子结点计算一个值,用来衡量其可行性或优越性。
- 将符合限界条件的结点加入“活结点表”中。
- 选择最优的扩展结点:
- 从活结点表中选取“最有利”的一个子结点,作为扩展的结点。
- 引导搜索向解空间树的最优解方向推进,以尽快找到问题的解。
简单问题介绍
问题:简单背包问题
你有一个容量为 10kg 的背包,想从以下物品中挑选一些装进去,使背包中的总价值最大。
物品 | 重量 (kg) | 价值 (元) |
---|---|---|
A | 2 | 6 |
B | 5 | 10 |
C | 3 | 12 |
规则:
- 每个物品最多选一次。
- 背包的总重量不能超过 10kg。
思考:暴力解法
如果我们不聪明地去解决问题,可以用“穷举法”:
- 列出所有可能的组合:包括不装任何物品、装一个物品、装两个物品等。
- 对每个组合,检查是否符合背包容量限制。
- 如果符合,就计算总价值,记录最大的一个。
举个例子:
- 不装任何物品,总重量为 0,总价值为 0。
- 装物品 A,总重量为 2,总价值为 6。
- 装物品 A 和 C,总重量为 5,总价值为 18。
这种方法对小规模问题还行,但物品数量一多,组合会成倍增加,效率太低。
聪明的解法:分支限界法
分支限界法可以帮助我们有选择地搜索组合,而不需要列举所有可能性。我们分步骤来看:
-
分支:生成子问题
- 从装还是不装某个物品的选择开始。例如:
- 不装 A,背包里还有 10kg 容量。
- 装 A,背包里剩下 8kg 容量。
- 从装还是不装某个物品的选择开始。例如:
-
限界:筛选有希望的分支
- 如果某个选择显然不可能比当前最优解更好,就放弃。
- 比如:如果当前背包已经装满了,但价值远低于已知最优解,就不再考虑这条路径。
-
活结点:保存还没探索的分支
- 我们用一个“活结点表”来存储每一步生成的子问题。
- 按照某种优先级(比如潜在价值的大小)选择下一个要扩展的结点。
-
剪枝:放弃无意义的计算
- 当某个分支已经超过背包容量限制,就直接丢弃。
直观理解分支限界法的步骤
假设我们开始解上面的问题:
-
初始状态:背包空着,容量为 10kg,当前总价值为 0。
-
第一分支:
- 不装 A:剩余容量 = 10kg,总价值 = 0。
- 装 A:剩余容量 = 8kg,总价值 = 6。
-
第二分支:
- 从“装 A”继续分支:
- 不装 B:剩余容量 = 8kg,总价值 = 6。
- 装 B:剩余容量 = 3kg,总价值 = 16。
- 从“不装 A”继续分支:
- 不装 B:剩余容量 = 10kg,总价值 = 0。
- 装 B:剩余容量 = 5kg,总价值 = 10。
- 从“装 A”继续分支:
-
每次分支后,检查是否超过容量。如果超过,就剪枝。例如:
- 假设某分支剩余容量为负值,这条路径就无效。
-
继续分支,直到所有路径探索完毕,记录下最大价值。
0-1背包问题
问题描述
给定n种物品和一个背包。物品的重量是w,其价值为p,背包的容量为C。
问:应如何选择装入背包的物品,使得装入背包的物品总重量不超过C,并且总价值最大?
问题建模
输入:物品数量n,各物品价值pi,背包容量C
输出:最优价值bestp,最佳选择方案s[1…n]
目标函数:
约束条件:
问题分析
1. 定义问题的解空间,确定易于搜索的解空间结构
在 0/1 背包问题中,解空间可以描述为一个多维向量 (x1, x2, …, xn),其中:
- 每个变量 xi 属于 {0, 1},表示第 i 个物品是否被选中。
- 解空间的结构是一个 解向量的集合,例如:对于 4 个物品,解空间可以表示为 (x1, x2, x3, x4) 的所有组合。
这种解空间结构的确定,使得搜索可以基于向量的组合逐步进行,清晰地定义了解的每一步推进方式。
2. 设计限界函数,确定目标函数值的估算方法
目标是求解 0/1 背包问题的最大价值,属于一个 目标函数最大值问题。
- 限界函数定义:在计算解向量中目标函数值的上界时,设计一个 限界函数 ( ub ),用于估算子问题的最大潜在解。
- 目的:通过目标函数上界的限制,加速剪枝,避免遍历不可能获得更优解的分支。
限界函数的引入,使得对每个子问题的解搜索能够快速判断是否值得继续深入计算。
3. 基于限界函数的广度优先搜索
广度优先搜索是解决 0/1 背包问题的一种有效方法,结合限界函数能够显著提高搜索效率。
-
限界函数估算上界:
在搜索树的每一个结点,限界函数为其所有可能的解计算一个最大价值的上界,用于筛选有潜力的分支。 -
剪枝规则:
- 规则 1:若结点的限界函数值小于当前已知的最大价值(
maxvalue
),则直接剪枝,避免不必要的搜索。 - 规则 2:若结点的当前重量
cw
超过背包容量C
,则剪枝该分支,避免产生无效解。
- 规则 1:若结点的限界函数值小于当前已知的最大价值(
通过这些规则,可以减少大量不必要的搜索,显著提高算法效率。
实例
以下是基于 优先队列分支限界法求解 0/1 背包问题 的伪代码以及一个简单的例子,帮助你理解算法的核心逻辑。
伪代码
INPUT: w[1..n] - 物品重量数组p[1..n] - 物品价值数组C - 背包容量
OUTPUT:bestp - 最大价值x[1..n] - 最优解向量1. 按照单位重量价值 p[i]/w[i] 的非递增次序对物品排序
2. 初始化:bestp = 0 # 当前最大价值x[1..n] = [0, ..., 0] # 最优解向量将根结点加入优先队列 PT,初始 ub 为全体物品能装下的最大可能值
3. while PT 非空:3.1 从 PT 中取出优先级最高的结点 node3.2 if node.ub <= bestp:剪枝,跳过该结点else:if node 是叶子结点:if node.value > bestp:更新 bestp 和 x[1..n](通过回溯路径)else:左儿子:装入当前物品if 剩余重量 >= 0:计算左儿子的 ub 和 value,将左儿子加入 PT右儿子:不装当前物品计算右儿子的 ub 和 value,将右儿子加入 PT
4. 输出 bestp 和 x[1..n]
简单例子
输入数据
- 物品重量 ( w = [2, 3, 4] )
- 物品价值 ( p = [4, 5, 6] )
- 背包容量 ( C = 5 )
按单位重量价值排序
计算单位重量价值 ( p[i]/w[i] ):
- ( p[1]/w[1] = 4/2 = 2 )
- ( p[2]/w[2] = 5/3 \approx 1.67 )
- ( p[3]/w[3] = 6/4 = 1.5 )
排序后(单位价值降序):
- 重量 ( w = [2, 3, 4] )
- 价值 ( p = [4, 5, 6] )
执行过程:
- 初始化:
- 将根结点加入优先队列 ( PT ):
- 当前价值 ( value = 0 )
- 剩余容量 ( C = 5 )
- 初始
ub = 9
(尝试装入前两个物品的最大价值)
- 将根结点加入优先队列 ( PT ):
- 第一层(根结点展开):
- 左儿子(装入第一个物品):
- 当前价值 ( value = 4 )
- 剩余容量 ( C = 5 - 2 = 3 )
ub = 9
- 加入队列。
- 右儿子(不装入第一个物品):
- 当前价值 ( value = 0 )
- 剩余容量 ( C = 5 )
ub = 7
- 加入队列。
- 左儿子(装入第一个物品):
- 第二层(左儿子展开):
- 左儿子的左儿子(装入第二个物品):
- 当前价值 ( value = 4 + 5 = 9 )
- 剩余容量 ( C = 3 - 3 = 0 )
ub = 9
- 是叶子结点,更新
bestp = 9
,解向量 ( x = [1, 1, 0] )。
- 左儿子的右儿子(不装入第二个物品):
- 当前价值 ( value = 4 )
- 剩余容量 ( C = 3 )
ub = 7
- 加入队列。
- 左儿子的左儿子(装入第二个物品):
- 第三层(右儿子展开):
- 右儿子的左儿子(装入第二个物品):
- 当前价值 ( value = 0 + 5 = 5 )
- 剩余容量 ( C = 5 - 3 = 2 )
ub = 7
- 加入队列。
- 右儿子的右儿子(不装入第二个物品):
- 当前价值 ( value = 0 )
- 剩余容量 ( C = 5 )
ub = 6
- 加入队列。
- 右儿子的左儿子(装入第二个物品):
- 剪枝与结束:
- 队列中的所有结点
ub <= bestp = 9
,剪枝完成,算法结束。
- 队列中的所有结点
最终结果
- 最大价值:( bestp = 9 )
- 最优解:( x = [1, 1, 0] )(选择物品 1 和物品 2)
总结
- 本算法通过 限界函数(ub) 估算子树的最大可能值,从而剪枝,减少不必要的计算。
- 优先队列 优先处理潜在最优解的分支,结合剪枝极大提高效率。
- 例子中展示了完整过程,最终输出了最优价值和解向量。
旅行商问题
问题描述
问题建模
分支界限法解决问题
小结
简单例子开始理解
相关文章:

分支限界笔记
文章目录 概要整体架构流程基本概念分支限界法的定义核心思想 简单问题介绍问题:简单背包问题思考:暴力解法聪明的解法:分支限界法直观理解分支限界法的步骤0-1背包问题问题描述问题建模问题分析1. 定义问题的解空间,确定易于搜索…...
PHP Cookie
Cookie 是什么? cookie 常用于识别用户。cookie 是一种服务器留在用户计算机上的小文件。每当同一台计算机通过浏览器请求页面时,这台计算机将会发送 cookie。通过 PHP,您能够创建并取回 cookie 的值。 如何创建 Cookie? setcoo…...
Java后端面试场景题汇总
1.50 亿数据如何去重&排序? 如此大的数据集进行去重(例如50亿数据条目),我们需要考虑内存和存储空间的限制,同时还需要有一个高效的算法。一般来说,这样的数据量无法直接载入内存进行处理,因此需要采用磁盘存储和分布式处理的技术。主要有以下几种思路: 外部排序…...

【量化中的复权数据详解】
【复权计算方法】 股票会时不时的发生现金分红、送股等一系列股本变动,这会造成股价的非正常变化,导致我们不能直接通过股价来计算股票的涨跌幅。例如一个股票是10元,当他10送10的时候,它的价格会变成5元,但是我们并不…...
YOLO简史
【欢迎关注编码小哥,学习更多实用的编程方法和技巧】 YOLO历史 YOLO (You Only Look Once) 是一种流行的对象检测和图像分割模型,由华盛顿大学的 Joseph Redmon 和 Ali Farhadi 开发。YOLO 于 2015 年推出,因其高速和…...

低通滤波器,高通滤波器,公式
1 低通滤波器 :输出的是电容的电压 1 低通滤波器可以把低频信号上面的高频信号给滤掉 2 100hz正常通过 3 经过低通滤波器后,波形光滑,绿色波形。一致 4 电容充电速度跟不上输入信号的速度(因为加了电阻,限制了电流&…...

深入了解IPv6——光猫相关设定:DNS来源、DHCPv6服务、前缀来源等
光猫IPv6设置后的效果对比图: 修改前: 修改后: 一、DNS来源 1. 网络连接 来源: 从上游网络(如运营商)获取 IPv6 DNS 信息,通过 PPPoE 或 DHCPv6 下发。 特点: DNS 服务器地址直…...
前端国际化实战:从需求到落地的完整实践
"我们要开拓东南亚市场了!"产品经理小王兴奋地告诉我这个消息。作为技术负责人,我立刻意识到这意味着我们需要对整个系统进行国际化改造。说实话,虽然之前也做过一些多语言的项目,但面对一个正在运行的大型系统,国际化改造的挑战还是不小。 回想起上周的…...

React的状态管理库-Redux
核心思想:单一数据源、状态是只读的、以及使用纯函数更新状态。 组成部分 Store(存储) 应用的唯一状态容器,存储整个应用的状态树,使用 createStore() 创建。 getState():获取当前状态。dispatch(action)ÿ…...

【Android学习】RxJava
文章目录 资料连接1. Merge & Zip操作符: 合并数据源2. Map & FlapMap & ConcatMap & Buffer: 变换操作符3. retry & retryUntil & retryWhen : 错误处理操作符4. Transformer & Compose 转换符 资料连接 Android RxJava: 这是一份全面…...
Pycharm访问MySQL数据库·上
1.MySQL驱动模块Connector #导入数据库的驱动工具 import mysql.connector #连接数据库必备的条件 config {"host": "localhost","port": 3306,"user": "root","password": "888888","database&…...
【CUDA】CUBLAS
【CUDA】CUBLAS 在深入了解之前,提前运行预热(warmup)和基准测试(benchmark runs) 是获得准确执行时间的关键。如果不进行预热运行,cuBLAS 的首次运行会有较大的开销(大约 45 毫秒)…...
YOLOv8-ultralytics-8.2.103部分代码阅读笔记-predict.py
predict.py ultralytics\models\yolo\detect\predict.py 目录 predict.py 1.所需的库和模块 2.class DetectionPredictor(BasePredictor): 1.所需的库和模块 # Ultralytics YOLO 🚀, AGPL-3.0 licensefrom ultralytics.engine.predictor import BasePredicto…...

细说Flash存储芯片W25Q128FW和W25Q16BV
目录 一、Flash存储芯片W25Q128FW 1、W25Q128硬件接口和连接 2、存储空间划分 3、数据读写的原则 4、操作指令 (1)“写使能”指令 (2)“读数据”指令 (3)“写数据”指令 5、状态寄存器SR1 二、Fl…...

python爬虫--小白篇【爬取B站视频】
目录 一、任务分析 二、网页分析 三、任务实现 一、任务分析 将B站视频爬取并保存到本地,经过分析可知可以分为四个步骤,分别是: 爬取视频页的网页源代码;提取视频和音频的播放地址;下载并保存视频和音频&#x…...

Three.js入门-模型加载
Three.js 支持多种 3D 模型格式,每种格式有其独特的优势和适用场景。根据项目的需求,选择合适的格式可以提高开发效率和用户体验。下面将详细介绍几种常见的模型格式及其特点,并补充每种格式的典型使用场景。 支持的模型类型及特点 Three.j…...

ECharts实现数据可视化入门详解
文章目录 ECharts实现数据可视化入门详解一、引言二、基础配置1.1、代码示例 三、动态数据与交互2.1、代码示例 四、高级用法1、多图表组合1.1、在同一容器中绘制多个图表1.2、创建多个容器并分别初始化 ECharts 实例1.3、实现多图联动 五、总结 ECharts实现数据可视化入门详解…...
C++(举例说明类的实例化方式)
太多的信息会让你抓不住重点,下面通过间短的举例说明了类的几种实例化方式,熟悉以后再阅读代码的时候就能减少疑惑。 1.直接实例化:使用类名直接实例化对象 MyClass obj; 2.使用 new 关键字动态分配内存:使用 new 关键字来在堆上…...
LeetCode32. 最长有效括号(2024冬季每日一题 32)
给你一个只包含 ( 和 ) 的字符串,找出最长有效(格式正确且连续)括号子串的长度。 示例 1: 输入:s “(()” 输出:2 解释:最长有效括号子串是 “()” 示例 2: 输入:s “…...

Textfocals ——基于大言模型的用户驱动型文本改进工具让用户在审阅自己的写作时对其进行修改
概述 论文地址:https://arxiv.org/abs/2403.01055 大规模语言模型可以生成媲美专业作家撰写的文本。目前使用的对话技术主要有两种:一种是交互式(如 OpenAI 的 ChatGPT 和 Google 的 Gemini),另一种是预测性文本补全&…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...

Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
[USACO23FEB] Bakery S
题目描述 Bessie 开了一家面包店! 在她的面包店里,Bessie 有一个烤箱,可以在 t C t_C tC 的时间内生产一块饼干或在 t M t_M tM 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC,tM≤109)。由于空间…...

MySQL体系架构解析(三):MySQL目录与启动配置全解析
MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录,这个目录下存放着许多可执行文件。与其他系统的可执行文件类似,这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中,用…...

Copilot for Xcode (iOS的 AI辅助编程)
Copilot for Xcode 简介Copilot下载与安装 体验环境要求下载最新的安装包安装登录系统权限设置 AI辅助编程生成注释代码补全简单需求代码生成辅助编程行间代码生成注释联想 代码生成 总结 简介 尝试使用了Copilot,它能根据上下文补全代码,快速生成常用…...
02-性能方案设计
需求分析与测试设计 根据具体的性能测试需求,确定测试类型,以及压测的模块(web/mysql/redis/系统整体)前期要与相关人员充分沟通,初步确定压测方案及具体的性能指标QA完成性能测试设计后,需产出测试方案文档发送邮件到项目组&…...