算法各种算法总结.docx
《算法各种算法总结.docx》由会员分享,可在线阅读,更多相关《算法各种算法总结.docx(13页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、(1)用计算机求解问题的步骤:1、问题分析2、数学模型建立3、算法设计与选择4、算法指标5、算法分析6、算法实现7、 程序调试8、结果整理文档编制(2)算法定义:算法是指在解决问题时,依据某种机械步骤肯定可以得到问题结果的处理 过程(3)算法的三要素1、操作2、掌握结构3、数据结构算法具有以下5个属性:有穷性:一个算法必需总是在执行有穷步之后结束,且每一步都在有穷时间内完成。确定性:算法中每一条指令必需有准确的含义。不存在二义性。只有一个入口和一个出可行性:一个算法是可行的就是算法描述的操作是可以通过已经实现的基本运算执行有 限次来实现的。输入:一个算法有零个或多个输入,这些输入取自于某个特定
2、对象的集合。输出:一个算法有一个或多个输出,这些输出同输入有着某些特定关系的量。算法设计的质量指标:正确性:算法应满足详细问题的需求;可读性:算法应当好读,以有利于读者对程序的理解;健壮性:算法应具有容错处理,当输入为非法数据时,算法应对其作出反响,而不是产 生莫名其妙的输出结果。效率与存储量需求:效率指的是算法执行的时间;存储量需求指算法执行过程中所需要 的最大存储空间。一般这两者与问题的规模有关。常常采纳的算法主要有迭代法、分而治之法、贪欲法、动态规划法、回溯法、分支限界法迭代法 也称“辗转法”,是一种不断用变量的旧值递推出新值的解决问题的方 法。采用迭代算法解决问题,需要做好以下三个方面
3、的工作:一、确定迭代模型。在可以用迭代算法解决的问题中,至少存在一个直接或 间接地不断由旧值递推出新值的变量,这个变量就是迭代变量。二、建立迭代关系式。所谓迭代关系式,指如何从变量的前一个值推出其下 一个值的公式(或关系)。迭代关系式的建立是解决迭代问题的关键,通常可以 使用递推或倒推的方法来完成。三、对迭代过程进行掌握。在什么时候结束迭代过程?这是编写迭代程序必 需考虑的问题。不能让迭代过程无休止地重复执行下去。迭代过程的掌握通常可 分为两种状况:一种是所需的迭代次数是个确定的值,可以计算出来;另一种是 所需的迭代次数无法确定。对于前一种状况,可以构建一个固定次数的循环来实 现对迭代过程的掌
4、握;对于后一种状况,需要进一步分析出用来结束迭代过程的 条件。编写计算斐波那契(Fibonacci)数列的第n项函数fib (n)o斐波那契数列为:0、1、1、2、3、,即:fib (0)=0;fib(l)=l;f ib (n) =f ib (n-l) +f ib (n-2)(当 nl 时)。写成递归函数有:scanf(%c,&awn);if (awn=,Q|awn=q) exit(O);queen_all(k+l,n);ai=bk+i=cn+k-i; )采纳递归方法找一个解与找全部解稍有不同,在找一个解的算法中,递归算法要对当 前候选解最终是否能成为解要有回答。当它成为最终解时,递归函数就不
5、再递归摸索,马上 返回;假设不能成为解,就得连续摸索。设函数queen_one()返回1表示找到解,返回。表示 当前候选解不能成为解。细节见以下函数。【程序】# define MAXN 20int n;int colMAXN+1 ,aM AXN+1 ,b2*M AXN+1 ,c2*M AXN+1 ;int queen_one(int k,int n) int i,found;i=found=0;While (!found&i i+;if (ai&bk+i&cn+k-i) colk=i;ai=bk+i=cn+k-i=O;if (k=n) return 1; elsefound=queen_one
6、(k+ l,n); ai=bk+i=cn+k-i=l;) return found;)分支定界法:分支限界法:这是一种用于求解组合优化问题的排解非解的搜寻算法。类似于回溯法,分枝定界法在搜寻 解空间时、也常常使用树形结构来组织解空间。然而与回溯法不同的是,回溯算法使用深度 优先方法搜寻树结构,而分枝定界一般用宽度优先或最小耗费方法来搜寻这些树。因此,可 以很简洁比拟回溯法与分枝定界法的异同。相对而言,分枝定界算法的解空间比回溯法大得 多,因此当内存容量有限时,回溯法胜利的可能性更大。算法思想:分枝定界(branch and bound)是另一种系统地搜寻解空间的方法,它与回溯法 的主要区分在于
7、对E-节点的扩充方式。每个活节点有且仅有一次机会变成E-节点。当一个 节点变为E.节点时,那么生成从该节点移动一步即可到达的全部新节点。在生成的节点中, 抛弃那些不行能导出(最优)可行解的节点,其余节点加入活节点表,然后从表中选择一个 节点作为下一个E-节点。从活节点表中取出所选择的节点并进行扩充,直到找到解或活动 表为空,扩充过程才结束。有两种常用的方法可用来选择下一个E-节点(虽然也可能存在其他的方法):1)先进先出(FIFO)即从活节点表中取出节点的挨次与加入节点的挨次相同,因此活 节点表的性质与队列相同。2)最小耗费或最大收益法在这种模式中,每个节点都有一个对应的耗费或收益。假如查找
8、一个具有最小耗费的解,那么活节点表可用最小堆来建立,下一个E-节点就是具有最小耗费 的活节点;假如盼望搜寻一个具有最大收益的解,那么可用最大堆来构造活节点表,下一个E-节点是具有最大收益的活节点装载问题用一个队列Q来存放活结点表,Q中weight 表示每个活结点所相应的当前载重量。当 weight = - 1时,表示队列已到达解空间树 同一层结点的尾部。算法首先检测当前扩展结点的左儿子结 点是否为可行结点。假如是那么将其加入到活 结点队列中。然后将其右儿子结点加入到活 结点队列中(右儿子结点肯定是可行结点)。2 个儿子结点都产生后,当前扩展结点被舍 弃。活结点队列中的队首元素被取出作为 当前扩
9、展结点,由于队列中每一层结点之后 都有一个尾部标记-1,故在取队首元素时, 活结点队列肯定不空。当取出的元素是-1 时,再推断当前队列是否为空。假如队列非 空,那么将尾部标记-1加入活结点队列,算法 开头处理下一层的活结点。/*该版本只算出最优解.*/#include#includestructQueueint weight ;struct Queue* next ;int bestw = 0 ; /目前的最优值Queue* Q; /活 结点队列 Queue* lq = NULL Queue* fq = NULL ;int Add(int w) Queue* q ;q = (Queue*)ma
10、lloc(sizeof(Queue);if(q=NULL) printf(M没有足够的空间安排 nn) ; return 1 ;q-next = NULL ;q-weight =w ;if(Q-next = NULL) Q-next = q ; fq = lq = Q-next ; /肯定要使元素放到 链中else lq-next = q ; lq = q ;/ lq = q-next;return 0 ;int IsEmpty() if(Q-next=NULL) return 1 ;return 0 ;int Delete(int&w) Queue* tmp = NULL ;/ fq = Q
11、-next ;tmp = fq ;w = fq-weight ;Q-next 二 fq-next ; /*肯定不能 丢了链表头*/fq = fq-next ;free(tmp) ;returnE-节点是具有最大收益的活节点装载问题用一个队列Q来存放活结点表,Q中weight 表示每个活结点所相应的当前载重量。当 weight = - 1时,表示队列已到达解空间树 同一层结点的尾部。算法首先检测当前扩展结点的左儿子结 点是否为可行结点。假如是那么将其加入到活 结点队列中。然后将其右儿子结点加入到活 结点队列中(右儿子结点肯定是可行结点)。2 个儿子结点都产生后,当前扩展结点被舍 弃。活结点队列中
12、的队首元素被取出作为 当前扩展结点,由于队列中每一层结点之后 都有一个尾部标记-1,故在取队首元素时, 活结点队列肯定不空。当取出的元素是-1 时,再推断当前队列是否为空。假如队列非 空,那么将尾部标记-1加入活结点队列,算法 开头处理下一层的活结点。/*该版本只算出最优解.*/#include#includestructQueueint weight ;struct Queue* next ;int bestw = 0 ; /目前的最优值Queue* Q; /活 结点队列 Queue* lq = NULL Queue* fq = NULL ;int Add(int w) Queue* q ;
13、q = (Queue*)malloc(sizeof(Queue);if(q=NULL) printf(M没有足够的空间安排 nn) ; return 1 ;q-next = NULL ;q-weight =w ;if(Q-next = NULL) Q-next = q ; fq = lq = Q-next ; /肯定要使元素放到 链中else lq-next = q ; lq = q ;/ lq = q-next;return 0 ;int IsEmpty() if(Q-next=NULL) return 1 ;return 0 ;int Delete(int&w) Queue* tmp =
14、NULL ;/ fq = Q-next ;tmp = fq ;w = fq-weight ;Q-next 二 fq-next ; /*肯定不能 丢了链表头*/fq = fq-next ;free(tmp) ;return0 ;void EnQueue(int wt, int& bestw, int i,intn)/该函数负责加入活结点假如不是 叶结点,那么将结点权值wt加入队列Qif(i = n) 叶子 if (wtbestw) bestw = wt;else Add(wt); / 不是叶子int MaxLoading(int w, int c, int n) / 返回 最优装载值为层次1初始
15、化int err ; 返 回值inti=l;当前扩展结点的层int Ew 二 0; /当前扩展结点的权值bestw=0;目前 的 最 优 值 Q = (Queue*)malloc(sizeof(Queue) ;Q-next = NULL ;Q-weight = -1 ;err = Add(-l); 标记 本层的尾部 if(err) return 0 ; while (true) 检查左孩子结点if (Ew + wi = c) / xi = 1 EnQueue(Ew + wi, bestw , i, n); /右孩子总是可行的 EnQueue(Ew, bestw, i, n); / xi = 0
16、 Delete(Ew); / 取下 一个扩展结点if (Ew=-1) /到达层的尾部 if (IsEmptyO) return bestw; if(in) Add(-l); / 同层结点的 尾部 Delete(Ew); /取下一扩展结 点i+;进入下一层 int main()int n =0 ; int c = 0 ;int i = 0 ;int* w ;FILE *in , *out ;in = fopen(input.txt , nrn) ;out 二 fopen(output.txt” , nwH) ;if(in=NULL|out=NULL) printf(n 没有输入输出文件n”);
17、return 1 ;fscanf(in , -d” , &n) ;fscanf(in , d” , &c) ;w = (int*)malloc(sizeof(int)*(n-i-l) ;for(i =1 ; il) return fib (n-l)+fib(n-2);)一个饲养场引进一只刚诞生的新品种兔子,这种兔子从诞生的下一个月开头, 每月新生一只兔子,新生的兔子也如此繁殖。假如全部的兔子都不死去,问到 第12个月时,该饲养场共有兔子多少只?分析:这是一个典型的递推问题。我们不妨假设第1个月时兔子的只数为 u 1 ,第2个月时兔子的只数为u 2 ,第3个月时兔子的只数为u 3 , 依据题意,
18、“这种兔子从诞生的下一个月开头,每月新生一只兔子”,那么有u 1 = 1 , u2 = ul+ulXl = 2, u3 = u2 + u2Xl = 4 ,依据这个规律,可以归纳出下面的递x=l推公式:for i=2 to 12u n = u n 1 X 2 (nN 2)y=x*2对应un和un 1 ,定义两 x=y个迭代变量y和x ,可将上面的递next i推公式转换成如下迭代关系:print yy=x*2endx二y让计算机对这个迭代关系重复执行11次,就可以算出第12个月时的兔子数。参考程序如下:cis分治法1、分治法的基本思想任何一个可以用计算机求解的问题所需的计算时间都与其规模N有关。
19、问题 的规模越小,越简洁直接求解,解题所需的计算时间也越少。例如,对于n个元素的 排序问题,当n=l时,不需任何计算;n=2时,只要作一次比拟即可排好序;n=3时 只要作3次比拟即可,。而当n较大时,问题就不那么简洁处理了。要想直接解决 一个规模较大的问题,有时是相当困难的。分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的 相同问题,以便各个击破,分而治之。分治法所能解决的问题一般具有以下几个特征:(1)该问题的规模缩小到肯定的程度就可以简洁地解决;(2)该问题可以分解为假设干个规模较小的相同问题,即该问题具有最优子结 构性质;(3)采用该问题分解出的子问题的解可以合并为该
20、问题的解;(4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共 的子子问题。3、分治法的基本步骤分治法在每一层递归上都有三个步骤:(1)分解:将原问题分解为假设干个规模较小,相互独立,与原问题形式相同 的子问题;(2)解决:假设子问题规模较小而简洁被解决那么直接解,否那么递归地解各个子 问题;(3)合并:将各个子问题的解合并为原问题的解。快速排序在这种方法中,n个元素被分成三段(组):左段left,右段right和中段middle。中 段仅包含一个元素。左段中各元素都小于等于中段元素,右段中各元素都大于等于中段元素。 因此1 e f t和r i g h t中的元素可以独立排序,
21、并且不必对因f t和r i g h t的排序结果进行合 并。middle中的元素被称为支点(pivot)。图1 4 - 9中给出了快速排序的伪代码。/使用快速排序方法对a 0 :n- 1 排序从a 0 :n- 1 中选择一个元素作为middle,该元素为支点把余下的元素分割为两段left和right,使得left中的元素都小于等于支点,而right 中的元素都大于等于支点递归地使用快速排序方法对left进行排序递归地使用快速排序方法对Fght进行排序所得结果为 left + middle + right考察元素序列4,8,3,7 , 1 , 5,6,2 。假设选择元素6作为支点,那么6位于m
22、i d d 1 e; 4, 3, 1, 5, 2位于left; 8, 7位于right。当left排好序后,所得结果为1, 2, 3, 4, 5;当rig hi排好序后,所得结果为7, 8。把right中的元素放在支点元素之后,left中 的元素放在支点元素之前,即可得到最终的结果1,2,3,4,5,6,7,8。把元素序列划分为left、middle和right可以就地进行(见程序14-6)。在程序 146中,支点总是取位置1中的元素。也可以采纳其他选择方式来提高排序性能,本章稍后局部将给出这样一种选择。程序14-6快速排序templatevoid QuickSort(Ta, int n)/对
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 各种 总结
限制150内