分支与限界货物装载问题.doc
《分支与限界货物装载问题.doc》由会员分享,可在线阅读,更多相关《分支与限界货物装载问题.doc(16页珍藏版)》请在冰豆网上搜索。
分支与限界:
货物装载问题
课程名称:
**************
院系:
************************
学生姓名:
******
学号:
************
专业班级:
*****************************
指导教师:
*******
2013年12月27日
第16页共16页
分支与限界:
货物装载问题
摘要:
在现实生活中,我们会经常遇见货物装载问题,如何解决货物装载问题,获取利润的最大化,花费最少的而得到更多的东西,是人们一直都要考虑的问题。
在广泛的解决问题中,人们一般采用分支限界算法解决这样的问题。
分支限界法是由分支策略和限界策略两部分组成的。
分枝定界法是一个用途十分广泛的算法,运用这种算法的技巧性很强,不同类型的问题解法也各不相同。
该算法在具体执行时,把全部可行的解空间不断分割为越来越小的子集(称为分支),并为每个子集内的解的值计算一个下界或上界(称为定界)。
在每次分支后,对凡是界限超出已知可行解值那些子集不再做进一步分支。
这样,解的许多子集(即搜索树上的许多结点)就可以不予考虑了,从而缩小了搜索范围。
该算法在具体执行时,把全部可行的解空间不断分割为越来越小的子集(称为分支),并为每个子集内的解的值计算一个下界或上界(称为定界)。
在每次分支后,对凡是界限超出已知可行解值那些子集不再做进一步分支。
这样,解的许多子集(即搜索树上的许多结点)就可以不予考虑了,从而缩小了搜索范围。
分支策略体现在对问题空间是按广度优先的策略进行搜索,限界策略是为了加速搜索速度而采用启发信息剪枝的策略。
在分支限界法,经常采用的是分支搜索法,分支搜索法是一种在问题空间上进行搜索尝试的算法。
所谓分支是采用广度优先的策略,依次搜索E-结点的所有的分支,也就是所有的相邻结点。
和回溯法一样,在生成的节点中,抛弃那些不满足的约束条件的的结点,其余结点加入活结点表。
在分支搜索的算法中,人们经常会采用FIFO搜索和优先队列式搜索。
例题中采用的是轮船装载的问题,这是一个非常经典的分支限界算法的例题,通过这个例子的学习,将会理解并掌握分支限界货物装载的问题。
关键词:
分支限界法货物装载FIFO分支限界优先队列分支限界
目录
第一章绪论 4
1.1分支-界限算法的基本思想 4
1.2常见的两种分支界限算法 4
第二章货物装载问题 5
2.1问题描述 5
2.2问题分析 5
第三章优先队列式分支限界法解决货物装载问题 6
3.1算法设计 6
3.2数据结构设计 7
3.2.1程序流程图 7
3.2.2数据结构描述 7
3.2.3重要算法 8
3.3测试结果与分析 9
第四章基于队列式(FIFO)分支限界法解决货物装载问题 10
4.1算法设计 10
4.2数据结构设计 10
4.2.1程序流程图 11
4.2.2数据结构描述和算法 11
4.3测试结果与分析 13
第五章结论 14
参考文献 15
第一章绪论
1.1分支-界限算法的基本思想
分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。
在分支限界法中,每一个活结点只有一次机会成为扩展结点。
活结点一旦成为扩展结点,就一次性产生其所有儿子结点。
在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。
此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。
这个过程一直持续到找到所需的解或活结点表为空时为止。
1.2常见的两种分支界限算法
队列式(FIFO)分支限界法按照队列先进先出(FIFO)原则选取下一个节点为扩展节点。
FIFO搜索算法要依赖“队”做基本的数据结构。
一开始根节点是唯一的活结点,根节点入队。
从活结点的对中取出艮结点后,作为当前扩展结点。
对当前扩展结点,先从左到右地产生它的所有儿子,用约束条件检查,把所有满足约束函数的儿子加入到活结点队列中。
再从活结点表中取出队首结点为当前扩展结点。
优先队列式分支限界法按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。
优先队列式搜索,对每一个活结点计算一个优先级,并根据这些优先级,从当前活结点表中优先选择一个一个优先级最高的节点作为扩展结点,使搜索朝着解空间树上最优解的分支推进,以便尽快找出一个最优解。
第二章货物装载问题
2.1问题描述
有两艘船和需要装运的N个货箱,第一艘船的载重量是c1,第二艘船的载重量是c2,wi是货箱i的重量,且w1+w2+.....+wn<=c1+c2。
希望确定是否有一种可能将所有货箱全部装船的方法。
若有的话,找出该方法。
2.2问题分析
先看一个实例,当n=3,c1=c2=50,w={10,40,40}时,可将货箱1,2装到第一艘船上,货箱3装到第二艘船上。
但如果w={20,40,40},则无法将货箱全部装船。
有此可知问题可能有解,可能无解,也可能多解。
虽然是关于两艘船的问题,若w1+w2+w3+....wn-bestw<=c2则可能确定一个解,否则问题就无解。
这样的问题就转化为第一艘船的最大装载问题。
第三章优先队列式分支限界法解决货物装载问题
3.1算法设计
解装载问题的优先队列式分支限界法用最大优先队列存储活结点表。
活结点x在优先队列中的优先级定义为从根结点到结点x的路径所相应的载重量再加上剩余集装箱的重量之和。
优先队列中优先级最大的活结点成为下一个扩展结点。
优先队列中活结点x的优先级为x.uweight。
以结点x为根的子树中所有结点相应的路径的载重量不超过x.uweight。
子集树中叶结点所相应的载重量与其优先级相同。
因此在优先队列式分支限界法中,一旦有一个叶结点成为当前扩展结点,则可以断言该叶结点所相应的解即为最优解,此时终止算法。
通过实验,了解了分支限界法的基本思想。
掌握了利用优先队列式分支限界法实现具体的装载问题。
由于利用java.util包下的PriorityQueue代替算法中的最大堆,免去了编写实现最大堆的程序代码。
优先队列式分支限界法进行算法设计的要点如下:
(1)结点扩展方式:
无论是那种分支限界法,需要有一张活的结点表。
优先队列的分支限界法将活结点组成一个优先队列,并按优先队列中规定的结点优先选取最高的下一个结点成为当前扩展结点。
(2)结点优先级确定:
优先队列中的结点优先级长规定一个与该节点相关的数值w,w一般表示以该节点为根的子树的分支接近最优解的程度。
(3)优先队列组织:
结点优先级确定后,按结点优先级进行排序,就生成了优先队列。
排序算法的时间复杂度较高,考虑到搜索算法每次只扩展一个结点,数据结构中堆排序,适合这一特点且比较交换的次数最少。
此例采用最大堆来实现优先队列。
3.2数据结构设计
3.2.1程序流程图
图3-1优先队列限界法流程图
3.2.2数据结构描述
(1)要输出解的方案,在搜索过程中仍需要生成解结构树,其结点信息包括指向父结点的指针和标识物品取舍(或是父结点的左、右孩子)。
(2)堆结点包括结点优先级信息:
结点所在分支的装载上界uweight;堆中无法体现结点的层次信息(level),只能存储在结点中;
(3)由于扩展结点不是按层进行的,计算结点所在分支的装载上界时,要用数组变量r记录当前层以下的最大重量,这样可随时方便使用各层结点的装载上界。
3.2.3重要算法
HeapNodeH[1000];
structbbnode
{bbnode*parent;//父结点指针
intLChild;};//当且仅当是父结点的左孩子时,取值为1
structHeapNode
{bbnode*ptr;//活结点指针
floatuweight;//活结点的重量上限
intlevel;};
MaxLoading(floatc,intn,intbestx[])
{floatr[100],Ew,bestw=0;r[n]=0;
for(intj=n-1;j>0;j--)r[j]=r[j+1]+w[j+1];
inti=1;bbnode*E=0;Ew=0;//搜索子集空间树
while(i!
=n+1)//不在叶子上
{if(Ew+w[i]<=c)//可行的左孩子
{AddLiveNode(E,Ew+w[i]+r[i],1,i+1);}
if(bestwif(bestwDeleteMax(H,E);i=N.level;E=N.ptr;Ew=N.uweight-r[i-1];
}
for(intj=n;j>0;j--)
{bestx[j]=E->LChild;E=E->parent;}
returnEw;
}
AddLiveNode(floatwt,intlev,bbnode*E,intch)
{bbnode*b=newbbnode;
b->parent=E;
b->LChild=ch;
HeapNodeN;
N.uweight=wt;
N.level=lev;
N.ptr=b;
Insert(H,N);
}
3.3测试结果与分析
图3.2货物装载问题的解
由图可以看出,当输入货箱的个数为5时,第一艘船的载重量为50,第二艘船的载重量为70时,每个货箱的质量分别是12,14,16,20,20,得到如下图的结果。
第四章基于队列式(FIFO)分支限界法解决货物装载问题
4.1算法设计
将此问题转化为一艘船的最优化问题,问题的解空间为一个子集树。
也就是算法要考虑的所有物品的取、舍情况的组合,n个物品的取舍组合共2的N次个分支,搜索子集树是NP-复杂问题。
如下图所示,xi为1表示选取第i件物品,xi为0表示不选取第i件物品。
搜索结点3,时可以确定它不必被扩充为活结点;因为扩展结点1后,就知道最大装载量不会小于50;而扩展节点3时,发现此分支的“装载上界”为w2+w3=20<50,无需搜索此分支,节点3不必入队。
图4-1子集图
4.2数据结构设计
用FIFO分支搜索所有的分支,并记录已搜索分支的最优解,搜索完子集树也就找到出了问题的解。
要想求出最优解,必须搜素出最优解,必须搜索到叶节点。
所以要记录树的层次,当层次为n+1时,搜索完全部叶节点