复杂递归算法的示例


14

我正在向一个朋友解释著名的确定性线性时间选择算法(中值算法的中位数)。

该算法的递归(非常简单)非常复杂。有两个递归调用,每个递归调用具有不同的参数。

我试图找到这种有趣的递归算法的其他示例,但找不到任何示例。我可以提出的所有递归算法要么是简单的尾部递归,要么是简单的分而治之(两个调用是“相同的”)。

您能否举一些复杂的递归示例?


使用广度优先搜索遍历迷宫或更一般的图形是有趣的递归的简单示例。

utdiscant,我认为BFS不适合我的问题,因为它可以使用队列和while循环轻松自然地实现。
elektronaj 2012年

在解决难题和解析时回溯呢?排名和取消排名算法也具有非标准的递归。
乌里2012年

记忆算法?
卡夫

2
@vzn:队列不能替换堆栈。BFS是一个特例。
拉斐尔

Answers:


15

我最喜欢的重复出现在输出敏感算法中,用于计算凸包,首先是Kirkpatrick和Seidel,后来又被其他人重复。设表示当凸包具有个顶点时计算平面中个点的凸包的时间。(除了琐碎的边界之外,的值是未知的。)Kirkpatrick和Seidel的算法产生递归 其中和并且ñ ħ ħ ħ Ñ Ť Ñ ħ = { Ô Ñ 如果  ñ 3  或  ħ 3 Ť Ñ 1ħ 1+ Ť Ñ 2ħ 2+ O n 否则为 n 1n 2ŤñHñHHHñ

T(n,h)={O(ñ如果 ñ3 要么 H3Ťñ1个H1个+Ťñ2H2+Øñ除此以外
Ñ 1 + Ñ 2 = Ñ ħ 1 + ħ 2 = ħñ1个ñ23ñ/4ñ1个+ñ2=ñH1个+H2=H

解为。这有点令人惊讶,因为不是参数被平均分配。但是实际上,当和都大约为时,会发生最坏的情况。如果以某种方式神奇地使始终恒定,则解将为。h h 1 h 2 h / 2 h 1 T n h = O n ŤñH=Øñ日志HHH1个H2H/2H1个ŤñH=Øñ

我在第一批计算拓扑论文中使用了这种重复的变体: 其中和。同样,解为,最坏的情况是和始终均分时。

ŤñG={Øñ如果 ñ3 要么 G=0Ťñ1个G1个+Ťñ2G2+Ø{ñ1个ñ2}除此以外
ñ1个+ñ2=ñG1个+G2=GØñ日志GñG

我遇到条件“ if或 ”的问题;在这里是什么意思?是否存在全局有界常数,在一种情况下,和必须被削弱以终止(并且作者不必费心给它们)。因为如果我按字面意义阅读它(即以与在同一行中相同的方式解释两个,则两个永远不会或总是发生(我什至不确定)。恕我直言,滥用符号太过分了。ñ=Ø1个H=Ø1个ØñHØ1个Øñ
拉斐尔

1
抱歉,我已经编辑了答案以弄清楚。 表示“您喜欢的常数”。我在修订版中使用了,但也可以使用。Ø1个31010100
JeffE 2012年

您是如何在计算拓扑文件中绘制这些图的?
user119264 2014年

12

我在Aggarwal 等人的论文 “用于计算凸多边形的Voronoi图的线性时间算法”中使用的递归也很复杂。

这里是对本文算法的描述。如果从描述中不清楚,则在第3步中将红色点分为深红色和石榴石点。步骤1、3和6均为线性时间。我们还知道,如果是总点数,,和对于某些。ñ||αñ|[R|βñ|C|γñαβγ>0

我会让您弄清楚为什么整个算法需要线性时间。

  1. 将原始点划分为蓝色和红色集合B和R。
  2. 递归计算蓝点的凸包。
  3. 使用蓝色船体的结构,选择深红色点C。
  4. 一次将深红色点添加到蓝色船体中。
  5. 递归计算石榴石点G的凸包。
  6. 将此石榴石外壳与步骤4的扩展蓝色外壳合并。

使算法呈线性的是能够以恒定的每点成本将固定比例的红色点添加到蓝色船体的能力。添加的点是深红色点。

因此,递归为 ,而您不知道和但保证。

Ťñ=Ť||+Ť|G|+Øñ
|||G|||+|G|1个-γñ


6

RNA二级结构预测中使用了一堆很酷的递归算法[1],[2]。留给它自己的装置,RNA链将与其自身形成碱基对。[3]中的一个相对简单的示例计算了RNA字符串将与其自身形成的嵌套,配对碱基的最大数目:

中号一世Ĵ=一种X一世ķ<Ĵ-大号一世ñ{中号一世ķ-1个+中号ķ+1个Ĵ-1个+1个中号一世Ĵ-1个


  1. M. Zuker,P. Stiegler(1981)使用热力学和辅助信息对大型RNA序列进行最佳计算机折叠

  2. E. Rivas,SR Eddy(1999)提出的包括假结在内的RNA结构预测的动态编程算法。

  3. R. Nussinov,AB Jacobson(1980)预测单链RNA二级结构的快速算法


这里提出的一个相关的复杂性很高,因为它具有三个相互依赖的(动态编程)递归。
拉斐尔

4

我仍然不太了解您所说的“复杂递归”的含义。例如,FFT算法中的递归步骤非常复杂!

但是,如果您要查找更复杂的递归,则相互递归可能是一个可能的答案。使用功能性编程语言时,相互递归很有用。相互递归是递归下降解析器的关键特征。


嗯,FFT(Cooley-Tukey的最简单形式)的递归是“标准”分而治之。从其O(nlogn)复杂度可以明显看出。2个递归调用(1为偶数,1为几率)有些“相同”。
elektronaj 2012年

3

我的头顶上,麦卡锡91功能

F(N) = 
    n - 100    if n > 100
    F(F(n+11)) if n <= 100

阿克曼函数

A(m, n) = 
    n + 1             if m = 0
    A(m-1, 1)         if m > 0 and n = 0
    A(m-1, A(m, n-1)) if m > 0 and n > 0

可能算作另类的,尽管具有玩具般的递归功能。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.