Python递归深度超出限制超出,并且不知道如何删除递归

use*_*051 0 python recursion limit

也许这个问题可以通过删除所有这些功能来解决,不是吗?但是,我真的不知道如何让源工作.顺便说一句,它只是模拟一匹马在一个chesstable,周围和周围,随机,试图访问每个广场一次; 我得到一个递归深度超出错误.

import random

def main():
    global tries,moves
    tries,moves=0,0
    restart()

def restart():
    global a,indexes,x,y
    a=[[0 for y in range(8)] for x in range(8)] #Costrutto chic
    indexes=[x for x in range(8)]
    #Random part
    x=random.randint(0,7)
    y=random.randint(0,7)
    a[x][y]=1
    start()

def start():
    global i,indexes,moves,tries
    i=0
    random.shuffle(indexes) #List filled with random numbers that i'll use as indexes
    while i<=7:
        if indexes[i]==0:
            move(-2,-1)
        elif indexes[i]==1:
            move(-2,1)
        elif indexes[i]==2:
            move(-1,-2)
        elif indexes[i]==3:
            move(-1,2)
        elif indexes[i]==4:
            move(1,-2)
        elif indexes[i]==5:
            move(1,2)
        elif indexes[i]==6:
            move(2,-1)
        elif indexes[i]==7:
            move(2,1)
        i+=1
    for _ in a:
        if 0 in _:
            print "Wasted moves: %d"%(moves)
            tries+=1
            moves=0
            restart()
    print "Success obtained in %d tries"%(tries)

def move(column,row):
    global x,y,a,moves
    try: b=a[x+row][y+column]
    except IndexError: return 0
    if b==0 and 0<=x+row<=7 and 0<=y+column<=7:
        x=x+row
        y=y+column
        a[x][y]=1
        moves+=1
        start()
    else: return 0

try :main()
#except: print "I couldn't handle it" <-Row added to prevent python from returning a huge amount of errors
Run Code Online (Sandbox Code Playgroud)

编辑:这是修改后的版本,仍然不起作用,但至少它是一个改进:

import random

def move((column,row),x,y):
    try: cell=squares_visited[x+row][y+column]
    except IndexError: return x,y ## NONE TYPE OBJECT
    if cell==0 and 0<=x+row<=7 and 0<=y+column<=7:
        x+=row
        y+=column
        squares_visited[x][y]=1
        return x,y ## NONE TYPE OBJECT

squares_visited=[[0] * 8 for _ in range(8)]
x=random.randint(0,7)
y=random.randint(0,7)
squares_visited[x][y]=1
moves=[(-2,-1),(-2,1),(-1,-2),(-1,2),(1,-2),(1,2),(2,-1),(2,1)]
indexes=list(range(8))
tries=0
print "The horse starts in position %d,%d"%(x,y)

while True:
    random.shuffle(indexes)
    for _ in indexes:
        cells=move(moves[indexes[_]],x,y) ##Passing as arguments x and y looks weird
        x=cells[0]
        y=cells[1]
    #If you out this for cicle, there are no legal moves anymore(due to full completion with 1, or to lack of legit moves)
    for _ in squares_visited:
        if 0 in _:
            squares_visited=[[0] * 8 for _ in range(8)]
            tries+=1
    else:
        print "You managed to do it in %d tries."%(tries)
Run Code Online (Sandbox Code Playgroud)

sen*_*rle 8

这段代码有很多问题 - 足够值得完全重复:

import random

def main():
    global tries,moves
Run Code Online (Sandbox Code Playgroud)

过度使用全局变量的许多例子中的第一个.如果可能,传递参数; 或创建一个类.这是一个通用策略,可以帮助您构建更易于理解(因此更可调试)的算法; 从一般意义上讲,这是您的代码失败的部分原因 - 不是因为任何特定的错误,而是因为代码的复杂性使得很难找到错误.

    tries,moves=0,0
    restart()

def restart():
    global a,indexes,x,y
Run Code Online (Sandbox Code Playgroud)

你为什么要命名你的电路板a?这是一个可怕的名字!使用描述性的东西squares_visited.

    a=[[0 for y in range(8)] for x in range(8)] #Costrutto chic
    indexes=[x for x in range(8)]
Run Code Online (Sandbox Code Playgroud)

Minor:在python 2中,[x for x in range(8)] == range(8)- 它们完全相同,所以列表理解是不必要的.在3中,它的工作方式略有不同,但如果你想要一个列表(而不是一个range对象),只需将其传递给list(list(range(8))).

    #Random part
    x=random.randint(0,7)
    y=random.randint(0,7)
    a[x][y]=1
    start()
Run Code Online (Sandbox Code Playgroud)

所以到目前为止我对代码的理解a是板子,xy是起始坐标,你已经标记了第一个访问过的点1.到现在为止还挺好.但事情开始变得毛茸茸,因为你start最后restart调用而不是从顶级控制函数调用它.这在理论上是可以的,但它使递归比必要的更复杂; 这是你问题的另一部分.

def start():
    global i,indexes,moves,tries
Run Code Online (Sandbox Code Playgroud)

更多全局...

    i=0
    random.shuffle(indexes) #List filled with random numbers that i'll use as indexes
    while i<=7:
        if indexes[i]==0:
            move(-2,-1)
        elif indexes[i]==1:
            move(-2,1)
        elif indexes[i]==2:
            move(-1,-2)
        elif indexes[i]==3:
            move(-1,2)
        elif indexes[i]==4:
            move(1,-2)
        elif indexes[i]==5:
            move(1,2)
        elif indexes[i]==6:
            move(2,-1)
        elif indexes[i]==7:
            move(2,1)
        i+=1
Run Code Online (Sandbox Code Playgroud)

好的,所以你要做的就是indexes按顺序遍历每个索引.你为什么用while?为什么i全球?我不认为它在其他任何地方使用过.这样做过于复杂.只需使用for循环indexes直接迭代,如

    for index in indexes: 
        if index==0:
            ...
Run Code Online (Sandbox Code Playgroud)

好的,现在针对具体问题......

    for _ in a:
        if 0 in _:
            print "Wasted moves: %d"%(moves)
            tries+=1
            moves=0
            restart()
    print "Success obtained in %d tries"%(tries)
Run Code Online (Sandbox Code Playgroud)

我不明白你在这里要做什么.看起来你restart每次0在电路板上找到一个(即一个未访问的地点)时都会打电话.但是将restart所有电路板值重置为0,所以除非1在达到此点之前还有其他方法用s 填充电路板,否则将导致无限递归.事实上,之间的相互递归move,并start 可能能够实现,在原则上,但因为它是,它的方式太复杂了!问题是没有明确的递归终止条件.

def move(column,row):
    global x,y,a,moves
    try: b=a[x+row][y+column]
    except IndexError: return 0
    if b==0 and 0<=x+row<=7 and 0<=y+column<=7:
        x=x+row
        y=y+column
        a[x][y]=1
        moves+=1
        start()
    else: return 0
Run Code Online (Sandbox Code Playgroud)

原则上,这个想法似乎是,如果你的移动击中1或离开了板,那么递归的当前分支终止.但是因为i并且indexes在全球范围之内start,当start被重新调用时,它会重新洗牌indexes并重置i为0!结果是纯粹的混乱!我甚至无法理解这将如何影响递归; 似乎因为每次i开始都会重置start,并且因为每次成功调用都会move导致调用start,while启动循环将永远不会终止!

我想最终这个过程可能会设法访问每个方块,此时事情可能会按预期工作,但事实上,即使预测也是如此.

try :main()
#except: print "I couldn't handle it" <-Row added to prevent python from returning a huge amount of errors
Run Code Online (Sandbox Code Playgroud)

不确定你最后一行是什么意思,但这听起来不是一个好兆头 - 你是在写错误而不是找到根本原因.

我将稍微使用这个代码,看看我是否可以通过对其某些状态进行去全球化来使其表现得更好......将很快报告.

更新:

好的,我indexes如上所述去全球化了.然后我用一个无限循环替换了start/ restartrecursion,一个调用过去restartreturn语句,以及一个结束时的语句(在成功时突破无限循环).结果表现得更像预期.这仍然是糟糕的设计,但它现在有效,因为它递归地尝试了一堆随机路径,直到每个本地位置都被访问过.startrestartsys.exit()start

当然它仍然没有成功; 它只是保持循环.实际上找到一个解决方案可能需要更多地重新思考这个算法!但遵循我的上述建议至少应该有所帮助.