Python递归意外停止

Python递归意外停止,python,recursion,graph,Python,Recursion,Graph,简单地说,递归中途停止,尽管其他一切都很好 递归函数如下所示(可以找到完整的代码): 问题是经过一段时间的递归之后,它停止了。让我困惑的是: 输入是固定的,但它停止的位置不是固定的。但是,它总是在大约7000次调用时停止 所有失败的递归都到达检查点1,但没有到达检查点2,并且根本不执行递归 它根本没有达到最大递归时间,我已经将最大递归设置为sys.setrecursionlimit(10**6) 它在相对较小的输入(数百或数千个节点)上运行得相当好,但在一个包含800000多个节点的大型图上却无

简单地说,递归中途停止,尽管其他一切都很好

递归函数如下所示(可以找到完整的代码):

问题是经过一段时间的递归之后,它停止了。让我困惑的是:

  • 输入是固定的,但它停止的位置不是固定的。但是,它总是在大约7000次调用时停止
  • 所有失败的递归都到达检查点1,但没有到达检查点2,并且根本不执行递归
  • 它根本没有达到最大递归时间,我已经将最大递归设置为
    sys.setrecursionlimit(10**6)
  • 它在相对较小的输入(数百或数千个节点)上运行得相当好,但在一个包含800000多个节点的大型图上却无法运行
  • 这让我抓狂,我看不出它不工作的原因,没有错误,没有堆栈溢出,只是停下来,说
    按任意键继续…
    就好像它完成了一样。任何人都有可能出错的线索吗?

    如指定:

    最高可能限制取决于平台。用户可能需要 当他们有一个需要深度的程序时,设置更高的限制 递归和支持更高限制的平台。这应该是 小心操作,因为过高的限制可能导致崩溃

    有一种方法可以检查该限制


    您必须实现非递归DFS。

    递归可能会消耗python中的内存,您可能需要确保不会耗尽内存。如果用完了,不同的操作系统上可能会发生不同的事情。例如,Linux将保存自身并
    终止进程,以免操作系统崩溃。如果您在Windows或Mac上运行,我不确定会发生什么,但这是一个值得关注的问题。@gabeio我在16G内存Windows机器上运行此脚本,从任务管理器中,我可以看到此脚本在停止之前需要大约600MB的时间。但是经过一些测试,它证明了我的机器能够为python提供大约10000 MB的内存。所以我并不认为是内存耗尽了。你是在32位Python上运行这个吗?正如@gabeio提到的,这可能是内存问题,但是如果函数终止并且没有崩溃,这似乎很奇怪。这可能是某种溢出/下溢问题吗?您能检查startNode/neighbor的值并查看是否存在某种整数溢出吗?我不认为在1e4-1e5范围内的数字会遇到这个问题,但最好检查一下。@SandeepDcunha我安装了带有64位Anaconda3的python。但我的交易量超过了80万。此外,当涉及到节点
    22473
    及其邻居(或邻居的邻居)时,递归总是无法执行,但由于输入是固定的,我不确定这是硬件问题还是算法问题。可能与问题无关,但您忘了
    返回DFS(图形,邻居)
    ,我发现我的平台上的默认递归限制是
    1000
    (使用
    sys.getrecursionlimit()
    ),您提供的代码的边界大约是
    3900
    ,我的脚本总是在大约
    6700
    次递归时停止。这些数字似乎有点不一致。但现在我确实相信递归是可以实现的bound@AmarthG在find_recursion.py模块中检查注释。最后一行是“一个不使用方法的程序可以设置一个更高的限制。”Python通过调用适当的方法来处理内置函数和操作符。例如,为了处理a+b,如果存在,则调用a.uu add_uuu(b);如果不存在,则调用b.u radd_uu(a)。在我看来,一个操作是由堆栈上的两个调用实现的。第一个调用处理要调用的方法,第二个调用是“real”方法。
    def DFS(graph, startNode = 0):
        global nodesProcessed; global explored; global finishingTime
        explored[startNode] = True
        currentLeader = startNode
    
        if startNode in graph:
            for neighbor in graph[startNode]:
                if not explored[neighbor]:
                    #checkpoint 1
                    DFS(graph, neighbor)
                    #checkpoint 2
        else: return currentLeader
    
        nodesProcessed += 1
        finishingTime[startNode] = nodesProcessed
        return currentLeader