在Python中递归地求解数学方程

时间:2015-02-24 22:49:49

标签: python math recursion

我想解决一个我应该递归解决的方程式,我上传了公式的图片(对不起!我不知道如何在这里写数学公式!) enter image description here 我用Python编写代码如下:

import math
alambda = 1.0
rho = 0.8
c = 1.0
b = rho * c / alambda
P0 = (1 - (alambda*b))
P1 = (1-(alambda*b))*(math.exp(alambda*b) - 1)

def a(n):
    a_n = math.exp(-alambda*b) * ((alambda*b)**n) / math.factorial(n)
    return a_n

def P(n):
    P(n) = (P0+P1)*a(n) + sigma(n)

def sigma(n):
    j = 2
    result = 0
    while j <= n+1:
        result = result + P(j)*a(n+1-j)
        j += 1
    return result

很明显我无法完成P功能。所以请帮助我。 当n = 1时我应该提取P2,当n = 2时我应该提取P3。 顺便说一下,P0和P1如第6行和第7行所示。 当我调用P(5)时,我想在输出端看到P(0),P(1),P(2),P(3),P(4),P(5),P(6)。

2 个答案:

答案 0 :(得分:3)

您需要重新组织公式,这样您就不必计算P(3)来计算P(2)。通过将求和的最后一项P(n + 1)a(0)带到等式的左边并除以a(0),这很容易做到。然后根据P(m)得到P(n + 1)的公式,其中m <= n,这可以通过递归来解决。

正如Bruce所提到的,最好通过将它们保存在dict中来缓存P(n)的中间结果,以便a)您不必在每次需要时重新计算P(2)等,并且b)之后你得到P(n)的值,你可以打印字典来查看P(m)的所有值,其中m <= n。

import math
a_lambda = 1.0
rho = 0.8
c = 1.0
b = rho * c / a_lambda
p0 = (1 - (a_lambda*b))
p1 = (1-(a_lambda*b))*(math.exp(a_lambda*b) - 1)
p_dict = {0: p0, 1: p1}

def a(n):
    return math.exp(-a_lambda*b) * ((a_lambda*b)**n) / math.factorial(n)

def get_nth_p(n, p_dict):
    # return pre-calculated value if p(n) is already known
    if n in p_dict:
        return p_dict[n]

    # Calculate p(n) using modified formula
    p_n = ((get_nth_p(n-1, p_dict)
            - (get_nth_p(0, p_dict) + get_nth_p(1, p_dict)) * a(n - 1)
            - sum(get_nth_p(j, p_dict) * a(n + 1 - j) for j in xrange(2, n)))
          / a(0))

    # Save computed value into the dict
    p_dict[n] = p_n
    return p_n

get_nth_p(6, p_dict)
print p_dict

修改2

代码的一些外观更新 - 缩短名称并使p_dict成为mutable default argument(我试图谨慎使用的东西)确实使代码更具可读性:

import math

# Customary to distinguish variables that are unchanging by making them ALLCAP
A_LAMBDA = 1.0
RHO = 0.8
C = 1.0
B = RHO * C / A_LAMBDA
P0 = (1 - (A_LAMBDA*B))
P1 = (1-(A_LAMBDA*B))*(math.exp(A_LAMBDA*B) - 1)

p_value_cache = {0: P0, 1: P1}

def a(n):
    return math.exp(-A_LAMBDA*B) * ((A_LAMBDA*B)**n) / math.factorial(n)

def p(n, p_dict=p_value_cache):
    # return pre-calculated value if p(n) is already known
    if n in p_dict:
        return p_dict[n]

    # Calculate p(n) using modified formula
    p_n = ((p(n-1)
            - (p(0) + p(1)) * a(n - 1)
            - sum(p(j) * a(n + 1 - j) for j in xrange(2, n)))
          / a(0))

    # Save computed value into the dict
    p_dict[n] = p_n
    return p_n

p(6)
print p_value_cache

答案 1 :(得分:0)

你可以解决这个问题:

import math
alambda = 1.0
rho = 0.8
c = 1.0
b = rho * c / alambda


def a(n):
  # you might want to cache a as well
  a_n = math.exp(-alambda*b) * ((alambda*b)**n) / math.factorial(n)
  return a_n


PCache={0:(1 - (alambda*b)),1:(1-(alambda*b))*(math.exp(alambda*b) - 1)}

def P(n):
 if n in PCache:
   return PCache[n]
 ret= (P(0)+P(1))*a(n) + sigma(n)
 PCache[n]=ret
 return ret

def sigma(n):
  # caching this seems smart as well
  j = 2
  result = 0
  while j <= n+1:
    result = result + P(j)*a(n+1-j)
    j += 1
  return result

void displayP(n):
  P(n) # fill cache :-)
  for x in range(n):
    print ("%u -> %d\n" % (x,PCache[x]))

您可能希望使用memoize装饰器(请参阅http://www.python-course.eu/python3_memoization.php

,而不是手动管理缓存。

注意:

  • 未经测试,但您应该了解它背后的想法
  • 你的复发不起作用P(n)取决于等式上的P(n + 1)......这将永远不会结束
  • 看起来我误解了P0和P1是两个常数(大数字)和结果(小数字,索引)......符号不是我猜的最佳选择......