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