【问题标题】:Any alternative or improvement of my recursive/iterative approach?我的递归/迭代方法的任何替代或改进?
【发布时间】:2016-09-30 04:11:18
【问题描述】:

我正在尝试使用 python 3 编写父搜索代码。

Parent 是一个基于 0 的数组,包含该元素的父元素。 例如,parent=[0,0] 表示

  1. 第一个元素的父元素是它自己。

  2. 第二个元素的父元素是第一个元素,因此是第二个元素 value 等于第一个元素的值

首先,我尝试使用递归方法。

def getParent2(table):
    # find parent and compress path
    if table!=parent[table]:
        parent[table]=getParent2(parent[table])
    return parent[table]

尽管这种方法似乎显示出非常好的速度,但它在一个非常大的父数组中面临堆栈溢出问题。

(*设置 recursionlimit 也会导致系统错误代码 7。)

我尝试将其修改为迭代方法

def getParent3(table):

    while table!=parent[table]:
        table=parent[table]    

    return table

不幸的是,它在同一个大型父阵列上运行速度慢得令人无法接受。

在不更改递归限制的情况下改进此代码的任何想法?

谢谢。


抱歉没有样本数据,它确实很大(10000+)所以这里是这个函数的一个小样本。

例如,

parent=[0,0,2,1,2]

getParent(3) 将给出0 作为结果

由于第 4 个元素(0-base)的父元素是第 2 个元素,而第 2 个元素的父元素是第 1 个元素

是这样的,3-->1-->0

【问题讨论】:

  • 这里的问题是您的原始代码会在执行过程中更新列表,从而缓存中间结果。您的新代码不会修改列表,因此它必须重复重新计算路径。但是,我不确定如何在不使用另一个列表作为堆栈的情况下解决此问题,因为您需要跟踪需要更新的父单元格。
  • 伟大的想法 Cel,我会尝试的。谢谢
  • 只是为了帮助您在需要时找到额外的资源:您在这里实现的称为联合查找数据结构的find-操作。在查找操作期间更新父关系通常称为“路径压缩”。

标签: python algorithm python-3.x recursion genetic-algorithm


【解决方案1】:

你没有给我们任何数据来测试它,所以我假设@Cel Skeggs 确定了她评论中的关键差异。充实她的建议(但未经测试,因为 - 再次 - 你没有提供数据):

def getParent4(table):
    chain = []
    while table != parent[table]:
        chain.append(table)
        table = parent[table]    
    for link in chain:
        parent[link] = table
    return table

但是,除非您在顶层多次调用该函数,否则您看到的速度差异并没有真正意义——在这种情况下,折叠路径会产生巨大的差异。但是,你也没有说什么;-)

【讨论】:

  • 对不起,我确实在我的回复中发布了一个示例。谢谢蒂姆。
  • 没关系。回复有帮助吗?如果可能,您应该接受一个有效的答案,或者解释剩下的问题是什么。 stackoverflow.com/help/someone-answers
  • 我刚刚完成了测试。该代码提供了准确的答案。不幸的是,它仍然比第一种递归方法慢,并且无法通过时间限制实现。但是,是的,我想我会尝试修改一下。
  • 完成!那太容易了:-)
  • 不是在chain 中存储必须更改其父元素的元素的索引,另一种方法是迭代路径两次;首先不更改条目,只是为了找到根,然后第二次(再次从查询的索引开始)压缩路径。这可以减少内存使用,甚至可以加快速度。
猜你喜欢
  • 1970-01-01
  • 2015-03-16
  • 1970-01-01
  • 2016-07-21
  • 2021-12-24
  • 2016-11-10
相关资源
最近更新 更多