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

「日拱一码」046 分支定界算法

目录

分支定界算法基本原理

算法基本步骤

应用场景

代码示例——0-1背包问题

算法优化技巧


分支定界(Branch and Bound)是一种用于解决组合优化问题的系统化方法,特别适用于离散优化问题

分支定界算法基本原理

分支定界算法通过以下两个核心操作来系统地搜索解空间:

  1. 分支(Branch): 将问题分解为更小的子问题
  2. 定界(Bound): 计算子问题的上下界,剪除不可能包含最优解的分支

算法基本步骤

  1. 初始化: 创建根节点表示原始问题,设置初始上下界
  2. 选择节点: 从活动节点列表中选择一个节点进行处理
  3. 分支: 将选中的节点分解为若干子节点
  4. 计算界限: 为每个子节点计算上下界
  5. 剪枝: 删除不可能包含最优解的子节点
  6. 终止条件: 当所有节点都被处理或满足停止条件时终止

应用场景

分支定界算法常用于以下问题:

  • 旅行商问题(TSP)
  • 整数规划
  • 背包问题
  • 调度问题
  • 图划分问题

代码示例——0-1背包问题

下面以经典的0-1背包问题为例,展示分支定界算法的实现:

import heapqclass Node:def __init__(self, level, profit, weight, bound, items):self.level = level  # 当前处理的物品层级self.profit = profit  # 当前总价值self.weight = weight  # 当前总重量self.bound = bound  # 价值上界self.items = items  # 包含的物品索引列表# 定义比较操作符用于优先队列def __lt__(self, other):return self.bound > other.bound  # 按bound从大到小排序def bound(node, n, W, items):"""计算节点的价值上界"""if node.weight >= W:return 0profit_bound = node.profitj = node.level + 1total_weight = node.weight# 贪心添加物品直到无法再添加完整物品while j < n and total_weight + items[j][1] <= W:total_weight += items[j][1]profit_bound += items[j][0]j += 1# 如果还有剩余空间,添加部分物品if j < n:profit_bound += (W - total_weight) * (items[j][0] / items[j][1])return profit_bounddef knapsack_branch_and_bound(W, wt, val, n):"""分支定界解决0-1背包问题W: 背包容量wt: 物品重量列表val: 物品价值列表n: 物品数量"""# 按单位价值排序(降序)items = sorted([(val[i], wt[i], i) for i in range(n)],key=lambda x: x[0] / x[1], reverse=True)# 创建优先队列queue = []# 创建根节点root = Node(-1, 0, 0, 0, [])root.bound = bound(root, n, W, items)heapq.heappush(queue, root)max_profit = 0best_items = []while queue:current = heapq.heappop(queue)# 如果当前节点的bound小于已知最大收益,则跳过if current.bound < max_profit:continue# 到达叶子节点if current.level == n - 1:continue# 处理下一物品next_level = current.level + 1next_val, next_wt, idx = items[next_level]# 分支1: 包含下一物品left_weight = current.weight + next_wtleft_profit = current.profit + next_valleft_items = current.items + [idx]if left_weight <= W and left_profit > max_profit:max_profit = left_profitbest_items = left_items.copy()left_bound = bound(Node(next_level, left_profit, left_weight, 0, left_items),n, W, items)if left_bound > max_profit:left_node = Node(next_level, left_profit, left_weight, left_bound, left_items)heapq.heappush(queue, left_node)# 分支2: 不包含下一物品right_bound = bound(Node(next_level, current.profit, current.weight, 0, current.items),n, W, items)if right_bound > max_profit:right_node = Node(next_level, current.profit, current.weight, right_bound, current.items)heapq.heappush(queue, right_node)return max_profit, [items[i][2] for i in best_items]# 示例使用
if __name__ == "__main__":W = 10  # 背包容量wt = [2, 3, 4, 5]  # 物品重量val = [3, 4, 5, 6]  # 物品价值n = len(val)  # 物品数量max_profit, selected_items = knapsack_branch_and_bound(W, wt, val, n)print("最大价值:", max_profit)print("选择的物品索引:", sorted(selected_items))print("选择的物品重量:", [wt[i] for i in selected_items])print("选择的物品价值:", [val[i] for i in selected_items])# 最大价值: 13
# 选择的物品索引: [0, 1, 3]
# 选择的物品重量: [2, 3, 5]
# 选择的物品价值: [3, 4, 6]

算法优化技巧

  1. 启发式选择规则: 优先处理更有希望的分支
  2. 预处理: 通过排序或预处理减少搜索空间
  3. 并行计算: 不同分支可以并行处理
  4. 缓存中间结果: 存储已计算的分支结果避免重复计算
  5. 混合算法: 结合其他算法如动态规划进行优化

分支定界算法的时间复杂度在最坏情况下是指数级的,因为可能需要遍历整个解空间。但在实际应用中,通过有效的剪枝可以大大减少搜索空间

    http://www.dtcms.com/a/320256.html

    相关文章:

  1. Airflow 入门案例教程
  2. 前端性能优化:从请求到资源的精细调控
  3. 【第9话:感知算法基础1】深度学习神经网络模型基础知识概念入门简介
  4. 批量获取亚马逊商品SKU商品规格调用流程
  5. 【实时Linux实战系列】基于实时Linux的高频交易系统构建
  6. Python 常用内置高阶函数
  7. RabbitMQ面试精讲 Day 15:RabbitMQ故障转移与数据恢复
  8. C++ min循环超超超详细指南
  9. WFP DNS 域名解析
  10. 深入理解C++模板进阶:非类型参数、特化与分离编译
  11. Linux节点创建API与路径对应关系
  12. AI日报0807 | GPT-5或今晚1点来袭:四大版本全曝光
  13. 什么是 TDengine IDMP?
  14. Disruptor 消费者核心:BatchEventProcessor解析
  15. 告别复杂配置!cpolar让Prometheus监控突破网络限制
  16. 【42】【OpenCV C++】 计算图像某一列像素方差 或 某一行像素的方差;
  17. 嵌入式开发硬件——单片机
  18. 【列出指定时间段内所有的下单产品】
  19. 数据结构(循环顺序队列)
  20. RAGAS:检索增强生成系统的无参考评估框架与技术解析
  21. 2025年华数杯C题超详细解题思路
  22. 哈希表原理与实现全解析
  23. 天道20金句
  24. Moses工具的配置和小语种平行语料训练SMT完整实现
  25. 大模型 Transformer模型(上)
  26. Java集合的遍历方式(全解析)
  27. 力扣经典算法篇-46-阶乘后的零(正向步长遍历,逆向步长遍历)
  28. BGP笔记整理
  29. Maven高级:继承与聚合实战指南
  30. RS485转Profibus网关在QDNA钠离子分析仪与300PLC通信中的应用解析