递推

来源:互联网 发布:源码包安装php 编辑:程序博客网 时间:2024/04/29 14:45

递推概述

  1. 递推的概念
    递推是一种应用非常广泛的常用算法之一,与递归有着密切的联系。
    在纷繁变幻的世界,所有事物都随时间的流逝发生着微妙的变化。许多现象的变化是有规律可循的,这种规律往往呈现出前因后果的关系。某种现象的变化结果与紧靠它前面变化的一个或一些结果紧密关联。递推的思想正体现了这一变化规律。

  2. 递推算法
    所谓递推,是在命题归纳时,可以由n−k,…,n−1的情形推得n的情形。
    递推关系是一种高效的数学模型,是组合数学中的一个重要解题方法,在组合计数中有着广泛的应用。在概率方面利用递推可以解决一类基本事件个数较大的概率问题。在对多项式的求解过程中,很多情况可以使用递推算法来实现。 在行列式方面,某些n阶行列式只用初等变换难以解决,但如果采用递推求解则显得较为容易。
    递推关系不仅在各数学分支中发挥着重要的作用,由它所体现出来的递推思想在各学科领域中更是显示出其独特的魅力。
    递推是利用问题本身所具有的一种递推关系求解问题的一种方法。设要求问题规模为n的解,当n=1时,解或为已知,或能非常方便地得到解。能采用递推法构造算法的递推性质,能从已求得的规模为1,2,…,i−1的一系列解,构造出问题规模为i的解。这样,程序可从i=0或i=1出发,重复地由已知至i−1规模的解,通过递推,获得规模为i的解,直至得到规模为n的解。
    递推算法的基本思想是把一个复杂的庞大的计算过程转化为简单过程的多次重复,该算法充分利用了计算机的运算速度快和不知疲倦的特点,从头开始一步步地推出问题最终的结果。使用递推算法编程,既可使程序简练,又可节省计算时间。
    对于一个序列来说,如果已知它的通项公式,那么要求出数列中某项之值或求数列的前n项之和是简单的。但是,在许多情况下,要得到数列的通项公式是困难的,甚至无法得到。然而,一个有规律的数列的相邻位置上的数据项之间通常存在着一定的关系,可以借助已知的项,利用特定的关系逐项推算出它的后继项的值,直到找到所需的那一项为止。递推算法避开了求通项公项的麻烦,把一个复杂的问题的求解,分解成连续的若干步简单运算。
    递推算法的首要问题是得到相邻的数据项之间的关系,即递推关系。它针对这样一类问题:问题的解决可以分为若干步骤,每个步骤都产生一个子解(部分结果),每个子解都是由前面若干子解生成。不同的子解,其所相关的问题规模也随子解不同而递增。我们把这种由前面的子解得出后面的子解的规则称为递推关系。
    我们在设计求解问题前,要通过细心的观察,丰富的联想,不断尝试推理,尽可能归纳总结其内在规律,然后再把这种规律性的东西抽象成递推数学模型。

  3. 递推实施步骤与描述
    利用递推求解实际问题,需要掌握递推的具体描述及其实施步骤。
    1.实施递推的步骤
    (1)确定递推变量
    应用递推算法解决问题,要根据问题的具体实际设置递推变量。递推变量可以是简单变量,也可以是一维或多维数组。
    (2)建立递推关系
    递推关系是指如何从变量的前一些值推出其下一个值或从变量的后一些值推出其上一个值的公式(或关系)。递推关系是递推的依据,是解决递推问题的关键。有些问题,其递推关系是明确的,大多数实际问题并没有现成的明确的递推关系,需根据问题的具体实际,细心的观察,丰富的联想,不断尝试推理,才能确定问题的递推关系。
    (3)确定初始(边界)条件
    对所确定的递推变量,要根据问题最简单情形的数据确定递推变量的初始(边界)值,这是递推的基础。
    (4)对递推过程进行控制
    递推过程不能无休止地重复执行下去。递推过程在什么时候结束,满足什么条件结束,这是编写递推算法必须考虑的问题。
    递推过程的控制通常可分为两种情形:一种是所需的递推次数是确定的值,可以计算出来;另一种是所需的递推次数无法确定。对于前一种情况,可以构建一个固定次数的循环来实现对递推过程的控制;对于后一种情况,需要进一步分析出用来结束递推过程的条件。
    2.递推算法框架描述
    递推通常由循环来实现,一般在循环外确定初始(边界)条件,在设置的循环中实施递推。
    下面归纳常用的递推模式并作简要的框架描述。
    首先,从递推流向可分为顺推与逆推。
    (1)简单顺推算法
    顺推即从前往后推,从已求得的规模为1,2,…,i−1的一系列解,推出问题规模为i的解,直至得到规模为n的解。
    简单顺推算法框架描述:
    f(1−i−1)=<初始值>; // 确定初始值
    for(k=i;k<=n;k++)
    f(k)=<递推关系式>; // 根据递推关系实施递推
    printf(f(n)); // 输出n规模的解f(n)
    (2)简单逆推算法
    逆推即从后往前推,从已求得的规模为n,n−1,…,i+1的一系列解,推出问题规模为i的解,直至得到规模为1的解。
    简单逆推算法框架描述:
    f(n—i+1)=<初始值>; // 确定初始值
    for(k=i;k>=1;k−−)
    f(k)=<递推关系式>; // 根据递推关系实施递推
    printf(f(1)); // 输出解f(1)
    简单递推问题设置一维数组实现,较复杂的递推问题需设置二维或二维以上数组。例如当规模为i的解为规模为1,2,…,i−1的解通过计算处理决定时,可设置二重循环处理这一较为复杂的递推。
    (3)二维数组顺推算法
    设递推的二维数组为f(k,j),1≤k≤n,1≤j≤m,由初始条件分别求得f(1,1),f(1,2),…,f(1,m),需求f(n,m),则据给定的递推关系由初始条件依次顺推得f(2,1),f(2,2),…, f(2,m);f(3,1),f(3,2),…, f(3,m);…,直至得到所要求的解f(n,m)。
    二维数组顺推算法框架描述:
    f(1,1−m)=<初始值>; // 赋初始值
    for(k=2;k<=n;k++)
    for(j=1;j<=m;j++)
    f(k,j)=<递推关系式>; // 根据递推关系实施递推
    printf(f(n,m)); // 输出n规模的解f(n,m)
    二维或二维以上数组递推常用于动态规划设计的最优值求解过程。当递推关系包含两个或两个以上关系式时,通常应用多关系分级递推算法求解。
    (4)多关系分级递推算法
    f(1−i−1)=<初始值>; // 赋初始值
    for(k=i;k<=n;k++)
    { if(<条件1>)
    f(k)=<递推关系式1>; // 根据递推关系1实施递推
    if(<条件2>)
    f(k)=<递推关系式2>; // 根据递推关系2实施递推
    ……
    if(<条件m>)
    f(k)=<递推关系式m>; // 根据递推关系m实施递推
    }
    printf(f(n)); // 输出n规模的解f(n)
    关于递推的时间复杂度,如果在一重循环中可完成递推,通常其相应的时间复杂度为O(n)。在实际应用中,由于递推关系的不同,往往需要二重或更复杂的循环结构才能完成递推,其相应的时间复杂度为O(n2)或更高。
0 0
原创粉丝点击