ImageVerifierCode 换一换
格式:DOCX , 页数:19 ,大小:60.89KB ,
资源ID:4740244      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4740244.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(实验指导书回溯法.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

实验指导书回溯法.docx

1、实验指导书回溯法算法设计与分析实验指导书(计算机科学与技术系)编写兰州交通大学电子与信息工程学院2018年3月目录实验5回溯法.1实验三回溯法一、实验目的(1)回溯法是一种通用的解题法,通过本次实验,掌握回溯法求解问题的一般步骤,掌握如何定义问题的解空间,并将解空间组织为解空间树并掌握如何在解空间树中进行深度优先搜索;利用回溯法解问题时一般按以下三步骤:1)定义问题的解空间;2)确定易于搜索的解空间结构;3)以深度优先策略搜索解空间,并在搜索过程中用剪枝函数避免无效搜索;(2)通过实验掌握回溯法思想和方法;(3)培养学生的动手能力。二、实验仪器设备(1)计算机;(2)C+编译调试环境。三、实验

2、原理掌握将算法转换为可运行程序的步骤。四、实验内容及注意事项(1)装载问题。(2)0-1背包问题。(3)TSP问题。(4)八皇后问题。五、实验步骤5.1 装载问题(1)问题描述:一批集装箱共n个要装上2艘载重量分别为c1和c2的轮船,其中集装箱i的重量为Wi且W1+W2+Wn=c1+c2;试确定一个合理的装载方案使这n个集装箱装上这两艘轮船。(2)求解思路:装载问题如果有解,那么相当于将一艘轮船尽可能的装满,那么装载问题转换为一个特殊的(所有物品单位价值均为1)的0-1背包问题,解空间树为子集树。回溯的过程可以使用约束函数(轮船1是否能装下选定的集装箱)以及限界函数(装入轮船1 的集装箱重量之

3、和+待选择的集装箱重量之和与当前最优值的对比)进行剪枝。回溯的方法有递归回溯与迭代回溯。具体代码如下:#includeusingnamespacestd;templateTMaxLoading(T w, T c, int n, intbestx);/在GNU中,需提前声明int count = 0;/用来记录递归回溯搜索了多少个节点templateclassLoadingprivate: int n;/ The numbers int *x;/ 当前的搜索的路径 xi=1 表示在第i层进入了左子树 int *bestx;/当前已知的最优解 T *w;/The weight array T c;

4、/The first boxs weight Tcw;/current weight Tbestw;/The best weight T r;/The rest weight public: void backtrack(int i); TfriendMaxLoading(T w, T c, int n, intbestx);templatevoidLoading:backtrack(inti) count+; if (in) bestw = cw; / 局部最优值 for (int j = 1; j = n; j+) bestxj = xj; /局部最优解 else r -= wi; /处理

5、第i层的本节点 if (cw + wi = bestw) /进入右子树 xi = 0; backtrack(i + 1); /右子树搜索完毕 r += wi; /两颗子树都搜索完毕,必须回溯 templateTMaxLoading(Tw, Tc, intn, intbestx) /* /递归回溯容易理解 Loading X; X.x=new intn+1; /集装箱编号从1开始 X.bestx=bestx; /引用 X.w=w; X.c=c; X.n=n; X.cw=0; X.bestw=0; X.r=0; / for(int i=1;i=n;i+) X.r+=wi; /r初始时为所有集装箱的

6、重量之和 X.backtrack(1); delete X.x; returnX.bestw; */ int i = 1; int *x = newintn + 1; Tbestw = 0, cw = 0, r = 0; for (int j = 1; j = n; j+) r += wj; while (true) while (i = n&cw + wi n (2) cw+wic if (in) bestw = cw; / 局部最优值 for (int j = 1; j c)而停止上次循环,无法进入下一层的左子树 /右子树肯定可以进入 r -= wi; xi = 0; i+; while

7、(cw + r 0 & xi = 0) r += wi; i-; if (i = 0) deletex; returnbestw; xi = 0; cw -= wi; i+; int main() int w = 0, 16, 15, 15 ; /算法下标从1开始 intbestx4; int n = 3; int max = 0; for (int i = 1; i = 10000000; i+) /可以循环运行1000万次,对比递归回溯和迭代回溯的效率 max = MaxLoading(w, 30, n, bestx); coutmax= max endl; coutbest soluti

8、on is:endl; for (int i = 1; i = n; i+) coutbestxi ; coutendl; coutsearched nodes count: count endl;5.20-1背包问题给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?0-1背包问题是一个特殊的整数规划问题。0-1背包问题的解空间树是子集树。#includestdafx.h#include#includeusingnamespacestd;typedefintTypew;typedefintTypep;/物品类cl

9、assObject friendclassKnap;public: int operator = a.d); private: int ID; /物品编号 Typew w; /物品重量 Typep p; /物品价值 double d; /单位重量价值;/0-1背包问题的主类classKnappublic: Knap(Typew *w, Typep *p, Typew c, int n); Typep Knapsack();/回溯法解决0-1背包问题的主函数 voidBackTrack(int floor);/递归回溯法 void print();/打印结果private: Typep Boun

10、d(int i); /计算结点价值上界 Typew c; /背包容量 int n; /物品总数 Object *Q; /在Q数组中存放的物品以单位重量价值降序排序注意与装载问题的不同! Typewcw; /当前装入背包的物品重量之和 Typepcp; /当前装入背包的物品价值之和 int *cbestx; /当前最优解 int count; /最优解的个数 int *bestx10; /最优解,最优解的个数不超过10个。 Typepbestp; /最优值 Typepoldbestp; /用于回溯法边界处理,保存上一次最优值;Knap:Knap(Typew *w, Typep *p, Typew

11、c, intn) /初始化 Typew W = 0; Typep P = 0; count = 0; this-c = c; oldbestp = 0; this-n = n; cw = 0; cp = 0; Q = newObjectn; for (int i = 0; in; i+) Qi.ID = i + 1; Qi.d = 1.0*pi / wi; Qi.w = wi; Qi.p = pi; P += pi; W += wi; /所有物品的总重量小于等于背包容量c,全部物品装入背包,程序可以结束。 if (W = c) bestp = P; int *newbestx = newint

12、n; for (int i = 0; in; i+) newbestxi = 1; bestxcount+ = newbestx; /所有物品的总重量大于背包容量c,存在最佳装包方案 sort(Q, Q + n); /采用stl的sort,Q重载了 0) /背包容量足够大,在初始化时已经将所有物品装入背包 print(); returnbestp; else/背包容量小于物品所有重量,存在最优装包方案 cbestx = newintn; BackTrack(0); /从数组Q下标0,首结点开始回溯法求解 voidKnap:BackTrack(intfloor) if (floor n - 1)

13、 /已经到了子集树中的叶子结点 if (cp = oldbestp) /说明可能有多个最优解 int *newbe = newintn; for (int i = 0; i oldbestp) /说明最优解需要更新同时只有一个 count = 0; int *newbe = newintn; for (int i = 0; i = cw + Qfloor.w) cw += Qfloor.w; cp += Qfloor.p; if (cp= bestp) bestp = cp; cbestxfloor = 1; BackTrack(floor + 1); cw -= Qfloor.w; cp -

14、= Qfloor.p; /舍去数组Q下标为floor的物品,满足限界函数 if (cp + Bound(floor + 1) = bestp) cbestxfloor = 0; BackTrack(floor + 1); voidKnap:print() Typep *original = newintn + 1; cout以下每行为一种解法:= 0; i-) for (int j = 0; j n; j+) originalQj.ID = bestxij; for (int k = 1; k = n; k+) cout originalk ; coutendl; cout最优解的个数: co

15、unt endl; cout最优值:bestpendl;TypepKnap:Bound(inti) Typew cleft = c - cw; Typep b = cp; while (i n & Qi.w = cleft) cleft -= Qi.w; b += Qi.p; i+; if (i n) b += Qi.p / Qi.w * cleft; return b;int_tmain(intargc, _TCHAR* argv) constint N = 4; Typew c = 7; TypewwN = 2, 3, 5, 2 ; TypeppN = 6, 4, 8, 4 ; cout背

16、包容量: c ,物品总数: N endl; cout物品重量数组:; for (int i = 0; i N; i+) cout wi ; coutendl; cout物品价值数组:; for (int i = 0; i N; i+) cout pi ; coutendl; KnapK(w, p, c, N); K.Knapsack(); K.print(); system(pause); return 0;5.3 TSP问题假设有四个城市A,B,C,D, 从A出发,求经过所有顶点后回到A的最短路径,我们用树表示所有的解,他的解空间树是一个排列树,如下图所示:/5d9 旅行员售货问题回溯法求解

17、#includestdafx.h#includeusingnamespacestd;constint N = 4;/图的顶点数templateclassTraveling template friendType TSP(Type aN+1N+1, int n);private: void Backtrack(int i); int n, / 图G的顶点数 *x, / 当前解 *bestx; / 当前最优解 Type (*a)N+1, / 图G的领接矩阵 cc, / 当前费用 bestc; / 当前最优值 intNoEdge; / 无边标记;templateinlinevoid Swap(Typ

18、e&a, Type&b);templateTypeTSP(Type aN+1N+1, int n);int main() cout图的顶点个数 n= N endl; int aN+1N+1 = 0,0,0,0,0, 0,0, 30, 6, 4 , 0,30, 0, 5, 10 , 0, 6, 5, 0, 20 , 0, 4, 10, 20, 0 ; cout图的邻接矩阵为:endl; for (int i = 1; i = N; i+) for (int j = 1; j = N; j+) cout aij ; coutendl; cout最短回路的长为: TSP(a, N) endl; sy

19、stem(pause); return 0;templatevoidTraveling:Backtrack(inti) if (i = n) if (axn - 1xn != 0 & axn1 != 0 & (cc + axn - 1xn + axn1 bestc | bestc = 0) for (int j = 1; j = n; j+) bestxj = xj; bestc = cc + axn - 1xn + axn1; else for (int j = i; j = n; j+) / 是否可进入xj子树? if (axi - 1xj != 0 & (cc + axi - 1xi b

20、estc | bestc = 0) / 搜索子树 Swap(xi, xj); cc += axi - 1xi; /当前费用累加 Backtrack(i + 1); /排列向右扩展,排列树向下一层扩展 cc -= axi - 1xi; Swap(xi, xj); templateTypeTSP(TypeaN+1N+1, intn) Traveling Y; Y.n = n; Y.x = newintn + 1; Y.bestx = newintn + 1; for (int i = 1; i = n; i+) Y.xi = i; Y.a = a; Y.cc = 0; Y.bestc = 0; Y

21、.NoEdge = 0; Y.Backtrack(2); cout最短回路为:endl; for (int i = 1; i = n; i+) coutY.bestxi ; coutY.bestx1 endl; delete Y.x; Y.x = 0; delete Y.bestx; Y.bestx = 0; returnY.bestc;templateinlinevoid Swap(Type&a, Type&b) Type temp = a; a = b; b = temp;5.4 八皇后问题八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯贝瑟尔于184

22、8年提出:在88格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。#include#includeusingnamespacestd;#defineN 8int xN + 1;int sum = 0;int count = 0;bool Place(intk) for (int j = 1; jN) sum+; for (int j = 1; j = N; j+) cout xj ; coutendl; else for (int i = 1; i = N; i+) xt = i; if (Place(t) Backtrack(t + 1); int main() Backtrack(1); coutsum= sum endl; int total = 1 24; couttotal= total endl; coutcount= count endl; coutratio= count*1.0 / total endl; return

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1