收藏 分享(赏)

装载问题5种解决方案.doc

上传人:精品资料 文档编号:10655062 上传时间:2019-12-15 格式:DOC 页数:34 大小:111.41KB
下载 相关 举报
装载问题5种解决方案.doc_第1页
第1页 / 共34页
装载问题5种解决方案.doc_第2页
第2页 / 共34页
装载问题5种解决方案.doc_第3页
第3页 / 共34页
装载问题5种解决方案.doc_第4页
第4页 / 共34页
装载问题5种解决方案.doc_第5页
第5页 / 共34页
点击查看更多>>
资源描述

1、算法分析与设计2016/2017(2)实验题目 装载问题 5 种解法 学 生 姓 名 学生学号 学生班级 任课教师 提 交 日 期 2017 计算机科学与技术学算法分析与设计II目录一问题定义 3二解决方案 31 优先队列式分支限界法求解 .31.1 算法分析 31.2 代码 31.3 运行结果 132 队列式分支限界法求解 .132.1 算法分析 132.2 代码 142.3 测试截图 223 回朔法-迭代 223.1 算法分析 223.2 代码 223.3 测试截图 264 回朔法-递归 264.1 算法分析 264.2 代码 274.3 测试截图 315 贪心算法 .315.1 算法分析

2、 315.2 代码 315.3 测试截图 35算法分析与设计3 / 34一问题定义有一批共有 n 个集装箱要装上两艘载重量分别为 c1 和 c2 的轮船,其中集装箱 i 的重量为 wi, 且重量之和小于(c1 + c2)。装载问题要求确定是否存在一个合理的装载方案可将这 n 个集装箱装上这两艘轮船。如果有,找出一种装载方案。二解决方案1 优先队列式分支限界法求解1.1 算法分析活结点 x 在优先队列中的优先级定义为从根结点到结点 x 的路径所相应的载重量再加上剩余集装箱的重量之和。优先队列中优先级最大的活结点成为下一个扩展结点。以结点 x 为根的子树中所有结点相应的路径的载重量不超过它的优先级

3、。子集树中叶结点所相应的载重量与其优先级相同。在优先队列式分支限界法中,一旦有一个叶结点成为当前扩展结点,则可以断言该叶结点所相应的解即为最优解。此时可终止算法。1.2 代码1.2-1/MaxHeap.htemplate class MaxHeap public: MaxHeap(int MaxHeapSize = 10); MaxHeap() delete heap; int Size() const return CurrentSize; 算法分析与设计4 / 34T Max() /查找 if (CurrentSize = 0) throw OutOfBounds(); return he

4、ap1; MaxHeap /增 MaxHeap /删 void Initialize(T a, int size, int ArraySize); private: int CurrentSize, MaxSize; T *heap; / element array ; template MaxHeap:MaxHeap(int MaxHeapSize) / Max heap constructor. MaxSize = MaxHeapSize; heap = new TMaxSize+1; CurrentSize = 0; template MaxHeap / 父节点下降 i /= 2; /

5、继续向上,搜寻正确位置 heapi = x; return *this; template MaxHeap / 是,i 就是 y 的正确位置,退出 / 否,需要继续向下,重整堆 heapi = heapci; / 大于父节点的孩子节点上升 i = ci; / 向下一层,继续搜索正确位置 ci *= 2; heapi = y; return *this; 算法分析与设计7 / 34template void MaxHeap:Initialize(T a, int size,int ArraySize) / Initialize max heap to array a. delete heap;

6、heap = a; CurrentSize = size; MaxSize = ArraySize; / 从最后一个内部节点开始,一直到根,对每个子树进行堆重整 for (int i = CurrentSize/2; i = 1; i-) T y = heapi; / 子树根节点元素 / find place to put y int c = 2*i; / parent of c is target / location for y while (c = heapc) break; / yes / no 算法分析与设计8 / 34heapc/2 = heapc; / move child up

7、 c *= 2; / move down a level heapc/2 = y; 1.2-2/6d3-2.cpp/装载问题 优先队列式分支限界法求解 #include “stdafx.h“ #include “MaxHeap.h“ #include using namespace std; const int N = 4; class bbnode; template class HeapNode template friend void AddLiveNode(MaxHeap template friend Type MaxLoading(Type w,Type c,int n,int b

8、estx); public: operator Type() constreturn uweight; private: 算法分析与设计9 / 34bbnode *ptr; /指向活节点在子集树中相应节点的指针 Type uweight; /活节点优先级(上界) int level; /活节点在子集树中所处的层序号 ; class bbnode template friend void AddLiveNode(MaxHeap template friend Type MaxLoading(Type w,Type c,int n,int bestx); friend class Adjacenc

9、yGraph; private: bbnode *parent; /指向父节点的指针 bool LChild; /左儿子节点标识 ; template void AddLiveNode(MaxHeaptemplate Type MaxLoading(Type w,Type c,int n,int bestx); int main() float c = 70; 算法分析与设计10 / 34float w = 0,20,10,26,15;/下标从 1 开始 int xN+1; float bestw; cout void AddLiveNode(MaxHeap 算法分析与设计11 / 34b-p

10、arent = E; b-LChild = ch; HeapNode N; N.uweight = wt; N.level = lev; N.ptr = b; H.Insert(N); /优先队列式分支限界法,返回最优载重量,bestx 返回最优解 template Type MaxLoading(Type w,Type c,int n,int bestx) /定义最大的容量为 1000 MaxHeap H(1000); /定义剩余容量数组 Type *r = new Typen+1; rn = 0; for(int j=n-1; j0; j-) rj = rj+1 + wj+1; /初始化

11、int i = 1;/当前扩展节点所处的层 bbnode *E = 0;/当前扩展节点 Type Ew = 0; /扩展节点所相应的载重量 算法分析与设计12 / 34/搜索子集空间树 while(i!=n+1)/非叶子节点 /检查当前扩展节点的儿子节点 if(Ew+wi N; H.DeleteMax(N);/非空 i = N.level; E = N.ptr; Ew = N.uweight - ri-1; /构造当前最优解 for(int j=n; j0; j-) bestxj = E-LChild; E = E-parent; return Ew; 算法分析与设计13 / 341.3 运行

12、结果2 队列式分支限界法求解2.1 算法分析在算法的循环体中,首先检测当前扩展结点的左儿子结点是否为可行结点。如果是则将其加入到活结点队列中。然后将其右儿子结点加入到活结点队列中(右儿子结点一定是可行结点)。2 个儿子结点都产生后,当前扩展结点被舍弃。活结点队列中的队首元素被取出作为当前扩展结点,由于队列中每一层结点之后都有一个尾部标记-1,故在取队首元素时,活结点队列一定不空。当取出的元素是-1 时,再判断当前队列是否为空。如果队列非空,则将尾部标记-1加入活结点队列,算法开始处理下一层的活结点。节点的左子树表示将此集装箱装上船,右子树表示不将此集装箱装上船。设 bestw 是当前最优解;e

13、w 是当前扩展结点所相应的重量;r 是剩余集装箱的重量。则当 ew+r using namespace std; template class Queue public: Queue(int MaxQueueSize=50); Queue()delete queue; bool IsEmpty()constreturn front=rear; bool IsFull()return ( ( (rear+1)%MaxSize=front )?1:0); T Top() const; T Last() const; Queue Queue Queue void Output(ostream int

14、 Length()return (rear-front); private: int front; int rear; int MaxSize; T *queue; ; template Queue:Queue(int MaxQueueSize) 算法分析与设计15 / 34 MaxSize=MaxQueueSize+1; queue=new TMaxSize; front=rear=0; template T Queue:Top()const if(IsEmpty() cout T Queue :Last()const if(IsEmpty() cout Queuei=(front+1)%M

15、axSize;i-) out ostreamreturn out; 2.2-2/6d3-1.cpp/装载问题 队列式分支限界法求解 #include “stdafx.h“ #include “Queue.h“ #include using namespace std; const int N = 4; template class QNode template 算法分析与设计18 / 34friend void EnQueue(Queue* template friend Type MaxLoading(Type w,Type c,int n,int bestx); private: QNod

16、e *parent; /指向父节点的指针 bool LChild; /左儿子标识 Type weight; /节点所相应的载重量 ; template void EnQueue(Queue* template Type MaxLoading(Type w,Type c,int n,int bestx); int main() float c = 70; float w = 0,20,10,26,15;/下标从 1 开始 int xN+1; float bestw; cout void EnQueue(Queue* bestxn = ch; return; 算法分析与设计20 / 34 /非叶节

17、点 QNode *b; b = new QNode; b-weight = wt; b-parent = E; b-LChild = ch; Q.Add(b); template Type MaxLoading(Type w,Type c,int n,int bestx) /队列式分支限界法,返回最优装载重量,bestx 返回最优解 /初始化 Queue* Q; /活节点队列 Q.Add(0); /同层节点尾部标识 int i = 1; /当前扩展节点所处的层 Type Ew = 0, /扩展节点所相应的载重量 bestw = 0, /当前最优装载重量 r = 0; /剩余集装箱重量 for(

18、int j=2; j *E = 0, /当前扩展节点 *bestE; /当前最优扩展节点 /搜索子集空间树 while(true) 算法分析与设计21 / 34 /检查左儿子节点 Type wt = Ew + wi; if(wt bestw) bestw = wt; EnQueue(Q,wt,i,n,bestw,E,bestE,bestx,true); /检查右儿子节点 if(Ew+rbestw) EnQueue(Q,Ew,i,n,bestw,E,bestE,bestx,false); Q.Delete(E);/取下一扩展节点 if(!E)/同层节点尾部 if(Q.IsEmpty() brea

19、k; Q.Add(0); /同层节点尾部标识 Q.Delete(E); /取下一扩展节点 i+; /进入下一层 r-=wi; /剩余集装箱重量 Ew =E-weight; /新扩展节点所对应的载重量 算法分析与设计22 / 34 /构造当前最优解 for(int j=n-1; j0; j-) bestxj = bestE-LChild; bestE = bestE-parent; return bestw; 2.3 测试截图3 回朔法-迭代3.1 算法分析用回溯法解装载问题时,用子集树表示其解空间显然是最合适的。可行性约束条件重量之和小于(c1 + c2)可剪去不满足约束条件的子树用 cw 记

20、当前的装载重量,即 cw=(w1x1+w2x2+.+wjxj),当 cwc1 时,以节点 Z 为根的子树中所有节点都不满足约束条件,因而该子树中解均为不可行解,故可将该子树剪去。3.2 代码#include using namespace std; 算法分析与设计23 / 34template Type MaxLoading(Type w , Type c, int n, int bestx ); int main() int n=3,m; int c=50,c2=50; int w4=0,10,40,40; int bestx4; m=MaxLoading(w, c, n, bestx);

21、coutc2) cout Type MaxLoading(Type w,Type c,int n,int bestx)/迭代回溯法,返回最优载重量及其相应解,初始化根结点 int i=1;/当前层,x1:i-1为当前路径 int *x=new intn+1; Type bestw=0, /当前最优载重量 cw=0, /当前载重量 r=0; /剩余集装箱重量 for (int j=1;jn)/到达叶结点 for (int j=1;j0 i-; 算法分析与设计26 / 34 /从右子树返回 if (i=0) delete x; return bestw; xi=0; cw-=wi; i+; 3.3

22、 测试截图4 回朔法-递归4.1 算法分析与回朔法-迭代的相同,以下代码只是更改了具体的实现过程4.2 代码#include 算法分析与设计27 / 34using namespace std; template class Loading /friend Type MaxLoading(Type,Type,int,int ); /private: public: void Backtrack(int i); int n, /集装箱数 *x, /当前解 *bestx; /当前最优解 Type *w, /集装箱重量数组 c, /第一艘轮船的载重量 cw, /当前载重量 bestw, /当前最优载

23、重量 r; /剩余集装箱重量 ; template void Loading :Backtrack (int i); template Type MaxLoading(Type w, Type c, int n, int bestx); int main() int n=3,m; int c=50,c2=50; 算法分析与设计28 / 34int w4=0,10,40,40; int bestx4; m=MaxLoading(w, c, n, bestx); coutc2) cout void Loading :Backtrack (int i)/ 搜索第 i 层结点 if (i n)/ 到达叶结点 if (cwbestw) for(int j=1;j bestw) xi = 0; / 搜索右子树 Backtrack(i + 1); r+=wi; template Type MaxLoading(Type w, Type c, int n, int bestx)/返回最优载重量 LoadingX; /初始化 X X.x=new intn+1; X.w=w; X.c=c; X.n=n; X.bestx=bestx; X.bestw=0; X.cw=0; /初始化 r X.r=0; for (int i=1;i=n;i+) X.r+=wi;

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报