求解初始值相差的递归关系

solving recurrence relations with far-off initial values

提问人:Lon 提问时间:4/27/2022 最后编辑:MushroomatorLon 更新时间:4/28/2022 访问量:137

问:

我想在设置 和 和 递归关系的初始值时获得 的值。a_1, a_2, ..., a_9a_0a_10a_(i+2) = (a_(i+1))^2 / (a_i + 0.5)

我应该如何用python编写代码?

Python 数学 序列 重复

评论

1赞 Mushroomator 4/27/2022
到目前为止,你尝试了什么?您能否提供一些输入和预期输出?
0赞 Mushroomator 4/27/2022
此外,在计算下一个值之前,您的递归关系依赖于两个值,但如果您最初只有一个值,您将无法计算,因为您没有 .你的意思是a_0a_1的初始值吗?在这种情况下,您实际上可以解决问题。您只需要提供 和 的初始值。a_0a_2a_2 = a_1 ** 2 / (a_0 + 0.5)a_1a_0a_1
0赞 Community 4/27/2022
请提供足够的代码,以便其他人可以更好地理解或重现问题。
0赞 duffymo 4/28/2022
我建议你研究一下记忆。你不可能每次都计算所有这些项,尤其是对于后面的项。

答:

0赞 Mushroomator 4/27/2022 #1

你的问题只有在被给予时才能得到解决。a0a1

有两种方法可以实现它。一种递归方法和一种迭代方法。您应该支持迭代方法,因为它速度更快,需要恒定内存,并且 Python 中的递归深度有上限。

我的实现允许为您设置初始值。a0a1

def rec_a(i, a0, a1):
    """
    Recursive function to calculate the i-th value of sequence
    :param i: i-th value of sequence for i >= 0
    :param a0: first value of sequence
    :param a1: seconds value of sequence
    :return: i-th value of sequence
    """
    if i < 0:
        raise ValueError("i must be >= 0")
    # the first value of sequence is a0
    if i == 0:
        return a0
    # the second value of sequence is a1
    if i == 1:
        return a1
    # all other sequences can now be calculated using recursion
    return rec_a(i - 1, a0, a1) ** 2 / (rec_a(i - 2, a0, a1) + 0.5)


def a_iter(i, init_a0, init_a1):
    """
    Iterative function to calculate the i-th value of sequence
    :param init_a0: first value of sequence
    :param init_a1: seconds value of sequence
    :param i: i-th value of sequence for i >= 0

    :return: i-th value of sequence
    """
    if i < 0:
        raise ValueError("i must be >= 0")
    a0 = init_a0
    # first value of sequence is a0
    if i == 0:
        return a0
    a1 = init_a1
    for j in range(2, i + 1):
        # calculate next sequence value
        a_next = a1 ** 2 / (a0 + 0.5)
        # shift all values a0 becomes a1, a1 becomes the next value of sequence (similar to iterative Fibonacci-number implementation)
        a0 = a1
        a1 = a_next
    return a1


initial_value_a0 = 2
initial_value_a1 = 1

# Calculate a_0
print(rec_a(0, initial_value_a0, initial_value_a1))
print(a_iter(0, initial_value_a0, initial_value_a1))

# Calculate a_1
print(rec_a(1, initial_value_a0, initial_value_a1))
print(a_iter(1, initial_value_a0, initial_value_a1))

# Calculate a_2
print(rec_a(2, initial_value_a0, initial_value_a1))
print(a_iter(2, initial_value_a0, initial_value_a1))

# Calculate a_4
print(rec_a(4, initial_value_a0, initial_value_a1))
print(a_iter(4, initial_value_a0, initial_value_a1))

# ValueError as 0 is first value of sequence
print(rec_a(-1, 1, 2))
print(a_iter(-1, 1, 2))

预期输出:

Traceback (most recent call last):
  File "main.py", line 60, in <module>
    print(rec_a(-1, 1, 2))
  File "main.py", line 10, in rec_a
    raise ValueError("i must be >= 0")
ValueError: i must be >= 0
2
2
1
1
0.4
0.4
0.01264197530864198
0.01264197530864198

如您所见,两种解决方案产生相同的结果。由于 Python 中的递归深度限制,对于大型输入,递归解决方案将失败。

0赞 JohanC 4/28/2022 #2

以下方法使用 sympy,Python 的符号数学库。由于方程的程度很高,符号求解器可能无法找到解。

下面的代码假定 和 的数值是给定的。在递归关系之后生成一个方程列表。(请注意,在 Python 中,用于幂,而保留用于布尔异或运算)。a[0]a[10]**^

from sympy import Symbol, Eq, nsolve

a = [Symbol(f'a{i}') for i in range(11)]
a[0] = 1
a[10] = 20
eqs = [Eq(a[i + 2], a[i + 1] ** 2 / (a[i] + 0.5)) for i in range(9)]

sol = nsolve(eqs, a[1:10], [1] * 9)
for i, a_i in enumerate(sol, start=1):
     print(f'a[{i}] = {a_i}')

输出:

a[1] = 2.65489718159571
a[2] = 4.69898602989657
a[3] = 6.99879217553299
a[4] = 9.42166253854625
a[5] = 11.8376030315757
a[6] = 14.1235246601829
a[7] = 16.1679662018854
a[8] = 17.8755216119038
a[9] = 19.1705616046603