[英]Approximate this equation using recursion 4 * (1 - (1 /3 ) + (1 / 5) - (1 / 7) + (1 / 9) - (1 / 11) … )
如何使用递归来近似以下方程式? 这是一种迭代方法:
def calculateFrac(num):
result = 0
for i in range(num):
if i % 2 == 0:
result = result + 1 / (2 * i + 1)
else:
result = result - 1 / (2 * i + 1)
print(4 * result)
print(calculateFrac(10))
首先,您也不会返回结果。 这是您代码的固定版本。
def calculateFrac(num):
result = 0
for i in range(num):
if i % 2 == 0:
result = result + 1 / (2 * i + 1)
else:
result = result - 1 / (2 * i + 1)
return result # return the result instead of printing it
print(calculateFrac(10)) # 0.7604599047323508
从那里开始,上面的代码非常完美。
虽然,请注意,用sum
和generator
更好地表示无限级数,而不是递归。 特别是在无法优化尾递归的 Python中。
递归解决方案将变慢,使用更多内存并最终达到最大递归深度。
from itertools import islice, count
def seq():
for n in count():
yield (-1) ** n / (2 * n + 1)
print(sum(islice(seq(), 0, 10))) # 0.7604599047323508
看来您想学习使用递归。 因此,重要的是,您还应确定不需要有效递归的问题。
递归通常更适合每次迭代都会产生问题的问题。 也就是说形式F(N)的问题= F(N 1)+ F(N 2),其中N 1和N 2是N个子集。 一个常见的例子是mergesort 。
您可以在线找到许多此类问题的习题集 。
def calculateFraction(num):
if (num > 0):
return (-1)**(num) * 1/(num*2+1) + calculateFraction(num-1)
else:
return 1
print(4 * calculateFraction(10))
编辑
Olivier的回答非常好,我希望我可以多次投票。
有鉴于此,我认为OP可能会受益于上述方法的二进制实现。 也就是说,每当递归时,将问题的一半发送到一个分支,另一半发送到另一个分支。 (这意味着,例如,请求num = 15将导致深度为4而不是深度为16。)
import inspect
def calculateFraction(num, end=0):
result = 0
depth = 'Depth({:d}){:s}>'.format(len(inspect.stack())-1, '='*(len(inspect.stack())-1)*2)
# If there are an odd number of parts to calculate, do the highest one now
if (((num-end+1)&1) == 1):
result += ((-1)**(num)) / (num*2+1)
print('{:s} Fraction part {:d} = {:f}'.format(depth, num, result))
num-=1
# If there are still any parts to calculate, do them recursively
# (There must be an even number, as we did the odd one previously)
# (That may leave 0 still to do, in which case the recursion is skipped)
if (num > end):
mid = ((num-end)>>1) + end
# Do the upper half of the remaining parts
print('{:s} Recursing to {:d},{:d}'.format(depth, num, mid+1))
result += calculateFraction(num, mid+1)
# Do the lower half of the remaining parts
print('{:s} Recursing to {:d},{:d}'.format(depth, mid, end))
result += calculateFraction(mid, end)
return result
print('Result: {:f}'.format(4*calculateFraction(10)))
我在问如何使用递归解决这个问题。
我不同意@OlivierMelançon所说的这是一个糟糕的递归示例。 我仅提供了一种可怕的递归解决方案的可能实现:
def calculateFrac(num):
if num < 1:
return 0.0
return calculateFrac(num - 1) + (2 * (num % 2) - 1) / (2 * num - 1)
print(calculateFrac(10)) # 0.7604599047323508 (put in the 4 *)
在我的系统上,它可以处理的最大参数是997,而无需通过sys.setrecursionlimit()
显式扩展调用堆栈。 使用记忆技术将无济于事。 我们可以通过执行以下操作来制作尾递归解决方案:
def calculateFrac(num, sum=0.0):
if num < 1:
return sum
return calculateFrac(num - 1, sum + (2 * (num % 2) - 1) / (2 * num - 1))
print(calculateFrac(10)) # 0.7604599047323506 (put in the 4 *)
并不是说Python关心这样的事情。 但是,如果确实进行了尾部调用优化,则诸如解决方案的速度可能与迭代解决方案一样快,并且没有任何堆栈限制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.