python中的递归,python每次运行时都会崩溃

时间:2014-02-25 20:11:40

标签: python recursion physics sys

我正在尝试编写一个程序,该程序使用递归来求解直接射向空中的物体的速度,并计算何时撞击地面,同时考虑重力随高度的变化而使用此等式g(s) = G∙ME / (RE + s)^2置换这个等式s(t) = s(t-∆t) + v(t)∙∆t和速度与这个等式v(t) = v(t-∆t) - g(s(t-∆t)) ∙ ∆t我使用先前的值(由t-Δt表示)作为输入,然后更新变量并返回它们对我来说有意义但我必须是做错了。最初我得到一个错误,说超过了最大递归限制但是在一些谷歌搜索后我发现我应该更改递归限制。现在程序似乎开始运行但是在输出任何东西之前python崩溃了。我一直无法弄清楚我能做些什么来完成这项工作。任何帮助将不胜感激

import math as m
import sys
sys.setrecursionlimit(20000)
  #
    #
    # Method that runs the simulation
    #

def run(deltat, G, ME, RE, velocity):
    # set initial time to 0
    s = 0
    t = 0

    # Save the initial velocity because it is needed to find when the ground is hit
    initialvelocity = velocity
    # while the height is greater than 0 execute the loop
    while s >= 0:
        # Find the height based on gravity, and velocity
        s = calculatedisplacement(t ,deltat, velocity, s, G, ME, RE)

        # Calculate the velocity based on the changing gravity
        velocity = calculatevelocity(velocity, t ,deltat, s, G, ME, RE)

        # If s is larger than 0 print where the object is
        if s >= 0:
            print ("At time t = " + str(t) + " The object is " + str(s) + " meters high")
            t = t + deltat
            print("Time: " + str(t))

        elif s < 0:
            print ("The object hits the ground at t = " + str(quadraticsolver((-0.5 * (G * ME)) / (m.pow(RE, 2)), initialvelocity, 0)))


# Function used to calculate gravity
def calculategravity(s, G, ME, RE):


    gravity = ((G * ME) / (m.pow((RE + s), 2)))

    print ("Gravity = " + str(gravity))

    return gravity

# Function used to calculate height
def calculatedisplacement(t ,deltat, velocity, s, G, ME, RE):
    s = s + (calculatevelocity(velocity, t ,deltat, s, G, ME, RE) * deltat)
    print("height = " + str(s))
    return s

# Function used to calculatevelocity
def calculatevelocity(t ,deltat, velocity, s, G, ME, RE):
    velocity = velocity - ((calculategravity(G, ME, RE,calculatedisplacement(t ,deltat, velocity, s, G, ME, RE)))* deltat)
    print("Velocity " + str(velocity))
    return velocity

# Used to solve quadratic equations and find where the object hits the ground
def quadraticsolver(a, b, c):
    discriminant = (m.pow(b, 2)) - (2 * a * c)
    # Two solutions to account for the + or - in the quadratic formula
    solution1 = (((-b) + (m.sqrt(discriminant))) / (2 * a))
    solution2 = (((-b) - (m.sqrt(discriminant))) / (2 * a))
    # One solution will always be 0 because height is 0 when time is 0 so return the solution that is not zero
    # This is the time when height = 0
    if solution1 == 0:
        return solution2
    elif solution2 == 0:
        return solution1

1 个答案:

答案 0 :(得分:4)

(这对评论来说太大了。)

递归有利于解决许多问题,但迭代数值模拟不是其中之一。堆栈帧的数量是有限的,要谨慎使用(Python对堆栈帧的数量有限制,因为当你使用太多的堆栈帧时,它通常是一个错误)。您可能正在耗尽为堆栈分配的内存(而不是堆),或者您可能正在耗尽所有内存,堆栈和堆。内存不足错误有时会毫无预警,因为程序或操作系统没有资源来生成警告。

如果您将程序重写为forwhile循环,您可能会发现您的程序更高效,更易于调试,甚至可能没有错误。

某些编程语言(如Scheme)鼓励使用递归进行迭代,但这些语言在内部将递归函数转换为while循环(“尾调用优化”)。 Python不是这些语言之一:每次调用函数时,它都会创建一个新的堆栈帧,并且在递归结束之前不会删除旧的堆栈帧,这实际上就像是内存泄漏。 (也就是说,对象不再有用,但它们仍然被引用并仍在内存中。)