- 浏览: 324892 次
- 性别:
- 来自: 西宁
文章分类
- 全部博客 (120)
- Java Thought (29)
- Java Pattern (4)
- Data Base (7)
- Algorithm Design (33)
- Linux (0)
- Mysql (2)
- Oracle (0)
- ConstructionDesign-架构 (5)
- Spring Platform (0)
- Tomcat (1)
- JavaScript (7)
- Web System (3)
- MS SQLServer (1)
- 软件哲学 (6)
- View (3)
- Java GUI (4)
- CSSDIV (7)
- CloudComputing (0)
- WebService (0)
- SystemOrProject (2)
- SOA (0)
- 互转共享 (3)
- 偶尔java习题 (0)
- Thinks with does (1)
最新评论
-
sassds:
佩服啊 高手
分享一款js特效 -
bhjackson:
学习啦,能否详细介绍下回溯的过程?O(∩_∩)O谢谢
分享回溯法- 找n个数中r个数的组合 -
zk7019311:
了解了解。。。。。
业务层代码复用的一点建议 -
lijie1819:
看到LZ的设计思想,感觉和抽象工厂模式有点相像。
业务层代码复用的一点建议 -
wjjcml1982:
酷毙了!楼主太强悍了!
分享一款js特效
1. 分支搜索算法
(1) 引入
用回溯算法解决问题时,是按照深度优先的策略在问题的状态空间中,尝试搜索可能的路径,不便于在搜索过程中对不同的解进行
比较,只能在搜索到所有解得情况下,才能通过比较确定哪个是最优解。这类问题更适合广度优先策略搜索,因为在扩展结点时,可以在
E-结点的各个子结点之间进行必要的比较,有选择的进行下一步扩展。这里的分支限界法就是一种较好的解决最优化问题的算法。
分支界限法是由"分支"策略和"限界"策略两部分组成。"分支"策略体现在对问题空间是按照广度优先策略进行搜索的;"限界"策略
是为了加速搜索速度而采用启发信息剪枝的策略。
(2) 深入
分支搜索法是一种在问题解空间上进行搜索尝试的算法。所谓"分支"是采用广度优先的策略,依次搜索E-结点的所有分支,也就是
所有的相邻结点。和回溯法一样,在生成的结点中,抛弃那些不满足约束条件(或者说不可能导致最优可行解)的结点,其余结点加入到活结
点表。然后从表中选择下一个结点作为下一个E-结点,继续搜索。
(3) 分类
选择下一个E-结点的方式不同,会出现几种不同的分支搜索方式。
1> FIFO 搜索
先进先出(FIFO)搜索算法要依赖"队列"做基本的数据结构。一开始,根结点是唯一的活结点,根结点入队。
从活结点队列中取出根结点后,作为当前扩展结点。对当前扩展结点,先从左到右地产生它的所有儿子,用约束条件检查,
把所有满足约束条件的儿子加入到活结点队列中。再从活结点表中取出队首结点(队中最先进来的结点)为当前扩展结点,
......,直到找到一个解或活结点队列为空为止。
2> LIFO搜索
后进先出(LIFO)搜索算法要依赖"栈"做基本的数据结构。一开始,根结点入栈。从栈中弹出一个结点为当前扩展结点。对当前
扩展结点,先从左到右地产生它的所有儿子,用约束条件检查,把所有满足约束函数的儿子入栈,再从栈中弹出一个结点(栈中最后进来
的结点)为当前扩展结点,......,直到找到一个解或栈空为止。
3> 优先队列式搜索
为了加速搜索的进程,应采用有效的方式选择E-结点进行扩展。优先队列式搜索,对每一个结点计算一个优先级,并根据这些
优先级,从当前活结点表中优先选择一个优先级最高(最有利)的结点作为扩展结点,使得搜索朝着解空间树上最优解的分支推进,以便尽
快找到一个最优解。
2. 用FIFO分支搜索算法求解最优解
(1) 问题描述:
有两艘船和需要装运的n个货箱,第一艘船的载重量是c1,第二艘船的载重量是c2,wi是货箱的质量,且w1+w2+...+wn <= c1+c2.
希望确定是否有一种可将所有n个货箱全部装船的方法。若有的话,找出该方法。
(2) 举例描述:
当n=3,c1=c2=50,w=[10,40,40]时,可将货箱1、2装到第一艘船上,货箱3装到第二艘船上。
但是如果w=[20,40,40],则无法将货箱全部装船。由此可知问题可能有解,可能无解,也可能有多解。
(3) 问题分析
虽然是关于两艘船的问题,其实只讨论一艘船的最大装载问题即可。因为当第一艘船的最大装载为bestw时,
若w1+w2+...+wn-bestw <= c2,则可以确定一种解,否则问题就无解。这样的问题转化为第一艘船的最大装载问题。
(4) 算法设计
转化为一艘船的最优化问题后, 问题的解空间为一个子集树。也就是算法要考虑所有物品取、舍情况的组合,
n个物品的取舍组合共有2的n次方个分支。
1> 和回溯算法的思想一样,用FIFO分支搜索所有的分支,并记录已搜索分支的最优解,搜索完子集树也就找出了问题的解。
2> 要想求出最优解,必须搜索到叶结点,所以要记录数的层次。当层次为n+1时,搜索完全部叶结点,算法结束。
3> 分支搜索过程中活结点的"层"是需要标识的,否则入队后无法识别结点所在的层。每处理完一层让"-1"入队,以此来标识
"层",并用变量i来记录当前层。
4> 每个活结点要记录当前船的装载量。
3. Java代码:
(1) 引入
用回溯算法解决问题时,是按照深度优先的策略在问题的状态空间中,尝试搜索可能的路径,不便于在搜索过程中对不同的解进行
比较,只能在搜索到所有解得情况下,才能通过比较确定哪个是最优解。这类问题更适合广度优先策略搜索,因为在扩展结点时,可以在
E-结点的各个子结点之间进行必要的比较,有选择的进行下一步扩展。这里的分支限界法就是一种较好的解决最优化问题的算法。
分支界限法是由"分支"策略和"限界"策略两部分组成。"分支"策略体现在对问题空间是按照广度优先策略进行搜索的;"限界"策略
是为了加速搜索速度而采用启发信息剪枝的策略。
(2) 深入
分支搜索法是一种在问题解空间上进行搜索尝试的算法。所谓"分支"是采用广度优先的策略,依次搜索E-结点的所有分支,也就是
所有的相邻结点。和回溯法一样,在生成的结点中,抛弃那些不满足约束条件(或者说不可能导致最优可行解)的结点,其余结点加入到活结
点表。然后从表中选择下一个结点作为下一个E-结点,继续搜索。
(3) 分类
选择下一个E-结点的方式不同,会出现几种不同的分支搜索方式。
1> FIFO 搜索
先进先出(FIFO)搜索算法要依赖"队列"做基本的数据结构。一开始,根结点是唯一的活结点,根结点入队。
从活结点队列中取出根结点后,作为当前扩展结点。对当前扩展结点,先从左到右地产生它的所有儿子,用约束条件检查,
把所有满足约束条件的儿子加入到活结点队列中。再从活结点表中取出队首结点(队中最先进来的结点)为当前扩展结点,
......,直到找到一个解或活结点队列为空为止。
2> LIFO搜索
后进先出(LIFO)搜索算法要依赖"栈"做基本的数据结构。一开始,根结点入栈。从栈中弹出一个结点为当前扩展结点。对当前
扩展结点,先从左到右地产生它的所有儿子,用约束条件检查,把所有满足约束函数的儿子入栈,再从栈中弹出一个结点(栈中最后进来
的结点)为当前扩展结点,......,直到找到一个解或栈空为止。
3> 优先队列式搜索
为了加速搜索的进程,应采用有效的方式选择E-结点进行扩展。优先队列式搜索,对每一个结点计算一个优先级,并根据这些
优先级,从当前活结点表中优先选择一个优先级最高(最有利)的结点作为扩展结点,使得搜索朝着解空间树上最优解的分支推进,以便尽
快找到一个最优解。
2. 用FIFO分支搜索算法求解最优解
(1) 问题描述:
有两艘船和需要装运的n个货箱,第一艘船的载重量是c1,第二艘船的载重量是c2,wi是货箱的质量,且w1+w2+...+wn <= c1+c2.
希望确定是否有一种可将所有n个货箱全部装船的方法。若有的话,找出该方法。
(2) 举例描述:
当n=3,c1=c2=50,w=[10,40,40]时,可将货箱1、2装到第一艘船上,货箱3装到第二艘船上。
但是如果w=[20,40,40],则无法将货箱全部装船。由此可知问题可能有解,可能无解,也可能有多解。
(3) 问题分析
虽然是关于两艘船的问题,其实只讨论一艘船的最大装载问题即可。因为当第一艘船的最大装载为bestw时,
若w1+w2+...+wn-bestw <= c2,则可以确定一种解,否则问题就无解。这样的问题转化为第一艘船的最大装载问题。
(4) 算法设计
转化为一艘船的最优化问题后, 问题的解空间为一个子集树。也就是算法要考虑所有物品取、舍情况的组合,
n个物品的取舍组合共有2的n次方个分支。
1> 和回溯算法的思想一样,用FIFO分支搜索所有的分支,并记录已搜索分支的最优解,搜索完子集树也就找出了问题的解。
2> 要想求出最优解,必须搜索到叶结点,所以要记录数的层次。当层次为n+1时,搜索完全部叶结点,算法结束。
3> 分支搜索过程中活结点的"层"是需要标识的,否则入队后无法识别结点所在的层。每处理完一层让"-1"入队,以此来标识
"层",并用变量i来记录当前层。
4> 每个活结点要记录当前船的装载量。
3. Java代码:
package boke.branchlimit; /** * 分支限界FIFO * * @since jdk1.6 * @author 毛正吉 * @version 1.0 * @date 2010.05.25 * */ public class BranchLimitFIFOSearch { /** * @param args */ public static void main(String[] args) { // n个货箱 int n = 3; // 第一艘船的载重量 float c1 = 50; // 第二艘船的载重量 float c2 = 50; // 货箱质量数组 float[] w = { 0, 10, 40, 40 }; // 测试例子 BranchLimitFIFOSearch bfis = new BranchLimitFIFOSearch(n, c1, c2, w); // 所有货箱的重量之和 float s = bfis.getS(); if (s <= c1 || s <= c2) { System.out.println("need only one ship!"); } if (s > c1 + c2) { System.out.println("no solution!"); return; } bfis.maxLoading(c1); float bestw = bfis.getBestw(); if (s - bestw <= c2) { System.out.println("The first ship loading " + bestw); System.out.println("The second ship loading " + (s - bestw)); } else { System.out.println("no solution!"); } } private int n; // n个货箱 private float c1; // 第一艘船的载重量 private float c2; // 第二艘船的载重量 private float bestw; // 第一艘船的最大装载 private float ew = 0; // 当前船的装载量 private float[] w; // 货箱质量数组 private float s = 0; // 所有货箱的重量之和 private MyQueue mq = new MyQueue(); // FIFO队列 /** * 构造方法 * * @param _n * @param _c1 * @param _c2 * @param _w */ public BranchLimitFIFOSearch(int _n, float _c1, float _c2, float[] _w) { n = _n; c1 = _c1; c2 = _c2; w = _w; for (float f : _w) { s += f; } } /** * 最优装载值 * * @param c */ public float maxLoading(float c) { mq.put(new Float(-1)); // 初始化结点队列,标记分层 int i = 1; // E-结点的层 ew = 0; // 当前船的装载量 bestw = 0; // 目前的最优值 while (!mq.empty()) { // 搜索子集空间树 if (ew + w[i] <= c) { // 检查E-结点的左孩子,货箱i是否可以装载 addLiveNode(ew + w[i], i); // 货箱i可以装载 } addLiveNode(ew, i); // 右孩子总是可行的,不装载货物i ew = (Float) mq.get(); // 取下一个结点 if (ew == -1) { // 到达层的尾部 if (mq.empty()) { return bestw; } mq.put(new Float(-1)); ew = (Float) mq.get(); // 取下一个结点 i++; // ew的层 } } return bestw; } /** * 入队 * * @param wt * @param i */ public void addLiveNode(float wt, int i) { if (i == n) { // 是叶子 if (wt > bestw) { bestw = wt; } } else { // 不是叶子 mq.put(new Float(wt)); } } public int getN() { return n; } public void setN(int n) { this.n = n; } public float getC1() { return c1; } public void setC1(float c1) { this.c1 = c1; } public float getC2() { return c2; } public void setC2(float c2) { this.c2 = c2; } public float getBestw() { return bestw; } public void setBestw(float bestw) { this.bestw = bestw; } public float getEw() { return ew; } public void setEw(float ew) { this.ew = ew; } public float getS() { return s; } public void setS(float s) { this.s = s; } } ------------------------------------------ package boke.branchlimit; import java.util.LinkedList; /** * 自定义队列 * * @since jdk1.6 * @author 毛正吉 * @version 1.0 * @date 2010.05.25 * */ public class MyQueue { private LinkedList ll = new LinkedList(); /** * 入队 * * @param o */ public void put(Object o) { ll.addLast(o); } /** * 出队 * * @return */ public Object get() { return ll.removeFirst(); } /** * 队是否为空 * * @return */ public boolean empty() { return ll.isEmpty(); } }
发表评论
-
开散列的简单模拟(一)
2010-06-28 08:33 18221. 散列 散列有两种 ... -
递归和动态规划构造两个字符序列的最长公共字符子序列
2010-06-28 08:28 4494应je朋友要求,所以翻开以前的算法题目,整理了以下,给 ... -
最大公约数的应用 - 分享
2010-06-25 08:08 18541.先看一家大公司笔试题 数组中有n个数据,要将它们顺 ... -
信息数字化解逻辑题分享
2010-06-21 08:09 12561. 前提条件: 将逻辑题目中的信息用数字化描述。 ... -
递归算法分析-分享
2010-06-19 16:09 15921. 深入认识递归 (1) 递 ... -
非递归算法分析实例分享
2010-06-18 15:47 10561 仅仅依赖于问题规模的时间复杂度 (1) 例1: 交换i和 ... -
NP完全性问题
2010-06-18 14:02 7014在学习算法设计与分析时,经常会提到NP完全性问题,到底 ... -
算法分析精述分享
2010-06-18 12:03 8721. 算法分析的评价体系 评价算法的三条主要标准是: ... -
贪婪策略算法的总结分享
2010-06-11 08:30 60701. 贪婪算法描述 贪婪算法又叫登山法,它的根本思想是 ... -
带权有向图 - 边上权值非负情形的单源最短路径问题
2010-06-07 08:57 26791. 问题描述: 给定 ... -
是否很久没抽象和逻辑了呢? DODO它吧(很基础)四
2010-06-07 08:54 137021. 工作分配问题。 ... -
是否很久没抽象和逻辑了呢? DODO它吧(很基础)三
2010-06-07 08:53 109317. 字符统计问题。 编写一个算法,统计在一个输入 ... -
是否很久没抽象和逻辑了呢? DODO它吧(很基础)二
2010-06-07 08:47 13668. 数字迷问题。 A B C ... -
是否很久没抽象和逻辑了呢? DODO它吧(很基础)一
2010-06-07 08:38 11801. 线程问题。 设计4个线程,其中两个线程每次对j增加 ... -
是否很久没抽象和逻辑了呢? DODO它吧(很基础)
2010-06-07 08:37 18811. 线程问题。 设计 ... -
Java快速排序算法整理(二)
2010-05-31 14:04 1033package boke.sort; /** * 快 ... -
Java快速排序算法整理(一)
2010-05-31 13:39 657package boke.sort; /** * 快 ... -
Java最小堆实现
2010-05-31 08:29 58521.堆结点 package boke.heap1; /* ... -
Java插入排序代码整理
2010-05-28 14:44 1252package boke.sort; /** * 插 ... -
Java选择排序代码整理
2010-05-28 14:37 1505package boke.sort; /** * 选 ...
相关推荐
算法设计与分析用分支限界法解决最优装载问题,,,
C++实现的分支限界的最优装载问题 可以运行
【最优装载问题与分支限界法】 最优装载问题是一个经典的组合优化问题,旨在寻找最佳的装载方案,使得一组集装箱能够合理地分配到两艘载重量有限的轮船上,以达到最大的装载重量。在这个问题中,每艘轮船的载重量...
java实现的装载问题-分支限界算法是一种有效的解决方案,可以正确地解决装载问题,并输出最优的解决方案。该算法可以应用于物流行业、manufacturing行业等领域,对解决实际问题具有重要的参考价值。
【最优装载问题与分支限界法】 最优装载问题是一个经典的组合优化问题,它涉及到如何将一组物品(在这里是集装箱)分配到有限的资源(两艘船)中,以达到最大的装载效率或最小化某些指标。在这个实验中,目标是找到...
分支限界法是一种在计算机科学中用于解决优化问题的有效算法,尤其在面对组合优化问题时。这种方法基于广度优先搜索(BFS)或优先级队列的策略来探索解空间树,逐步剪枝掉那些不可能产生最优解的分支,从而减少搜索...
分支限界法中的优先队列式分支限界法解装载问题
采用队列分支界限法实现最优装载,并对算法做了改进,其中用到了c++模版库
#### 一、分支限界法概览 **分支限界法**是一种在问题求解过程中采用广度优先搜索或最小耗费(最大效益)优先搜索方式的搜索方法。它通常用于求解优化问题,在解空间树中寻找最优解。 #### 二、分支限界法的基本...
在队列式分支限界法中,算法通过检查当前扩展节点的左右儿子节点来解决装载问题。如果左儿子节点(代表将下一个集装箱放入第一艘船)是可行的,则将其加入活跃节点队列;之后,无论左儿子节点是否可行,都将右儿子...
### 算法设计与分析:回溯法与分支限界法 #### 一、回溯法 **1.0-1背包问题** - **问题描述**:设有n种物品和一个容量为C的背包,每种物品都有固定的重量Wi和价值Vi。目标是从这n种物品中选择一些放入背包,使得...
总之,分支限界法是一种强大的算法工具,适用于解决离散优化问题,如旅行商问题、装载问题等。其关键在于有效的节点选择策略和限界函数的设计,以确保能够高效地搜索到全局最优解。通过合理地应用分支限界法,可以...
在算法的角度,最优装载问题可以通过多种方法解决,包括贪心算法、动态规划、回溯法、分支限界法等。这里主要介绍其中的动态规划方法,因为它是解决这类问题的一种常用且有效的方法。 动态规划(Dynamic ...
《装载问题(分支限界法)报告》详细解读 装载问题是一个经典的组合优化问题,它涉及到如何有效地将一组物品分配到有限的资源中,以达到某种优化目标。在这个实验报告中,我们关注的是如何利用分支限界法来解决装载...
分支限界法在这种问题中的应用,通常涉及到建立解空间树,每个节点代表一种装载方案,通过计算每个节点的价值和当前的装载情况,不断扩展节点直到找到最优解。 6.3 单源最短路径问题 单源最短路径问题是从图中的一...
### 最优装载问题详解 #### 一、问题背景与定义 **最优装载问题**是一种经典的计算机科学中的优化问题。该问题通常涉及一个或多个约束条件下的最大化或最小化目标函数。在这个特定的情境中,我们需要考虑如何将一...
分支限界法与回溯法不同,它不仅关注找到满足约束条件的解,更专注于找到其中最优的一个。以下是关于分支限界法的详细说明: 1. **基本思想**: - **求解目标**:分支限界法的目标是在解空间树中找到满足条件的最...
分支限界法在此类问题中可以帮助我们高效地找到最优装载组合,避免过度搜索。 综上所述,分支限界法是解决优化问题的强大工具,尤其适用于寻找全局最优解。它结合了广度优先或优先级搜索策略,有效地剪枝以减少无用...
《分支限界法案例算法分析》 分支限界法是一种重要的搜索算法,广泛应用于解决优化问题,特别是...在实际应用中,如装载问题、0-1背包问题、最大团问题和旅行售货员问题等,分支限界法都能展现出其强大的求解能力。