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