Recursion 如何将递归算法转化为迭代算法

Recursion 如何将递归算法转化为迭代算法,recursion,iteration,Recursion,Iteration,我有我写的这个算法,但我真的不知道是否有可能将其转换为迭代算法。我试图得到立方体形状中每个节点的邻接节点。相邻节点必须满足两个条件: 它是一个灰色的节点 它位于距离的半径范围内 def find_continumm(种子、节点、行、灰色、xyz、距离): """ 种子:我们要为其查找相邻节点的节点。 节点:要在邻接中的候选节点。 行:保存相邻的节点。 灰色:表示节点是否为灰色的布尔数组。 xyz:形状的3维。 距离:半径 """ node_ravel=np.ravel_多索引(node,xyz

我有我写的这个算法,但我真的不知道是否有可能将其转换为迭代算法。我试图得到立方体形状中每个节点的邻接节点。相邻节点必须满足两个条件:

  • 它是一个灰色的节点
  • 它位于距离
    的半径范围内
  • 
    def find_continumm(种子、节点、行、灰色、xyz、距离):
    """
    种子:我们要为其查找相邻节点的节点。
    节点:要在邻接中的候选节点。
    行:保存相邻的节点。
    灰色:表示节点是否为灰色的布尔数组。
    xyz:形状的3维。
    距离:半径
    """
    node_ravel=np.ravel_多索引(node,xyz)
    如果节点在行中移动或~gray[node\u ravel]或math.dist(node,seed)>距离:
    返回
    行。添加(节点\u ravel)
    如果节点[0]0:
    节点[0]=节点[0]-1
    查找连续mm(种子、节点、行、灰色、xyz、距离)
    节点[0]=节点[0]+1
    如果节点[1]0:
    节点[1]=节点[1]-1
    查找连续mm(种子、节点、行、灰色、xyz、距离)
    节点[1]=节点[1]+1
    如果节点[2]0:
    节点[2]=节点[2]-1
    查找连续mm(种子、节点、行、灰色、xyz、距离)
    节点[2]=节点[2]+1
    
    是的,将递归算法转化为迭代算法始终是可能的。执行此操作的一般步骤是切换到、应用,然后应用。这三种转换的组合将把递归函数变成迭代函数,可能需要堆栈

    在我将此应用于您的代码之前,我将简要重写您的代码,如下所示:

    def find_continumm(种子、节点、行、灰色、xyz、距离):
    def helper():
    node_ravel=np.ravel_多索引(node,xyz)
    如果节点在行中移动或~gray[node\u ravel]或math.dist(node,seed)>距离:
    返回
    行。添加(节点\u ravel)
    对于范围(3)中的i:
    如果节点[i]0:
    节点[i]-=1
    助手()
    节点[i]+=1
    助手()
    
    您可以自己看到,这相当于您的代码版本。我将进行最后一次重写,以使用
    while
    -循环而不是
    for
    -循环:

    def find_continumm(种子、节点、行、灰色、xyz、距离):
    def helper():
    node_ravel=np.ravel_多索引(node,xyz)
    如果节点在行中移动或~gray[node\u ravel]或math.dist(node,seed)>距离:
    返回
    行。添加(节点\u ravel)
    i=0
    而我<3:
    如果节点[i]0:
    节点[i]-=1
    助手()
    节点[i]+=1
    i+=1
    助手()
    
    这大大简化了代码,并使将其转换为迭代版本变得更加简单

    由此产生的迭代版本是:

    开始=0
    进入_循环=1
    完成第一次呼叫=2
    如果=3,则输入第二个
    完成第二次呼叫=4
    增量i=5
    #上述变量的实际值并不重要
    #只要他们不一样
    def find_continumm(种子、节点、行、灰色、xyz、距离):
    堆栈=[]
    将_添加到_stack=lambda标记,数据:stack.append((标记,数据))
    返回到\u开始=lambda:将\u添加到\u堆栈(开始,无)
    返回到起始位置()
    堆栈时:
    标记,i=stack.pop()
    如果标记开始:
    node_ravel=np.ravel_多索引(node,xyz)
    如果节点在行中移动或~gray[node\u ravel]或math.dist(node,seed)>距离:
    通过
    其他:
    行。添加(节点\u ravel)
    将\u添加到\u堆栈(输入\u循环,0)
    elif标记正在进入\u循环:
    如果i<3:
    如果节点[i]0:
    节点[i]+=1
    将\添加到\堆栈(完成\第二次\调用,i)
    返回到起始位置()
    其他:
    将_添加到_堆栈(增量_i,i)
    elif标记正在完成第二次呼叫:
    节点[i]-=1
    将_添加到_堆栈(增量_i,i)
    elif标记为增量_i:
    将_添加到_堆栈(输入_循环,i+1)
    

    如果你看一下迭代版本,你会注意到它非常接近于递归版本的
    while
    -循环。在这个递归版本中,每个标记对应一行特定的代码,我们“跳回”到它。

    太好了!只是一个小错误,
    elif标记正在完成第二次调用
    ,它应该是
    node[i]+=1