欢迎来到冰豆网! | 帮助中心 分享价值,成长自我!
冰豆网
全部分类
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • 党团工作>
  • ImageVerifierCode 换一换
    首页 冰豆网 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    算法实验报告.docx

    • 资源ID:8333812       资源大小:415.62KB        全文页数:27页
    • 资源格式: DOCX        下载积分:12金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要12金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    算法实验报告.docx

    1、算法实验报告华北电力大学实 验 报 告| 实验名称 算法设计与分析综合实验 课程名称 算法设计与分析设计 | 专业班级: 学生姓名: 学 号: 成 绩:指导教师: 实验日期:(一)矩阵相乘问题:多个矩阵做乘法时最多的操作是做乘法运算,矩阵乘法是满足结合律的,不同的结合方式乘法运算次数相差非常大,在矩阵的阶较大和矩阵数目很大时,这成为制约程序效率的关键,穷举找出最优结合方式显然是无效的,结合方式非常的多。所以利用动态规划解决此问题,给出最少的乘法次数。一、算法设计动态规划思想类似于分治,总是把规模较大的问题分解成小的问题加以求解,原问题的解依赖于子问题的解,还有一个显著特征就是原问题最优解的条件

    2、就是子问题的最优。不同的地方就是子问题树中的子问题大量重复出现。为减少运算,总是在第一次遇到时计算并保存计算结果,以后遇到直接使用即可。动态规划求解算法,通常按以下几个步骤进行。(1) 分析最优解性质,刻画其结构特征(2) 递归定义最优值(3) 自底向上的方式计算最优解(4) 根据计算最优值得到的信息,构造一个最优解本问题是最小乘次数,定义最优结构说明:当i等于j时,取mij为0,否则取另外一个值,这时递归算最优乘次基础。二、算法分析动态规划算法可以解决的问题有一个特点,就是问题本身的最优是在子问题的最优方案基础上的。这个算法只是给出了给定矩阵序列乘积所要计算的最少次数,并没有给出给出如何最终

    3、的每次计算结合方式,但是在每次构造最优解时,数组result保存了截断点的位置,即每次计算时结合断开的下标k,通过递归到最后只剩2个数组时所有的矩阵相乘的结合方式就确定下来。即间接给出了如何计算的方案。可用动态规划算法求解的问题还具备另外一个要素就是子问题的重叠性质,在递归 算法自顶向下求解问题时,每次产生的子问题不是新问题,有些子问题被反复计算多次。正是这样,只是在第一次遇到问题时计算并保存结果,以后直接使用,这个算法只需多项式的事件,效率较高。三、代码#include#define N 100/定义最大连乘的矩阵个数是100void matrixChain(int p,int mN+1N+

    4、1,int sN+1N+1)/*用mij二维数组来存储Ai*.Aj的最少数乘次数,用sij来存储使Ai.Aj获得最少数乘次数对应的断开位置k,需要注意的是此处的N+1非常关键,虽然只用到的行列下标只从1到N,但是下标0对应的元素默认也属于该数组,所以数组的长度就应该为N+1*/ int n=N;/定义m,s数组的都是n*n的,不用行列下标为0的元素,但包括在该数组中 for(int i=1;i=n;i+) mii=0;/*将矩阵m的对角线位置上元素全部置0,此时应是r=1的情况,表示先计算第一层对角线上个元素的值*/ for(int r=2;r=n;r+)/r表示斜对角线的层数,从2取到n f

    5、or(int i=1;i=n-r+1;i+)/i表示计算第r层斜对角线上第i行元素的值 int j=i+r-1;/j表示当斜对角线层数为r,行下标为i时的列下标 mij=mi+1j+pi-1*pi*pj;/计算当断开位置为i时对应的数乘次数 sij=i;/断开位置为i for (int k=i+1;kj;k+) int t=mik+mk+1j+pi-1*pk*pj;/*计算断开位置k为从i到j(不包括i和j)的所有取值对应的 (Ai*.*Ak)*(Ak+1*.Aj)的数乘次数*/ if(tmij) mij=t;/将Ai*.Aj的最少数乘次数存入mij sij=k;/将对应的断开位置k存入sij

    6、 void traceback(int i,int j,int sN+1)/用递归来实现输出得到最小数乘次数的表达式 if(i=j) printf(A%d,i); else printf(); traceback(i,sij,s); traceback(sij+1,j,s); printf(); void main() int n;/用来存储矩阵的个数 int q2*N;/*用q数组来存储最原始的输入(各矩阵的行和列),主要目的是为了检验这N个矩阵是否满足连乘的条件*/ int pN+1,flag=1;/*用pi-1,pi数组来存储A的阶数,flag用来判断这N个矩阵是否满足连乘*/ int

    7、mN+1N+1;/ 用mij二维数组来存储Ai*.Aj的最小数乘次数 int sN+1N+1;/ 用sij来存储使Ai.Aj获得最小数乘次数对应的断开位置k printf(输入矩阵的个数(注:小于100):); scanf(%d,&n); for(int i=0;i=2*n-1;i+)/各矩阵的阶数的输入先存入数组q中接受检验 if(i%2=0) printf(n); printf(*输入A%d的行:,(i/2)+1); else printf( *列:); scanf(%d,&qi); for(i=1;i=2*n-2;i+)/矩阵连乘条件的检验 if(i%2!=0&qi!=qi+1) fla

    8、g=0; break; for(int j=1;j=n-1;j+) pj=q2*j; if(flag!=0) p0=q0; pn=q2*n-1; matrixChain(p,m,s); printf(式子如下:n); traceback(1,n,s); printf(n); printf(最少数乘次数为%dn,m1n); else printf(这%d个矩阵不能连乘!n,n); 四、结果截图五、结果分析说明,输入的行和列时遇到重复的数只输入一次即可,这就是为什么程序运行例子中8个矩阵相乘,输入的是9的数据的原因了。值得注意的是,编程中使用的数据是int 类型的,所以矩阵个数不能太大,不然最后结

    9、果超出了int 的表示范围而发生错误。程序优劣比较,程序完成了问题要求的计算,但是在输入的时候不太符合平时的习惯,不太让人满意,如果规模很大,则需要改动下程序。(二)0/1背包问题:现有n种物品,对1=i,说明第n个物品被装入了背包中,前n-1个物品被装入容量为的背包中;否则,第n个物品没有装入背包中,前n-1个物品被装入容量为W的背包中。依此类推,直到确定第一个物品是否被装入背包为止。由此,我们可以得到如下的函数: 根据动态规划函数,用一个的二维数组C存放中间变量,表示把前i个物品装入容量为j的背包中获得的最大价值。 设物品的重量存放在数组wn中,价值存放在数组vn中,背包的容量为W,数组存

    10、放迭代的结果,数组xn存放装入背包的物品。 5)回溯法分析:用回溯法解0_1背包问题时,会用到状态空间树。在搜索状态空间树时,只要其左儿子结点是一个可行结点,搜索就进入其左子树。当右子树有可能包含最优解时才进入右子树搜索,否则将右子树剪去。设r是当前剩余物品价值总和;cp是当前价值;bestp是当前最优价值。当cp+rbestp时,可剪去右子树。计算右子树中解的上界可以用的方法是将剩余物品依其单位重量价值排序,然后依次装入物品,直至装不下时,再装入该物品的一部分而装满背包。由此得到的价值是右子树中解的上界,用此值来剪枝。为了便于计算上界,可先将物品依其单位重量价值从大到小排序,此后只要顺序考察

    11、各物品即可。在实现时,由MaxBoundary函数计算当前结点处的上界。它是类Knap的私有成员。Knap的其他成员记录了解空间树种的节点信息,以减少函数参数的传递以及递归调用时所需要的栈空间。在解空间树的当前扩展结点处,仅当要进入右子树时才计算上界函数MaxBoundary,以判断是否可以将右子树减去。进入左子树时不需要计算上界,因为其上界与父结点的上界相同。在调用函数Knapsack之前,需要先将各物品依其单位重量价值从达到小排序。为此目的,我们定义了类Objiect。其中,运算符与通常的定义相反,其目的是为了方便调用已有的排序算法。在通常情况下,排序算法将待排序元素从小到大排序。 在搜索

    12、状态空间树时,由函数Backtrack控制。在函数中是利用递归调用的方法实现了空间树的搜索。三、时空效率分析1)穷举法: 对于一个有n个元素的集合,其子集数量为,所以,不论生成子集的算法效率有多高,穷举法都会导致一个的算法。2)递归法: 在递归法的算法体中有一个if判断中出现了两次递归调用比较大小所以它们之间的递归关系式可以大体表示为:,其中表示递归法的时间复杂度,C是常数。求解递归方程可以知道的量级为。所以递归法解0-1背包问题的时间复杂度为。递归法是耗费空间最多的算法,每次递归调用都需要压栈,导致栈的使用很频繁。3)动态规划法: 由于函数Knapsack中有一个两重for循环,所以时间复杂

    13、度为O(n+1)x(m+1).空间复复杂度也是O(n+1)x(m+1),即O(nm).4)回溯法:由于计算上界的函数MaxBoundary需要O(n)时间,在最坏情况下有个右儿子结点需要计算上界,所以解0-1背包问题的回溯法算法BackTrack所需要的计算时间为.四、运行结果递归法输出结果:动态规划法输出结果:回溯法输出结果:五、分析输出结果 上面测试的是每种算法在两种输入情况下得到的0-1背包问题的解。两种测试数据为:第一组:背包容量:18; 物品数目:7; 每个物品重量为:11 2 4 8 9 6 10; 每个物品价值为:7 8 8 12 13 4 14。第二组:背包容量:50; 物品数

    14、目:10; 每个物品重量为: 8 12 24 16 6 9 35 21 18 19; 每个物品价值为: 34 32 56 67 54 32 45 56 46 70。 四种实现的算法中,只有回溯法没能够得到预期的最优解。(但是可能是算法设计时的问题,其实回溯法是穷举法的变形,肯定能够得到最优解的,这里是我设计函数的问题。从递归法的输出可知,它的结果就是我们想要的最优解)。从时间复杂度和空间复杂度分析可知,动态规划法的时间复杂度是最小的,但是同时它的空间复杂度又是最大的。这里就可以看出在设计算法的过程中要考虑它们的平衡问题。在时间要求比较快的情况下,我们就可以选择动态规划法;在空间要求比较高时,我

    15、们就可以使用穷举法或是分枝限界法等其他改进的穷举法。各种算法在解背包问题时的比较如下表所示:算法名称时间复杂度优点缺点改进穷举法最优解速度慢剪枝递归法最优解空间消耗大用数组存动态规划法最优解速度慢递归方程求解贪心法不一定是最优解速度快可以作为启发回溯法最优解速度慢改进剪枝分枝限界法最优解速度慢优化限界函数从计算复杂性理论看,背包问题是NP完全问题。半个多世纪以来,该问题一直是算法与复杂性研究的热门话题。通过对0-1背包问题的算法研究可以看出,回溯法和分枝限界法等可以得到问题的最优解,可是计算时间太慢;动态规划法也可以得到最优解,当时,算法需要的计算时间,这与回溯法存在一样的缺点计算速度慢;采用

    16、贪心算法,虽然耗费上优于前者,但是不一定是最优解。目前,以上几种方法中回溯法、动态规划法、贪心法都广泛地应用到不同的实际问题中,并在应用中不断地改进。六、算法代码1)递归法#include stdafx.h#include #include #include dosmax.h / has max() and min()int p6 = 0, 6, 3, 5, 4, 6; / p 价值,多放置一个0,是为了让下标统一,方便理解和计算。int w6 = 0, 2, 2, 6, 5, 4; / w 重量/ int x6;int n = 5; / 所有物品的数量int c = 10; / 实际最大总容

    17、量/ F函数的返回值是,当前剩为余容量为y,并且当前仍有剩余物品从i到n时,的最优解。/ i为当前检索到哪个物品的序号int F(int i, int y) if (i = n) return (y wn) ? 0 : pn;/ 最终返回点,一次性比较搞定! if (y wi) return F(i+1, y);/ 如果y小于当前重量,那么只有一个选择:继续向下搜寻,看看能不能放下后面的物品 / 如果y大于当前物品的重量wi,就有两个选择了(虽然不能当场计算出这两个选择的值,但是没关系,让它们继续往下计算就是了):/ 最后返回(假设当前不放入物品,y的值不变)和(假设当前放入物品,y减去当前物

    18、品的重量)的两种不同选择之后,所造成不同价值的比较结果。 / 在i=n之前,所有的F函数代表的临时总价值,都是悬而未决的。但是一旦i=n之后,依次返回正确的值。 / F(i+1,y) 和 F(i+1, y-wi)+pi,它们都是i+1时候的情况,分头进行计算,相互不依赖。层次分解,就好象是一颗二叉树(中间如果ywi就只有一个节点)。 / 最后只得出一个F的值(最优值),其余F的临时总价值,全部丢弃。 return max(F(i+1,y), F(i+1, y-wi)+pi); / 切记,返回的是物品的总价值(最大值=最优解)void main(void) cout Optimal value

    19、is ; cout F(1, c) endl;/ =dosmax.h=#ifndef dosmax_#define dosmax_template inline type max(type a, type b) return (a b)? a : b;template inline type min(type a, type b) return (a b)? a : b;#endif/ =/如果下标从0开始,那么只需要改碰到n的情况,因为没有wn和pn存在。但当前wi与pi不变。int p5 = 6, 3, 5, 4, 6; / p 价值,多放置一个0,是为了让下标统一,方便理解和计算。int

    20、 w5 = 2, 2, 6, 5, 4; / w 重量int n = 5; / 所有物品的数量int c = 10; / 实际最大总容量int F(int i, int y) if (i = n-1) return (y wn-1) ? 0 : pn-1; / cas darret,一次性比较搞定! if (y wi) return F(i+1, y); return max(F(i+1,y), F(i+1, y-wi)+pi);void main(void) cout Optimal value is ; cout F(0, c) endl;2)动态规划法/*0/1背包问题求解(visualstudio2005)*给定一个载重量为m,及n个物品,其重量为wi,价值为vi,1=i=n*要求:把物品装入背包,并使包内物品价值最大/*/#include#include#includes


    注意事项

    本文(算法实验报告.docx)为本站会员主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2022 冰点文档网站版权所有

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

    收起
    展开