算法分析与设计上机实验指导书
- 格式:docx
- 大小:259.94 KB
- 文档页数:23
《算法分析与设计》实验指导书《算法分析与设计》课程是计算机专业的一门必修课程。
开设算法分析与设计实验,目的就是为了使学生消化理论知识,加深对讲授内容的理解,尤其是一些算法的实现及其应用,培养学生独立编程和调试程序的能力,使学生对算法的分析与设计有更深刻的认识。
《算法分析与设计》课程实验的目的:是为了使学生在课程学习的同时,通过实验环境中的实际操作,对部分算法的具体应用有一个初步的了解,使学生加深了解和更好地掌握《算法分析与设计》课程教学大纲要求的内容。
《算法分析与设计》课程实验的注意事项:在《算法分析与设计》的课程实验过程中,要求学生做到:(1)预习实验指导书有关部分,认真做好实验内容的准备,就实验可能出现的情况提前作出思考和分析。
(2)认真书写实验报告。
实验报告包括实验目的和要求,实验情况及其分析。
(3)遵守机房纪律,服从辅导教师指挥,爱护实验设备。
(4)实验课程不迟到。
如有事不能出席,所缺实验一般不补。
《算法分析与设计》课程实验的验收:实验的验收将分为两个部分。
第一部分是上机操作,包括检查程序运行和即时提问。
第二部分是提交电子的实验报告。
实验一算法实现一一、实验目的与要求熟悉C/C++语言的集成开发环境;通过本实验加深对分治法、贪心算法的理解。
二、实验内容:掌握分治法、贪心算法的概念和基本思想,并结合具体的问题学习如何用相应策略进行求解的方法。
三、实验题1. 【伪造硬币问题】给你一个装有n个硬币的袋子。
n个硬币中有一个是伪造的。
你的任务是找出这个伪造的硬币。
为了帮助你完成这一任务,将提供一台可用来比较两组硬币重量的仪器,利用这台仪器,可以知道两组硬币的重量是否相同。
试用分治法的思想写出解决问题的算法,并计算其时间复杂度。
2.【找零钱问题】一个小孩买了价值为33美分的糖,并将1美元的钱交给售货员。
售货员希望用数目最少的硬币找给小孩。
假设提供了数目有限的面值为25美分、10美分、5美分、及1美分的硬币。
算法设计与分析实验指导书. . .. . .算法设计与分析实验指导书东北大学软件学院2012年.. .专业. .目录算法设计与分析 (1)实验指导书 (1)前言 (3)实验要求 (4)实验1 分治法的应用(2学时) (5)1.实验目的 (5)2.实验类型 (5)3.预习要求 (5)4.实验基本要求 (5)5.实验基本步骤 (7)实验2动态规划(2学时) (9)1.实验目的 (9)2.实验类型 (9)3.预习要求 (9)4.实验基本要求 (9)5.实验基本步骤 (10)实验3 回溯法(4学时) (12)1.实验目的 (12)2.实验类型 (12)3.预习要求 (12)4.实验基本要求 (12)5.实验基本步骤 (13)前言《算法设计与分析》是一门面向设计,处于计算机科学与技术学科核心地位的教育课程。
通过对计算机算法系统的学习,使学生理解和掌握计算机算法的通用设计方法,培养对算法的计算复杂性正确分析的能力,为独立设计算法和对算法进行复杂性分析奠定基础。
要求掌握算法复杂度分析、分治法、动态规划法、贪心法、回溯法、分支限界法等算法的设计方法及其分析方法。
能将这些方法灵活的应用到相应的问题中,并且能够用C++实现所涉及的算法,并尽量做到低复杂度,高效率。
通过本课程的实验,使学生加深对课程容的理解,培养学生严密的思维能力,运用所学知识结合具体问题设计适用的算法的能力;培养学生良好的设计风格,激励学生创造新算法和改进旧算法的愿望和热情。
希望同学们能够充分利用实验条件,认真完成实验,从实验中得到应有的锻炼和培养。
希望同学们在使用本实验指导书及进行实验的过程中,能够帮助我们不断地发现问题,并提出建议,使《算法设计与分析》课程成为对大家有益的课程。
实验要求《算法设计与分析》课程实验的目的是为了使学生在课堂学习的同时,通过一系列的实验,使学生加深理解和更好地掌握《算法设计与分析》课程教学大纲要求的容。
在《算法设计与分析》的课程实验过程中,要求学生做到:(1)仔细观察调试程序过程中出现的各种问题,记录主要问题,做出必要说明和分析。
计算机科学与技术学院算法分析与设计实验指导书2011年8月于洪编写2015年9月周应华修订目录实验一分治策略排序 (3)实验二减治策略查找顺序表 (5)实验三动态规划求解0/1背包问题 (8)实验四贪心算法求解最短路径问题 (10)附录1 关于文件的操作 (12)附录2 关于如何统计运算时间 (13)实验一分治策略排序实验目的1)以排序问题为例,掌握分治法的基本设计策略;2)熟练掌握合并排序算法的实现;3)熟练掌握快速排序算法的实现;4) 理解常见的算法经验分析方法。
实验环境计算机、C语言程序设计环境实验学时2学时实验内容与步骤1.准备实验数据要求:编写一个函数data-generate,生成2000个在区间[1,10000]上的随机整数,并将这些数输出到外部文件data.txt中。
这些数作为本算法实验的输入数据。
2.实现合并排序算法要求:实现mergesort算法。
输入:待排数据文件data.txt;输出:有序数据文件resultsMS.txt(注:建议将此排好序的数据作为实验二的算法输入);程序运行时间TimeMS。
合并排序算法(类C语言):/* 数组A[] 中包含待排元素;array B[] is a work array */TopDownMergeSort(A[], B[], n){TopDownSplitMerge(A, 0, n, B);}// iBegin is inclusive; iEnd is exclusive (即:A[iEnd]不是待排元素)TopDownSplitMerge(A[], iBegin, iEnd, B[]){if(iEnd - iBegin < 2) // 如果只有1个待排元素,返回。
return;// recursively split runs into two halves until run size == 1,// then merge themiMiddle = (iEnd + iBegin) / 2; // 划分TopDownSplitMerge(A, iBegin, iMiddle, B);TopDownSplitMerge(A, iMiddle, iEnd, B);TopDownMerge(A, iBegin, iMiddle, iEnd, B); // 合并;元素放到数组B中。
实验一串匹配程序设计(2学时)一、实验目的(1). 熟练掌握串匹配的含义(2). 掌握BF算法匹配的过程并编程实现(3). 熟悉C++编译环境的基本操作二、实验内容给定两个字符串S和T,用BF算法,在主串S中查找字串T,输出结果,输出时要求有文字说明。
请编写程序。
三、实验要求(1)、熟悉C++编译环境的基本操作(2)、考虑各种可能的情况(匹配成功或不成功)(3)、写出完整的程序四、实验结果实验二排序问题程序设计(2学时)一、实验目的(1). 掌握选择排序和起泡排序的基本思想(2). 掌握两种排序方法的具体实现过程(3). 在掌握的基础上编程实现两种排序方法二、实验内容输入一个待排序的序列,分别用选择排序和起泡排序两种排序方法将其变换成有序的序列,输出结果,输出时要求有文字说明。
请编写程序。
三、实验要求(1)、熟悉C++编译环境的基本操作(2)、考虑各种可能的情况(序列本身已是有序序列,序列不是有序序列)(3)、写出完整程序四、实验结果实验三数字旋转方阵程序设计(2学时)一、实验目的(1). 掌握分治法的设计思想(2). 掌握数字旋转方阵的具体实现过程(3). 熟练掌握二维数组的使用方法(4). 在掌握的基础上编程实现数字旋转方阵的实现过程二、实验内容给出一个初始数据,在此数据的基础上由外层向里层填写数据,完成一个数字旋转方阵,输出结果,输出时要求有文字说明。
请编写程序。
三、实验要求(1)、熟悉C++编译环境的基本操作(2)、考虑各种可能的情况(方阵有一层,两层或更多层)(3)、写出完整程序四、实验结果实验四排序中分治法的程序设计(2学时)一、实验目的(1). 掌握归并排序和快速排序的划分方法(2). 掌握归并排序和快速排序的具体分治策略(3). 在掌握的基础上编程两种排序方法的实现过程二、实验内容给出一个初始序列,分别用归并排序和快速排序两种分治法将所给序列变换为有序序列,输出结果,输出时要求有文字说明。
《算法设计与分析》课程上机指导上机常见错误与对策 (1)上机指导1 (2)上机指导2 (5)上机常见错误与对策㈠创建工程时,选错工程类型(应选择倒数第三个“Win32 Console Application”);创建源程序文件时,选错文件类型。
㈡要修改程序,应打开工作区(dsw)文件,而不是源程序(cpp)文件。
㈢在VC++系统中,程序是用西文字符(ASCII码)来描述的,汉字只能出现在字符串常数或注释中。
◆请注意汉字双引号和西文双引号的区别◆请注意汉字单引号和西文单引号的区别◆请注意汉字分号和西文分号的区别◆请注意汉字园括号和西文园括号的区别㈣在一般情况下,一个工作区只有一个工程,一个工程对应一个程序。
当一个程序完成,编制下一个程序时,一定要新建工程(不要修改系统默认设置“创建新工作区”)。
最简单的方法是:退出VC++集成环境后,重新进入VC++。
㈤当系统出现不可解释的现象时,此时应选择“编译”→“重建全部”,然后执行。
若还不行,则重新启动计算机,利用硬盘保护卡功能恢复系统。
操作步骤:◆重新启动计算机后,出现菜单画面。
◆选中“Windows 2000 Professional”。
◆在按住“Ctrl”键的同时,按“R”健。
◆对于系统提问,按“Y”键回答。
㈥源程序若有错误,编译系统会在输出区显示错误信息。
由于识别错误能力有限,指示的错误信息有时不一定完全正确,但至少提供了线索。
双击错误信息条目,指针会自动指向出错语句,编程者可逐字符查找错误。
《算法设计与分析》上机指导1 ㈠(每个)程序书写要求// ******************************************************* // * 工程名:103.dsp * // * 程序名:103.cpp * // * 主要功能:自底向上合并排序法* // * 学号姓名:57053001某某某*// * 编制时间:2011年7月13日* // ******************************************************** #include <iostream.h> //#include <iostream>void main() //using namespace std;{ //int main()……//{……// …………// return 0;} //}㈡实习内容习题一(工程名为101、源程序名为101)选择排序法的伪代码描述如下:算法1.4 SelectionSort(参见Page 8)输入:数组A[1..n]输出:按升序排列的数组A[1..n]1. for i←1 to n-12. Selection(i)3.end for过程Selection(i)1. k←i2. for j←i+1 to n3. if A[j]<A[k] then k←j4. end for5. if k≠i then 交换A[i]和A[k]用C语言实现上述算法并上机通过。
《算法分析与设计》实验指导与报告书实验目录实验1 求最大公约数 (1)实验2 斐波那契数列 (3)实验3 最近对问题 (6)实验4 堆排序 (7)实验5 霍纳法则和二进制幂 (8)实验6 字符串匹配问题 (9)实验7 Warshall算法和Floyd算法 (10)实验8 最优二叉查找树 (11)实验9 Huffman编码* (12)实验10 求解非线性方程* (13)实验11 投资问题* (14)注:(1)实验4和实验5为变治法应用,二选一;(2)实验7和实验8为动态规划法应用,二选一;(3)带*号的实验为选做实验,根据课时及学生实验完成情况机动安排。
实验1 求最大公约数{c = a;a = b;b = c;}while(a % b != 0){c = a % b;a = b;b = c;}printf("%d", b);return 0;}连续整数检测算法最大公约数算法:#include <stdio.h>int main(){int a,b,t;printf("Please input two integers: ");scanf("%d %d",&a,&b);if(a<b)t=a;elset=b;while(t>=1){if((a%t==0)&&(b%t==0))break;t--;}printf("%d",t);return 0;}相减循环:#include<stdio.h>int main(){int m,n;printf("Please input two integers: ");scanf("%d%d",&m,&n);while(m!=n)if(m>n) m=m-n;else n=n-m;printf("%d",m);return 0;}教师评分实验2 斐波那契数列实验目的(1)求斐波那契数列;(2)区分递归和递推思想。
算法分析与设计本书是为配合《计算机算法分析与设计》而编写上机指引,其目是使学生消化理论知识,加深对讲授内容理解,增强算法分析与设计实践动手能力。
上机实验注意事项如下:(1)课前认真做好预习,准备好实验工具,熟悉实验流程和手段。
(3)课中依照实验指引书,结合课本实例进行编程实验。
实验时,一人一组,独立上机调试,上机时浮现疑问,可以举手询问实验指引教师,或者与周边同窗小声讨论,勉励独立解决问题。
(4)课后准时按质按量整顿出实验报告。
实验报告应独立完毕,回绝抄袭。
实验内容覆盖:递归与分治方略、动态规划、贪心算法、回溯法、分支限界法等。
实验一递归与分治方略一.实验目与规定(1)理解和掌握递归与分治方略基本原理。
(2)理解课本中示例代码。
(3)调试代码通过。
二.递归与分治基本思想(1)递归与分治办法。
递归与分治办法基本思想是:将一种难以解决大问题,分割成某些规模较小、相似子问题,以便各个击破,分而治之。
(2)递归。
递归问题分析时,要把握如下两个要素:●递归出口。
●递归公式。
其中:●递归出口给出了最简朴状况下问题解。
●递归公式则给出了普通意义下大问题(原问题)和小问题(子问题)之间递归关系。
通过递归公式,一种难以解决大问题会随着递归不断分解为各种小问题,小问题继续递归变为更小小问题,直到最后到达递归出口得到解。
三.实验代码分析和阐明本某些实验,需完毕“棋盘覆盖”(课本P20)和“迅速排序”(课本P22)两个问题。
3.1棋盘覆盖1. 棋盘覆盖问题思路:(1)一方面,将原始棋盘覆盖问题看作最初大问题。
(2)然后,将棋盘行、列一分为二,从而将原始大棋盘分为四个同样大小小棋盘。
(3)接着,采用P21图2-5中适当L型骨牌,覆盖原始大棋盘中心位置,将四个同样大小小棋盘都转化为特殊棋盘。
(4)最后,对四个特殊小棋盘进行递归解决即可。
以上环节(2)和环节(3)合起来,完毕了将大问题划分为小问题过程,特别需要注意是:小问题必要要和大问题相似或相似,否则无法递归。
《算法分析与设计》实验指导.实验一锦标赛问题[实验目的]1.基本掌握分治算法的原理.2.掌握递归算法及递归程序的设计.3.能用程序设计语言求解锦标赛等问题的算法.[预习要求]1.认真阅读数据结构教材和算法设计教材,了解分治算法原理;2.设计用分治算法求解背包问题的数据结构与程序代码.[实验题]【问题描述】设有n=2k个运动员要进行网球循环赛。
现要设计一个满足以下要求的比赛日程表:(1)每个选手必须与其他n-1个选手各赛一次;(2)每个选手一天只能参赛一次;(3)循环赛在n-1天内结束。
请按此要求将比赛日程表设计成有n行和n-1列的一个表。
在表中的第i行,第j列处填入第i个选手在第j天所遇到的选手。
其中1≤i≤n,1≤j≤n-1。
[实验提示]我们可以按分治策略将所有的选手分为两半,则n个选手的比赛日程表可以通过n/2个选手的比赛日程表来决定。
递归地用这种一分为二的策略对选手进行划分,直到只剩下两个选手时,比赛日程表的制定就变得很简单。
这时只要让这两个选手进行比赛就可以了。
1 2 3 4 5 6 71 2 3 4 5 6 7 82 1 43 6 7 8 53 4 1 2 7 8 5 61 2 3 4 3 2 1 8 5 6 71 2 3 4 5 6 7 8 1 4 3 21 2 1 4 3 6 5 8 7 2 1 4 31 2 3 4 1 2 7 8 5 6 3 2 1 42 1 43 2 1 8 7 6 54 3 2 1(1)(2)(3)图1 2个、4个和8个选手的比赛日程表图1所列出的正方形表(3)是8个选手的比赛日程表。
其中左上角与左下角的两小块分别为选手1至选手4和选手5至选手8前3天的比赛日程。
据此,将左上角小块中的所有数字按其相对位置抄到右下角,又将左下角小块中的所有数字按其相对位置抄到右上角,这样我们就分别安排好了选手1至选手4和选手5至选手8在后4天的比赛日程。
依此思想容易将这个比赛日程表推广到具有任意多个选手的情形。
《算法设计与分析》实验指导书《算法设计与分析》实验指导书本文档主要用于《算法设计与分析》课程的实验指导。
《算法设计与分析》旨在教会学生处理各种问题的方法,通过实验,使学生能够把所学的方法用于具体的问题,并对所用算法进行比较分析,从而提高学生分析问题、解决问题的能力。
通过该课程的实验,使学生对课堂中所讲述的内容有一个直观的认识,更好地掌握所学的知识,培养学生的实际动手能力,加强学生创新思维能力的培养。
本课程设计了7个设计型实验。
实验内容包括用分治法、动态规划、贪心法、回溯法以及分支限界法求解问题。
一、实验内容安排二、实验基本要求实验前要求学生一定要先了解实验目的、内容、要求以及注意事项,要求学生熟悉实验对象,设计并编写相应的算法。
学生应独立完成所布置实验内容,编写代码,运行程序,记录结果并撰写实验报告。
三、实验报告要求实验结束后,应及时整理出实验报告,实验报告提交书面文档。
四、考核方式理论考试(60%)+实验(30%)+作业(10%)五、实验内容与指导实验一快速排序问题1.实验目的(1) 用分治法求解该问题。
2.实验环境PC机,要求安装Eclipse软件或VC++软件供学生实验。
3.实验内容有n个无序的数值数据,现要求将其排列成一个有序的序列。
4. 实验步骤(1) 输入实现该问题的源代码;(2) 输入测试数据,验证代码的正确性。
5.实验要求(1)做好实验预习,熟悉本实验中所使用的开发环境。
(2)写出实验报告①实验目的②实验内容③出错信息及处理方法④实验结果实验二最少硬币问题1.实验目的(1) 用动态规划求解该问题。
2.实验环境PC机,要求安装Eclipse软件或VC++软件供学生实验。
3.实验内容有n种不同面值的硬币,各硬币面值存于数组T[1:n];现用这些面值的钱来找钱;各面值的个数存在数组Num[1:n]中。
对于给定的1≤n≤10,硬币面值数组、各面值的个数及钱数m,0<=m<=2001,设计一个算法,计算找钱m的最少硬币数。
算法实验指导书12级《算法设计与分析》实验指导书本实验指导书是为配合《算法设计与分析》课程实验而编写的,其目的是使学生消化算法理论知识,加深对课堂讲授内容的理解,尤其是一些典型算法的实现及其应用,培养学生独立编程和调试程序的能力,使学生对算法的设计与分析有更深刻的认识。
一、上机实验应遵循以下步骤:(1)实验前,先准备好上机所需的程序。
手编程序应书写整齐,并经自我检查无误后才能上机。
(2)实验时,输入并调试自己所编的程序,独立上机调试,上机时出现的问题,最好能自己独立解决。
(3)实验结束后,按照规定整理出实验报告,并在规定时间内提交。
二、实验报告的内容:实验报告应该包括:实验名称、实验目的、实验题目、问题分析、程序清单、运行结果、实验结论(即算法的时间空间分析与改进建议)。
三、需写出实验报告的实验:实验一、实验四、实验五。
实验一递归与迭代算法一、实验目的与要求1、通过本实验掌握迭代算法和递归算法的基本思想及设计工作的主要步骤。
2、通过本实验加深对循环和递归过程的理解。
3、通过本实验加深对迭代过程的理解。
4、掌握两种算法策略的主要适用范围。
二、实验题目:1、求2+22+222+……+22……22(精确计算)n个22、从键盘输入任一正整数n(n>=3),打印如下图所示的n×n 方阵(下图中n=7)。
1 2 3 4 5 6 724 25 26 27 28 29 823 40 41 42 43 30 922 39 48 49 44 31 1021 38 47 46 45 32 1120 37 36 35 34 33 1219 18 17 16 15 14 133、完成给“余”猜数的游戏:心里先想好一个1~100之间的整数x,然后输入3个除数a、b、c,再输入x分别除以a、b、c后所得到的余数ra、rb、rc,计算机能求出这个数x并输出x。
4、用递归函数判断字符串str是否为“回文”。
三、实验步骤1、理解算法思想和问题要求。
《算法分析与设计》实验指导本书是为配合《算法分析与设计实验教学大纲》而编写的上机指导,其目的是使学生消化理论知识,加深讲授内容的理解,尤其是一些算法的实现及其应用,培养学生独立编程和调试程序的能力,使用学生对算法的分析与设计有更深刻的认识。
上机实验一般应包括以下几个步骤:1、准备好上机所需的程序,手编程序应书写整齐,并经人工检查无误后才能上机。
2、上机输入和调试自己所编的程序。
一人一组,独立上机调试,上机时出现的问题,最好独立解决。
3、上机结束后,整理出实验报告。
实验报告应包括:题目,程序清单,运行结果,对运行情况所作的分析。
本书共分阶段4个实验,每个实验有基本题和提高题。
基本题必须完成,提高题根据自己实际情况进行取舍。
题目不限定如下题目,可根据自己兴趣爱好做一些与实验内容相关的其它题目,如动态规划法中的图象压缩,回溯法中的人机对弈等。
其具体内容如下:实验一分治与递归(4学时)基本题一:基本递归算法一一、实验目的与要求1、熟悉C/C++语言的集成开发环境;2、通过本实验加深对递归过程的理解;二、实验内容掌握递归算法的概念和基本思想,分析结果能够用递归方法实现整数的划分。
三、实验题:任意输入一个整数,输出结果能够用递归方法实现整数的划分。
四、四实验步骤1、理解算法思想和问题要求;2、编程实现题目要求;3、上机输入和调试自己所编写的程序;4、验证分析实验结果;5、整理实验报告。
基本题二:棋盘覆盖问题一、实验目的与要求1、掌握棋盘覆盖问题的算法;2、初步掌握分治算法。
二、实验题目棋盘覆盖问题在一个2k*2k方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一个特殊棋盘。
在棋盘覆盖问题中,要用图标4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
提高题一:二分搜索一、实验目的与要求1、熟悉二分搜索算法;2、初步掌握分治算法。
二、实验题1、高a【0:n-1】是一个已排好的数组。
《算法设计与分析课程设计》指导书《算法设计与分析课程设计》实习指导书一、课程设计目的本课程设计是在学生学习《算法设计与分析》课程后,进行的一次针对具体问题进行算法设计与分析的综合训练,其目的在于加深算法设计分析的理解,掌握算法分析设计方法。
二、算法设计与分析课程设计要求1.学生必须仔细阅读《算法设计与分析课程设计》实习方案,认真主动完成课设的要求。
有问题及时主动通过各种方式与教师联系沟通。
2.学生要发挥自主学习的能力,充分利用时间,安排好课程设计的时间计划,并在课程设计过程中不断检测自己的计划完成情况,及时向教师汇报。
3.课程设计按照教学要求需要一周(5天)时间完成。
三、实验所用仪器及实验环境PC机,Codeblocks软件环境。
四、实习基本内容本次课程设计要求在(一)、(二)、(三)、(四)组中每组选择至少一个题目完成。
(一)分治策略1、输油管道问题【题目描述】某石油公司计划建造一条由西向东的主输油管道,该管道要穿过一个有n口油井的油田。
从每口油田都要有一条输油管道沿最短路径(或南或北)与主管道相连。
如果给定n口油井的位置,即它们的x坐标(东西向)和y坐标(南北向),应如何确定主管道的最优位置,即使各油井到主管道之间的输油管长度总和最小的位置?【输入】第一行是一个整数n,表示油井数量(1-1000之间),接下来n行是油井的位置,每行两个整数x和y。
【输出】各油井到主管道之间的输油管道最小长度总和。
【输入样例】51 22 21 33 -23 3【输出样例】62、船的价值问题描述:大橙子最近在玩《艦これ》,因此大橙子收集了很多很多的船(这里我们假设大橙子氪了很多金,开了无数个船位)。
去除掉重复的船之后,还剩下N(1≤N≤1,000,000)种不同的船。
每一艘船有一个稀有值,任意两艘船的稀有值都不相同,稀有值越小的船越稀有,价值也就越高。
Nettle现在通过大建又造出了一艘船,他想知道这艘船是不是重复的。
《算法设计与分析》实验指导书实验一递归与分治1、实验目的(1)掌握设计有效算法的分治策略;(2)通过合并排序和快速排序两个示例学习分治策略设计技巧。
2、实验要求(1)熟练掌握分治法的基本思想及其应用实现;(2)理解所给出的算法,并对其加以改进。
3、实验内容(1)分治法基本思想如果原问题可分割成k个子问题,1<k≤n ,且这些子问题都可解,并可利用这些子问题的解求出原问题的解。
由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。
在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。
(2)分治法--算法设计模式如下:Divide-and-Conquer(P)1) if |P|≤n02) then return(ADHOC(P))3) 将P分解为较小的子问题P1 ,P2 ,...,Pk4) for i←1 to k5) 5. do yi ← Divide-and-Conquer(Pi) △递归解决Pi6) 6. T ← MERGE(y1,y2,...,yk)△合并子问题7) return(T)4、实验方法1)合并排序:将待排序元素分成个数大致相同的2个子集合,分别对2个子集合进行排序,最终将排好序的子集合并成为所要求的排序集合。
2)快速排序:对于输入的子序列L[p..r],如果规模足够小则直接进行排序,否则分三步处理:①分解(Divide):将输入的序列L[p..r]划分成两个非空子序列L[p..q]和L[q+1..r],使L[p..q]中任一元素的值不大于L[q+1..r]中任一元素的值。
②递归求解(Conquer):通过递归调用快速排序算法分别对L[p..q]和L[q+1..r]进行排序。
③合并(Merge):由于对分解出的两个子序列的排序是就地进行的,所以在L[p..q]和L[q+1..r]都排好序后不需要执行任何计算L[p..r]就已排好序。
常熟理工学院
《算法设计与分析》实验指导与报告书
______学年第____ 学期
专业:___________________________________________ 学号:___________________________________________ 姓名:___________________________________________ 实验地点:___________________________________________ 指导教师:___________________________________________
计算机科学与工程学院
2012
实验目录
实验一求最大公约数 (4)
实验二串匹配问题 (7)
实验三斐波那契数列 (10)
实验四堆的创建与堆排序 (13)
实验五霍纳法则 (16)
实验六Warshall算法和Floyed算法 (19)
实验七最优二叉查找树 (22)
实验八解非线性方程的算法 (25)
实验一求最大公约数
实验二串匹配问题
实验三斐波那契数列
实验四堆的创建与堆排序
实验五霍纳法则
实验六Warshall算法和Floyed算法
实验七最优二叉查找树
实验八解非线性方程的算法。
算法分析与设计本书是为配合《计算机算法分析与设计》而编写的上机指导,其目的是使学生消化理论知识,加深对讲授内容的理解,增强算法分析与设计实践动手能力。
上机实验注意事项如下:(1)课前认真做好预习,准备好实验工具,熟悉实验流程和手段。
(3)课中根据实验指导书,结合课本实例进行编程实验。
实验时,一人一组,独立上机调试,上机时出现疑问,可以举手询问实验指导老师,或者与周边同学小声讨论,鼓励独立解决问题。
(4)课后按时按质按量整理出实验报告。
实验报告应独立完成,拒绝抄袭。
实验内容覆盖:递归与分治策略、动态规划、贪心算法、回溯法、分支限界法等。
实验一递归与分治策略一.实验目的与要求(1)理解和掌握递归与分治策略的基本原理。
(2)理解课本中的示例代码。
(3)调试代码通过。
二.递归与分治的基本思想(1)递归与分治方法。
递归与分治方法的基本思想是:将一个难以解决的大问题,分割成一些规模较小的、相同的子问题,以便各个击破,分而治之。
(2)递归。
递归问题分析时,要把握如下两个要素:●递归出口。
●递归公式。
其中:●递归出口给出了最简单情况下问题的解。
●递归公式则给出了一般意义下大问题(原问题)和小问题(子问题)之间的递归关系。
通过递归公式,一个难以解决的大问题会随着递归不断分解为多个小问题,小问题继续递归变为更小的小问题,直到最后到达递归出口得到解。
三.实验代码分析和说明本部分实验,需完成“棋盘覆盖”(课本P20)和“快速排序”(课本P22)两个问题。
3.1棋盘覆盖1. 棋盘覆盖问题的思路:(1)首先,将原始的棋盘覆盖问题看作最初的大问题。
(2)然后,将棋盘的行、列一分为二,从而将原始的大棋盘分为四个同样大小的小棋盘。
(3)接着,采用P21的图2-5中合适的L型骨牌,覆盖原始大棋盘的中心位置,将四个同样大小的小棋盘都转化为特殊棋盘。
(4)最后,对四个特殊小棋盘进行递归处理即可。
以上步骤(2)和步骤(3)合起来,完成了将大问题划分为小问题的过程,特别需要注意的是:小问题必须要和大问题相同或相似,否则无法递归。
算法设计与分析课程设计实验指导书一、运动员比赛日程表设有n=2k个运动员要进行网球比赛。
设计一个满足以下要求的比赛日程表:●每个选手必须与其它n-1个选手各赛一次●每个选手一天只能赛一次●循环赛一共进行n-1天1、运用分治策略,该问题的递归算法描述如下,根据算法编制程序并上机通过。
输入:运动员人数n(假定n恰好为2的i次方)输出:比赛日程表A[1..n,1..n]1. for i←1 to n //设置运动员编号2. A[i,1]←i3. end for4. Calendar(0,n) //位移为0,运动员人数为n。
过程Calendar(v, k) //v表示位移(v=起始行-1),k表示运动员人数。
1. if k=2 then //运动员人数为2个2. A[v+2,2]←A[v+1,1] //处理右下角3. A[v+1,2]←A[v+2,1]//处理右上角4. else5. Calendar(v,k/2) //假设已制定了v+1至v+k/2运动员循环赛日程表6. Calendar(v+k/2,k/2) //假设已制定了v+k/2+1至v+k运动员循环赛日程表7. comment:将2个k/2人组的解,组合成1个k人组的解。
8. for i←1 to k/29. for j←1 to k/210. A[v+i+k/2,j+k/2]←A[v+i,j] //沿对角线处理右下角11. end for12. end for13. for i←k/2+1 to k14. for j←1 to k/215. A[v+i-k/2,j+k/2]←A[v+i,j] //沿对角线处理右上角16. end for17. end for18. end if2、编制该问题的非递归算法,上机通过。
将如上文件保存在命名为“学号+姓名+实验一”的文件夹中并上传到指定的服务器。
二、最长公共子序列运用动态规划法最长公共子序列问题,给出最优值并输出最优解。
天津商业大学信息工程学院算法分析与设计实验指导书杨亮2011/3/1目录实验1:大整数运算(分治策略) (1)程序1-1. 未使用分治策略 (2)程序1-2. 使用分治策略 (3)实验2:最长公共子序列(动态规划) (5)程序2-1 自底向上方法 (6)实验3:图的最小生成树(贪心策略) (9)程序3-1 Kruskal算法 (13)程序3-2 Prim算法 (16)实验4:八皇后问题(解空间搜索方法) (19)程序4-1 回溯法与剪枝 (20)实验1:大整数运算(分治策略)实验目的:通过大整数相乘的算法实现来加深对分治策略的了解。
技术描述:在大整数相乘的算法中,如果不使用分之策略所需的时间复杂度为O(n2),而使用了动态规划思想进行重新设计后时间复杂度可以降低到O(n1.59)。
时间:100分钟实验内容:编程完成相应的大整数加法,普通乘法和使用分治策略设计的大整数乘法,比较其相应的性能差别,并完成实验报告。
算法描述:设X和Y都是n位的二进制整数,现在要计算它们的乘积XY。
我们可以用小学所学的方法来设计一个计算乘积XY的算法,但是这样做计算步骤太多,显得效率较低。
如果将每2个1位数的乘法或加法看作一步运算,那么这种方法要作O(n2)步运算才能求出乘积XY。
下面我们用分治法来设计一个更有效的大整数乘积算法。
图1-1 大整数X和Y的分段我们将n位的二进制整数X和Y各分为2段,每段的长为n/2位(为简单起见,假设n是2的幂),如图6-3所示。
由此,X=A2n/2+B ,Y=C2n/2+D。
这样,X和Y的乘积为:XY=(A2n/2+B)(C2n/2+D)=AC2n+(AD+CB)2n/2+BD (1)如果按式(1)计算XY,则我们必须进行4次n/2位整数的乘法(AC,AD,BC和BD),以及3次不超过n位的整数加法(分别对应于式(1)中的加号),此外还要做2次移位(分别对应于式(1)中乘2n和乘2n/2)。
所有这些加法和移位共用O(n)步运算。
设T(n)是2个n位整数相乘所需的运算总数,则由式(1),我们有:(2)由此可得T(n)=O(n2)。
因此,用(1)式来计算X和Y的乘积并不比小学生的方法更有效。
要想改进算法的计算复杂性,必须减少乘法次数。
为此我们把XY写成另一种形式:XY=AC2n+[(A-B)(D-C)+AC+BD]2n/2+BD (3)虽然,式(3)看起来比式(1)复杂些,但它仅需做3次n/2位整数的乘法(AC,BD和(A-B)(D-C)),6次加、减法和2次移位。
由此可得:(4)用解递归方程的套用公式法马上可得其解为T(n)=O(n log3)=O(n1.59) 程序1-1. 未使用分治策略#include <stdio.h>#include <string.h>#define MAX_LEN 200unsigned an1[MAX_LEN+10];unsigned an2[MAX_LEN+10];unsigned aResult[MAX_LEN* 2 + 10];char szLine1[MAX_LEN+10];char szLine2[MAX_LEN+10];int main(){gets( szLine1); //gets函数读取一行gets( szLine2);int i, j;int nLen1 = strlen( szLine1);memset( an1, 0, sizeof(an1));memset( an2, 0, sizeof(an2));memset( aResult, 0, sizeof(aResult));j = 0;for( i = nLen1 - 1;i >= 0 ; i --)an1[j++] = szLine1[i] - '0';int nLen2 = strlen(szLine2);j = 0;for( i = nLen2 - 1;i >= 0 ; i --)an2[j++] = szLine2[i] - '0';//每一轮都用an1的一位,去和an2各位相乘,从an1的个位开始for( i = 0;i < nLen2; i ++ ) {//用选定的an1的那一位,去乘an2的各位for( j = 0; j < nLen1; j ++ )//两数第i, j位相乘,累加到结果的第i+j位aResult[i+j] += an2[i]*an1[j];}//下面的循环统一处理进位问题int nHighestPos = 0;for( i = 0; i < MAX_LEN * 2; i ++ ){if( aResult[i] >= 10 ) {aResult[i+1] += aResult[i] / 10;aResult[i] %= 10;}if( aResult[i] ) n HighestPos = i;}for( i = nHighestPos; i >= 0; i --)printf("%d", aResult[i]);return 0;}程序1-2. 使用分治策略#include <iostream.h>#include <math.h>long mult(long x,long y,int n);int num(long x);void main() //主函数{long x,y;cout<<"input x and y:"<<endl;cin>>x>>y;cout<<mult(x,y,num(x))<<endl;}long mult(long x,long y,int n){long a,b,c,d,s;if (n==1) //起初这里落了个=号return x*y;else{a=long(x/pow(10,(n/2))); //取x的左半部分b=long(x%long(pow(10,(n/2)))); //取x的右半部分c=long(y/pow(10,(n/2))); //取y的左半部分d=long(y%long(pow(10,(n/2)))); //取y的右半部分s=mult(a,c,n)*pow(2,n)+(mult((a-b),(d-c),n)+mult(a,c,n)+mult(b,d,n))*pow(2,n/2)+mult(b,d,n); //书上的公式return (s);}}int num(long x) //判断输入的数字的位数{int i=0;if(x-9<=0)return 1;else{while (x!=0){i++;x=x/10;}return i;}}实验2:最长公共子序列(动态规划)实验目的:通过对最长公共子序列的编程实现,增强对动态规划方法的了解。
技术描述:在最优化问题的求解过程中,通常会出现大量重复计算问题,当遇到此类问题的时候,如果我们又可以容易的找到它的最优子结构,那么就可以尝试使用动态规划方法求解,动态规划方法中可以使用自底向上法和自顶向下记录法两种方法来减少重复的运算量,从而达到提高运算效率的目的。
时间:100分钟实验内容:编程用动态规划的自底向上的方法求解两个序列的最长公共子序列问题。
算法描述:求两字符序列的最长公共字符子序列,并完成实验报告。
问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列。
令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk-1”是X的子序列,存在X的一个严格递增下标序列<i0,i1,…,ik-1>,使得对所有的j=0,1,…,k-1,有xij=yj。
例如,X=“ABCBDAB”,Y=“BCDB”是X的一个子序列。
考虑最长公共子序列问题如何分解成子问题,设A=“a0,a1,…,am-1”,B=“b0,b1,…,bm-1”,并Z=“z0,z1,…,zk-1”为它们的最长公共子序列。
不难证明有以下性质:(1)如果am-1=bn-1,则zk-1=am-1=bn-1,且“z0,z1,…,zk-2”是“a0,a1,…,am-2”和“b0,b1,…,bn-2”的一个最长公共子序列;(2)如果am-1!=bn-1,则若zk-1!=am-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列;(3)如果am-1!=bn-1,则若zk-1!=bn-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列。
这样,在找A和B的公共子序列时,如有am-1=bn-1,则进一步解决一个子问题,找“a0,a1,…,am-2”和“b0,b1,…,bm-2”的一个最长公共子序列;如果am-1!=bn-1,则要解决两个子问题,找出“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列和找出“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列,再取两者中较长者作为A和B的最长公共子序列。
求解:引进一个二维数组c[][],用c[i][j]记录X[i]与Y[j] 的LCS 的长度,b[i][j]记录c[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向。
我们是自底向上进行递推计算,那么在计算c[i,j]之前,c[i-1][j-1],c[i-1][j]与c[i][j-1]均已计算出来。
此时我们根据X[i] = Y[j]还是X[i] != Y[j],就可以计算出c[i][j]。
问题的递归式写成:回溯输出最长公共子序列过程:算法分析:由于每次调用至少向上或向左(或向上向左同时)移动一步,故最多调用(m + n)次就会遇到i = 0或j = 0的情况,此时开始返回。
返回时与递归调用时方向相反,步数相同,故算法时间复杂度为Θ(m + n)。
程序2-1 自底向上方法#include <stdio.h>#include <string.h>#define MAXLEN 100void LCSLength(char *x, char *y, int m, int n, int c[][MAXLEN], int b[][MAXLEN])...{int i, j;for(i = 0; i <= m; i++)c[i][0] = 0;for(j = 1; j <= n; j++)c[0][j] = 0;for(i = 1; i<= m; i++)...{for(j = 1; j <= n; j++)...{if(x[i-1] == y[j-1])...{c[i][j] = c[i-1][j-1] + 1;b[i][j] = 0;}else if(c[i-1][j] >= c[i][j-1])...{c[i][j] = c[i-1][j];b[i][j] = 1;}else...{c[i][j] = c[i][j-1];b[i][j] = -1;}}}}void PrintLCS(int b[][MAXLEN], char *x, int i, int j) ...{if(i == 0 || j == 0)return;if(b[i][j] == 0)...{PrintLCS(b, x, i-1, j-1);printf("%c ", x[i-1]);}else if(b[i][j] == 1)PrintLCS(b, x, i-1, j);elsePrintLCS(b, x, i, j-1);}int main(int argc, char **argv)...{char x[MAXLEN] = ...{"ABCBDAB"};char y[MAXLEN] = ...{"BDCABA"};int b[MAXLEN][MAXLEN];int c[MAXLEN][MAXLEN];int m, n;m = strlen(x);n = strlen(y);LCSLength(x, y, m, n, c, b);PrintLCS(b, x, m, n);return 0;}实验3:图的最小生成树(贪心策略)实验目的:通过编程实现最小生成树,增强对贪心策略的理解 。