算法知识点整理——第6章 分支限界法

本文详细介绍了分支限界法与回溯法的区别,强调分支限界法在寻找一个解或最优解上的应用。讨论了队列式和优先队列式两种分支限界法,并通过0-1背包问题、TSP问题、单源最短路径、装载问题、布线问题、八数码难题和分配问题等多个实例展示了分支限界法的具体运用和优化策略,如提前剪枝和优先拓展策略。
第 6 章 分支限界法
1.分支限界 VS 回溯
回溯:求出满足问题的所有解,深度优先
分支限界:求出满足问题的一个解(或者是找出问题中的一个最优解),广度优先

都要先定义解空间结构
 
两者对当前扩展节点所采取的扩展方式不同。


2.分支限界法常见方式
队列式分支限界法(FIFO)
优先队列式分支限界法(可以理解为OS中的优先级,一般是代价越低、或者是收益越多)



3.0-1背包
队列式FIFO分支限界法
就是数构中的广度优先算法
优先队列式分支限界法
用一个极大堆来存储结果(也就是价值越多且重量不超过的放在最上面,可以被优先扩展)


4.TSP问题
队列式FIFO分支限界法
依次
使用 C 或 C语言实现游戏“迷失的魔杖”。程序实现的过程中,对课程中学习的c分治法、贪心法、回溯法、分支限界法、随机算法等主要知识点进行整理,并根据实际情况综合运用,加深对知识点的理解。三个关卡不能用同样的算法,随机不能单独用,但是要嵌入进三个关卡中,随机算法要使用舍伍德算法,必须第一关过了才第二关,第一关分治法,第二关tsp问题,分支限界法,第三关,会议室问题,回溯法,也可以用c语言进行封装,但不要用c++封装,我没学,最好多文件,不要全写在一个.cpp.h里面,后期不好改 游戏分为三个单元,各游戏单元功能及要求包括: (1) 寻找地图:五块魔杖碎片分散在不同地点,记载着所有碎片位置的地图 藏在魔法学院一本魔法书的夹层中,正常情况下每本魔法书重量相同, 藏有地图则书的重量会增加。游戏目标:快速找到藏有地图的魔法书; (2) 集齐碎片:地图显示五块碎片分处于不同地点,合成魔杖的魔法炉在城 堡主楼。游戏目标:从魔法学院出发快速集齐所有碎片,并回到城堡主 楼; (3) 合成魔杖:每块碎片需要使用魔法炉打磨后才可以合成为魔杖。每块碎 片的长度与重量不同,魔法炉每次只能打磨一块碎片,初次开启魔法炉 需要 1 天的准备时间,打磨一块碎片后,如果下一块碎片的长度及重量 均不小于刚刚打磨的这块碎片,则魔法炉可以继续打磨,否则,若下一 块碎片的长度或重量小于刚刚打磨的这块碎片,则魔法炉再需要 1 天的 准备时间才能打磨下一块碎片。游戏目标:以最短时间合成魔杖。 然后我需要一些提示性的语句,比如按什么键进行哪一步,然后过了第一关就提示你过关了,然后进入第二关,还有关卡里面要含有随机算法,比如这里五块魔杖碎片分散在不同地点就要用随机算法,地图显示五块碎片分处于不同地点这里用随机算法,只能用舍伍德算法,在这个我改进的基础上,再结合我上面发的,再给我一个游戏完整的代码 你先理解一下,我还没讲完具体的游戏要求
10-22
使用 C 或 C++语言实现游戏“迷失的魔杖”。程序实现的过程中,对课程中学习的c++分治法、贪心法、回溯法、分支限界法、随机算法等主要知识点进行整理,并根据实际情况综合运用,加深对知识点的理解。三个关卡不能用同样的算法,随机不能单独用,必须第一关过了才第二关,第一关分治法,第二关tsp问题,分支限界法或回溯法第三关,会议室问题,贪心法,也可以用c语言进行封装,但不要用c++封装,我没学,最好多文件,不要全写在一个.cpp.h里面,后期不好改 游戏分为三个单元,各游戏单元功能及要求包括: (1) 寻找地图:五块魔杖碎片分散在不同地点,记载着所有碎片位置的地图 藏在魔法学院一本魔法书的夹层中,正常情况下每本魔法书重量相同, 藏有地图则书的重量会增加。游戏目标:快速找到藏有地图的魔法书; (2) 集齐碎片:地图显示五块碎片分处于不同地点,合成魔杖的魔法炉在城 堡主楼。游戏目标:从魔法学院出发快速集齐所有碎片,并回到城堡主 楼; (3) 合成魔杖:每块碎片需要使用魔法炉打磨后才可以合成为魔杖。每块碎 片的长度与重量不同,魔法炉每次只能打磨一块碎片,初次开启魔法炉 需要 1 天的准备时间,打磨一块碎片后,如果下一块碎片的长度及重量 均不小于刚刚打磨的这块碎片,则魔法炉可以继续打磨,否则,若下一 块碎片的长度或重量小于刚刚打磨的这块碎片,则魔法炉再需要 1 天的 准备时间才能打磨下一块碎片。游戏目标:以最短时间合成魔杖。
10-21
分支限界法解决 01 背包问题的基本思路如下: 首先考虑暴力法,对所有情况进行穷举,由于每件物品有选和不选两种情况,所以解空间是二叉树。接着对所有穷举出的情况进行筛选,先删除容量超过背包的情况,再在剩下的情况中选择价值最大的情况,并且可以对该过程进行优化[^1]。 设有 `n` 个物体和一个背包,物体 `i` 的重量为 `wi` 价值为 `pi`,背包的载荷为 `M`,若将物体 `i`(`1 <= i <= n`)装入背包,则有价值为 `pi`,目标是找到一个方案,使得能放入背包的物体总价值最高[^2]。 以下是使用 Java 实现分支限界法解决 01 背包问题的示例代码: ```java import java.util.*; class Node implements Comparable<Node> { int level; int profit; int weight; int bound; public Node(int level, int profit, int weight) { this.level = level; this.profit = profit; this.weight = weight; } @Override public int compareTo(Node other) { return other.bound - this.bound; } } public class KnapsackBranchAndBound { static int n; static int capacity; static int[] weights; static int[] profits; static int bound(Node u) { if (u.weight >= capacity) { return 0; } int profitBound = u.profit; int j = u.level + 1; int totalWeight = u.weight; while ((j < n) && (totalWeight + weights[j] <= capacity)) { totalWeight += weights[j]; profitBound += profits[j]; j++; } if (j < n) { profitBound += (capacity - totalWeight) * (profits[j] / weights[j]); } return profitBound; } static int knapsack() { PriorityQueue<Node> pq = new PriorityQueue<>(); Node u, v; u = new Node(-1, 0, 0); u.bound = bound(u); pq.add(u); int maxProfit = 0; while (!pq.isEmpty()) { u = pq.poll(); if (u.bound > maxProfit) { v = new Node(u.level + 1, u.profit + profits[u.level + 1], u.weight + weights[u.level + 1]); if (v.weight <= capacity && v.profit > maxProfit) { maxProfit = v.profit; } v.bound = bound(v); if (v.bound > maxProfit) { pq.add(v); } v = new Node(u.level + 1, u.profit, u.weight); v.bound = bound(v); if (v.bound > maxProfit) { pq.add(v); } } } return maxProfit; } public static void main(String[] args) { n = 4; capacity = 10; weights = new int[]{2, 3, 4, 5}; profits = new int[]{3, 4, 5, 6}; int result = knapsack(); System.out.println("最大价值: " + result); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值