我正在尝试为Stein的算法(二进制GCD算法)提出递归关系,但是我追踪它的能力证明不是最易于划分的。
我完全被多路径和递归调用所困扰,以及我们处理总位来表示我们的值而不是值本身的事实。
这是算法:
stein(u, v):
if either of u or v are 0: return their sum.
if either of u or v are 1: return 1.
if both u and v are even: return 2 * stein(u/2, v/2)
if u is even and v is odd: return stein(u/2, v)
if u is odd and v is even: return stein(u, v/2)
if both u and v are odd: return stein(larger-smaller/2, smaller)
我正在尝试找到递归关系T(n),其中n是表示u和v所需的总位数。我认为这里的第一步应该是在出现最坏情况时的性能
我认为每个除法运算会将位数减少1,但这是我迄今为止所理解的最多。
我试过跟踪算法,但无济于事。我还阅读了Knuth Vol的相关部分。 2但我认为这有点超出了我理解的范围,因为它对我来说没什么意义。
答案 0 :(得分:3)
你想要一个表示u和v中位数的递归关系,而不是stein(u,v)的值,所以让我们通过一点来推理它。
给定任意u和v,最好和最坏的情况是什么?
最好的情况(我们快速完成):一个恒定时间案例。
最坏情况:递归调用斯坦因(u / 2,v / 2),斯坦因(u,v / 2)或斯坦因(较大 - 较小/ 2,较小)
在第一个场景中,我们将值减半,这将简单地删除两个二进制数字。这需要我们一次操作。 T(n)= T(n-2)+ 1
在第二种情况下,我们只划分其中一个值,因此只比我们开始时少一位数。这需要一次手术。 T(n)= T(n-1)+ 1
第三种情况变得更加丑陋。减法迭代n中的所有数字。这意味着如果我们丢失了m个数字,但是使用了n个步骤(减法),则我们的重现是T(n)> = T(n-m)+ n。我们仍然必须找到m,如果我们能证明这一步消除了许多数字(例如:m = n / 2),则重复可能不会太慢。
不幸的是,我们很容易想出一个非常糟糕的情况
将v设置为3.这可以确保它是奇数,并且它将始终是两者中较小的一个。现在,如果我们设置你使(u-v)/ 2继续变为奇数,那么重复将继续进行第三种情况。并且当v = 3时,(u-v)/ 2将仅比u短1位。这意味着在最坏的情况下m是1. ==> T(n)= T(n-1)+ n
该不良情景的例子:(21,3) - > (9,3) - > (3,3)我们可以通过取v'= v * 2 + 3来继续构造更大的数字。如你所见,这些“坏”数字的增长一次只是一个二进制数字并且会导致我们总是下降第三条道路。这就是m为1的原因。
遗憾的是,最后一次重复的情况是O(n * n)
答案 1 :(得分:0)
您正在寻找一种规则,该规则依赖于以尽可能大的子问题大小(相对于问题大小)递归地评估函数。有两个规则要求解决一个较少位的子问题:处理u
或v
中只有一个是奇数的情况的规则。奇数不会改变,偶数应该尽可能长。这表明以下是最坏的情况:(1)不作为基本情况处理的最小奇数(2)自由增长2的幂。即,u = 3
和v=2^n
取一些{ {1}}。在这种情况下,n
的运行时间是输入的位数。