在定义一个过程或者函数时,出现调用本过程或本函数的成分,称之为递归。如果调用自身,称之为直接递归;
若过程或者函数p调用过程或者函数q,而q又调用p,称之为间接递归;
任何间接递归都可以等价地转换为直接递归;
如果一个递归过程或递归函数中递归调用语句是最后一条执行语句,则称这种递归为尾递归;
可以使用递归解决的问题,应该满足以下三个特点:
一般来说,在以下三种情况下,常常使用到递归的方法:
递归模型是对递归问题的抽象,它反映一个递归问题的递归结构;
一般来说,递归模型有两部分组成:递归出口和递归体。前者决定递归过程何时结束,后者确定递归如何进行;
如果{P(1),P(2),P(3),…,P(n)}是命题序列,且满足以下两个性质,则所有命题为真:
如果{P(1),P(2),P(3),…,P(n)}是命题序列且满足以下两个性质,则所有命题均为真:
数学归纳法是一种论证方法,而递归是算法和程序设计的一种实现技巧,数学归纳法是递归的基础;
递归算法设计的核心是给出递归模型:
前面提到递归处理手法的使用场景:问题定义、数据结构、求解方法;实际上围绕这三个点,我们就可以对其实施递归算法设计的一般步骤了;
对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小的时候)则直接解决,否则将其分解为K个规模较小的子问题。这些子问题相互独立且与原问题形式相同,递归地解决这些子问题,然后将各个子问题的合并得到原问题的解;
分治法通常采用递归算法设计技术,在每一层递归上都包含三个步骤:
蛮力法是一种简单直接地解决问题的方法,通常根据问题的描述和所涉及的概念定义找出所有可能的解;然后选择其中一种或者多种解进行测试,如果该解不可行,则探寻下一种可能的解;
一个复杂问题的解决方案是由若干个小的决策步骤组成的决策序列;解决一个问题的所有可能的决策序列构成该问题的解空间;
应用回溯法解决问题时,首先应该明确问题的解空间。解空间中满足约束条件的决策序列称为可行解;
一般来说,解任何问题都有一个目标,在约束条件下使目标达成的最优的可行解成为该问题的最优解;
问题的解有一个不等长或者等长的解向量X={x1,x2,x3…xn}构成,其中xi表示第i步的决策;所有满足约束条件的解向量组构成问题的解空间;
问题的解空间一般用树来表示,也称为解空间树或者状态树。树中的每一个结点确定所求解问题的一个问题状态;
解空间树通常有两种类型:
而针对两种解空间树的类型,回溯法通常求解两类问题:找所有解和找最优解;
在包含问题所有解的解空间树中,按照深度优先搜索策略,从根结点出发搜索解空间树的方法;它体现了走不通就退回再走的思路;
回溯法在搜索解空间时,通常采用两种策略避免无效搜索,提高回溯的搜索效率:
限界函数和约束函数都属于剪枝函数;剪枝函数存在的意义基于该观点:我们往往只需要解空间中的部分树或者最优的数;
也就是说,回溯法=深度优先搜索+剪枝;
分枝限界法类似于回溯法,也是在问题对的额解空间树上搜索问题解的算法;在一般情况下,分枝限界法与回溯法的求解目标并不相同;回溯法的目标是找出解空间中满足约束条件的所有解;分枝限界法的目标则是找出满足约束条件的一个解;或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解;
所为分枝,就是采用广度优先的策略,依次搜索活结点的所有分枝,也就是所有相邻结点;采用一个限界函数,计算限界函数值,选择一个最有利的子结点作为扩展结点,使搜索朝着解空间树上有最优解的分枝推进,以便尽快地找出一个最优解;
分枝限界法和回溯法的主要区别:
方法 | 回溯法 | 分枝限界法 |
---|---|---|
解空间搜索方法 | 深度优先 | 广度优先 |
存储结点的数据结构 | 栈 | 队列、优先队列 |
结点存储特性 | 活结点的所有可行子结点被遍历后才从栈中出栈 | 每个节点只有一次成为活结点的机会 |
常用应用 | 找出满足条件的所有解 | 找出满足条件的一个解或者特定意义的最优解 |
在所有解空间树时,每个活结点可能有很多孩子结点,其中有些孩子结点搜索下去是不可能产生问题解或者最优解的;好的限界函数在扩展时将删除这些不必要的孩子结点从而提高搜索效率:
根据选择下一个扩展结点的方式来组织活结点表,不同的活结点表对应不同的分枝搜索方式:
分枝限界法在搜索解空间树时,结点的处理是跳跃式的,回溯也不是单纯地沿着双亲结点一层一层地向上回溯;具体有两种方式确定最优解的解向量:
贪心法的基本思路是在求解问题时总是做出当前看来最好的选择,也就是说贪心法不从整体最优上考虑,所做出的仅是在某种意义上的局部最优选择;
但是人们通常希望得到整体最优解,所以在使用贪心法解决问题时需要证明所设计的算法确实是整体最优解或求解了它要解决的问题;
贪心法从问题的某一个初始解出发,采用逐步构造最优解的方法向给定目标前进,每一步都产生n元最优解向量的一个分量;
贪心法在每一步决策时所用的依据称为最优量度标准,也称为贪心准则;
每一次贪心选择都将问题简化为规模更小的子问题,并期望每次所做的局部最优选择产生出一个全局最优解;
所谓贪心选择性质是指问题的整体最优解可以通过一系列局部最优解的选择,也就是贪心选择来达到;
贪心法仅在当前状态下做出最好选择,即局部最优选择,然后再去求解做出这个选择后产生的相应子问题的最优解;
如果一个问题的最优解包含其子问题的最优解,则称此问题具有最优子结构性质;问题的最优子结构性质是该问题可以通过动态规划算法或者贪心法求解的关键特性;
动态规划是一种多阶段决策问题的优化方法;将多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解;
能采用动态规划问题求解的问题,一般具有3个性质:
实际应用中简化的步骤:
动态规划思想和分治法类似,都是将待求解问题分解为若干个子问题(阶段),然后按顺序求解子阶段,前一子问题为后一字问题的求解提供了有用的信息;
在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题的解就是初始问题的解;
动态规划又和贪心法有些类似,在动态规划中,可以将一个问题的解决方案视为一系列决策的结果;不同的是在贪心法中,每采用一次贪心准则就做出一个不可回溯的决策,还需要考察每个最优决策序列中是否包含一个最优子序列;