我想评估以下递归函数:
当p在0和0.5(含)之间时,F(x)= 0.25 * F(2x);
当p在0.5和1(含)之间时,F(x)= 0.25 + 0.75 * F(2x-1)。
另外,F(0)= 0,F(1)= 1。我不知道如何有效地做到这一点。我想要做的是为一组dyadic numbers计算F(x),然后绘制图形。困难的部分是找到函数值。有人可以提供一个如何处理这种递归函数评估的例子吗?至少有一些参考。请问哪种语言适合这样的任务?
答案 0 :(得分:4)
如果您只对表单a / 2 b 的输入感兴趣,那么它可能有助于定义类似
的内容G(a,b)= F(a / 2 b )
考虑到这一点,请注意,由于F(0)= 0且F(1)= 1,我们有
G(0,0)= 0
G(1,0)= 1
现在,自
F(x)= 0.25 F(2x)(如果x≤0.5)
我们看到了
G(a,b)= 0.25 G(a,b - 1)(如果b> 0且a≤2 b-1 )
而且,因为
F(x)= 0.25 + 0.75 F(2x - 1)(如果x≥0.5)
我们看到了
G(a,b)= 0.25 + 0.75 G(a - 2 b-1 ,b - 1)*(如果b> 0且a≥2 b-1功能)
总的来说,我们现在必须解决这个问题:
G(0,0)= 0
G(1,0)= 1
G(a,b)= 0.25 G(a,b - 1)如果a≤2 b-1
G(a,b)= 0.25 + 0.75 G(a - 2 b - 1 ,b - 1)否则
因此,要计算F(a / 2 b ),你可以通过简单地扩展上述递归关系来及时做O(b)。
当然,还有一个问题是,对于这里发生的事情是否有更清晰的解释。基于我们将单位区间划分为[0,1 / 2]和[1 / 2,1]的范围这一事实,或许根据数字x来看待数字x是不会有害的。它的二进制表示。让我们看看如果我们这样做会发生什么。
如果x只有一位长,则它为0或1,我们可以直接评估:
F(0)= 0
F(1)= 1
现在,假设x具有二进制表示。 0.b <子> 0 子> B'的子> 1 子> ... B'的子>名词子>。注意
2x = b 0 .b 1 b 2 ... b n 。
这非常方便,因为如果我们这样做,递归工作就会非常好。例如,如果b 0 = 0,那么我们采用第一个分支:
F(0.0b 1 b 2 ... b n )= 0.25 F(0.b 1 子> ... b'的子>名词子>)
否则,b 0 = 1,所以我们采取第二个分支:
F(0.1b 1 ... b n )= 0.25 + 0.75 F(0.b 1 ... b <子>名词子>)
这可以在时间O(n)中进行评估,其中n是数字表示中的位数(这与上面的时间限制匹配,因为上面的分母b是我们的numnber n。所有,我们在这里所做的只是改变表示。)
当我试图评估这种复发时,我还没有深入了解出现的模式,但是如果我发现某些内容,我会更新这个答案。
希望这有帮助!
答案 1 :(得分:2)
在Ruby中实现它是直截了当的,它有一个内置的Rational
类,因此数字舍入问题不会因为二元数而困扰你。
ONE_HALF = Rational(1,2)
ONE_QUARTER = Rational(1,4)
THREE_QUARTERS = Rational(3,4)
def f(r)
r = r.to_r # ensure r is a rational
if r == 0
return 0
elsif r == 1
return 1
elsif r <= ONE_HALF
return ONE_QUARTER * f(2 * r)
else
return ONE_QUARTER + THREE_QUARTERS * f(2 * r - 1)
end
end
p f(Rational(0)) # => 0
p f(Rational(1)) # => 1
p f(Rational(1,2)) # => (1/4)
p f(Rational(1,4)) # => (1/16)
p f(Rational(3,4)) # => (7/16)
p f(Rational(47,1024)) # => (1549/1048576)