Recursion 如何使用主定理来描述递归?

Recursion 如何使用主定理来描述递归?,recursion,recurrence,master-theorem,Recursion,Recurrence,Master Theorem,最近我一直在研究递归;如何编写它,分析它,等等。有一段时间我一直认为递归和递归是同一回事,但最近的家庭作业和测验中的一些问题让我认为有细微的区别,“递归”是描述递归程序或函数的方式 直到最近,我才意识到有一种叫做“主定理”的东西被用来编写问题或程序的“递归”。我一直在阅读维基百科的页面,但和往常一样,事情的措辞让我不太明白它在说什么。我通过例子学习得更好 因此,有几个问题: 假设您被赋予了这种重复性: r(n)=2*r(n-2)+r(n-1) r(1)=r(2) =1 事实上,这是主定理的形式吗

最近我一直在研究递归;如何编写它,分析它,等等。有一段时间我一直认为递归和递归是同一回事,但最近的家庭作业和测验中的一些问题让我认为有细微的区别,“递归”是描述递归程序或函数的方式

直到最近,我才意识到有一种叫做“主定理”的东西被用来编写问题或程序的“递归”。我一直在阅读维基百科的页面,但和往常一样,事情的措辞让我不太明白它在说什么。我通过例子学习得更好

因此,有几个问题: 假设您被赋予了这种重复性:

r(n)=2*r(n-2)+r(n-1)
r(1)=r(2) =1

事实上,这是主定理的形式吗?如果是的话,换句话说,它在说什么?如果您正试图基于此递归编写一个小程序或递归树,那会是什么样子?我应该试着用数字代入,看到一个模式,然后写伪代码递归地创建这个模式,或者,因为这可能是主定理的形式,有没有更直接的数学方法

现在,让我们假设您被要求查找递归T(n),以计算由上一个递归创建的程序执行的添加数。我可以看到基本情况可能是T(1)=T(2)=0,但我不确定从那里开始

基本上,我是在问如何从给定的循环到代码,反之亦然。因为这看起来像是主定理,我想知道是否有一个简单的数学方法来处理它

编辑:好的,我已经浏览了我过去的一些作业,以找到另一个例子,说明我被要求“寻找重复”,这是我在帖子中遇到的问题的一部分

以最佳方式描述的重复 加法运算的次数 在下面的程序片段中 (当用l==1和r==n调用时)


您的方法是使用递归函数编写的代码,如下所示:

function r(int n) 
{
  if (n == 2) return 1;
  if (n == 1) return 1;
  return 2 * r(n-2) + r(n-1);  // I guess we're assuming n > 2
}
我不确定什么是“递归”,但递归函数只是一个调用自身的函数


递归函数需要一个escape子句(一些非递归的情况-例如,“if n==1 return 1”)来防止堆栈溢出错误(即,函数被调用太多以至于解释器耗尽内存或其他资源)

一个简单的程序,它将实现如下所示:

public int r(int input) {
    if (input == 1 || input == 2) {
        return 1;
    } else {
        return 2 * r(input - 2) + r(input -1)
    }
}

您还需要确保输入不会导致无限递归,例如,如果开始时的输入小于1。如果这不是一个有效的案例,则返回一个错误,如果它是有效的,则返回适当的值。

几年前,Mohamad Akra和Louay Bazzi证明了一个推广主方法的结果——它几乎总是更好。你真的不应该再使用主定理了

例如,请参见此writeup:

基本上,让你的递推看起来像论文中的方程1,取下系数,然后积分定理1中的表达式。

“我也不确定‘递推’是什么。”

“递归关系”的定义是一个数字序列,“其域是一组无限的整数,其范围是一组实数。”附加条件是,描述此序列的函数“根据前一个定义序列的一个成员。”

我认为,解决这些问题的目的是从递归定义转变为非递归定义。假设所有n>0都有T(0)=2和T(n)=2+T(n-1),则必须从表达式“T(n)=2+T(n-1)”转换为类似“2n+2”的表达式

资料来源: 1) “离散数学与图论-第二版”,由Edgar G.Goodair和Michael M.Parmenter编写 2)“计算机算法C++”,由Ellis Horowitz、Sartaj Sahni和Sunuthavar RajayeKLAN。

< P>扎卡里:

假设你得到了这个 复发:

r(n)=2*r(n-2)+r(n-1);r(1)=r(2) =1

事实上,这是以 主定理?如果是,换句话说,是什么 它在说什么

我认为你的递推关系是,对于参数为“n”(表示你输入的数据集总数)的“r”函数,在数据集的第n个位置得到的结果是第n-1个位置的输出加上第n-2个位置结果的两倍,没有做任何非递归的工作。当你试图解决一个递归关系时,你试图用一种不涉及递归的方式来表达它

然而,我不认为这是主定理方法的正确形式。你的陈述是“常系数二阶线性递推关系”。显然,根据我的旧离散数学教科书,这是你需要的形式,以解决递归关系

以下是他们给出的表格:

r(n) = a*r(n-1) + b*r(n-2) + f(n)
对于'a'和'b'是一些常数,而f(n)是n的一些函数。在你的陈述中,a=1,b=2,f(n)=0。每当f(n)等于零时,递归关系称为“齐次”。所以,你的表达是同质的

我不认为你可以用主方法theorem来解决一个齐次递归关系,因为f(n)=0。主方法定理的任何情况都不允许这样做,因为任何事物的n次方不能等于零。我可能错了,因为我不是这方面的专家,但我不认为使用主方法解决同质递归关系是可能的

我认为解决齐次递推关系的方法是按5个步骤进行:

1) 形成特征e
r(n) = a*r(n-1) + b*r(n-2) + f(n)
x^k - c[1]*x^k-1 - c[2]*x^k-2 - ... - c[k-1]*x - c[k] = 0
x^2 - a*x - b = 0
r(n) = a*r(n-1) + b*r(n-2)
r(n) - a*r(n-1) - b*r(n-2) = 0
if x[1]!=x[2]
    c[1]*x[1]^n + c[2]*x[2]^n
else
    c[1]*x[1]^n + n*c[2]*x[2]^n
x = (-1 +- sqrt(-1^2 - 4(1)(-2)))/2(1)

    x[1] = ((-1 + 3)/2) = 1
    x[2] = ((-1 - 3)/2) = -2
c[1](x[1])^n + c[2](x[2])^n
c[1](1)^1 + c[2](-2)^1 = 1
c[1](1)^2 + c[2](-2)^2 = 1
[ 1 1   | 1 ]
[ 1 2   | 1 ] 
int example(A, int l, int r) {
  if (l == r)
    return 2;
  return (A[l] + example(A, l+1, r);
}
int example(A, int l, int r) {      =>  T(r) = 0
  if (l == r)               =>  T(r) = 1
    return 2;               =>  T(r) = 1
  return (A[l] + example(A, l+1, r);    =>  T(r) = 1 + T(r-(l+1))
}

Total:                      T(r) = 3 + T(r-(l+1))