计算Levenshtein编辑距离的复杂性

时间:2013-01-31 15:00:18

标签: python algorithm complexity-theory dynamic-programming levenshtein-distance

我一直在关注Levenshtein Edit Distance这个简单的python实现。

def lev(a, b):
    """Recursively calculate the Levenshtein edit distance between two strings, a and b.
    Returns the edit distance.
    """
    if("" == a):
        return len(b)   # returns if a is an empty string
    if("" == b):
        return len(a)   # returns if b is an empty string
    return min(lev(a[:-1], b[:-1])+(a[-1] != b[-1]), lev(a[:-1], b)+1, lev(a, b[:-1])+1)

来自:http://www.clear.rice.edu/comp130/12spring/editdist/

我知道它具有指数复杂性,但我如何从头开始计算复杂性?

我一直在互联网上搜索,但没有找到任何解释说明它是指数级的。

感谢。

1 个答案:

答案 0 :(得分:6)

  1. 绘制调用树(您显然已经完成了)。

  2. 来自调用树的摘要。对于任意 n ,请确定树的深度 d ,作为 n 的函数。

    此外,当 n 接近无穷大时,平均确定每个节点有多少个分支/子节点;这称为平均分支因子 b

  3. 实现访问深度为 d 的树中的每个节点,平均分支因子 b 至少需要 b > ^ d 操作。用 n 表示该数字,并且根据输入大小,您在复杂性方面有一个下限。

  4. 更具体地说:你持续递归,直到你击中一个空字符串,每次取消一个字符。如果我们调用字符串 m n 的长度,那么树的深度为min( m n )。在除了叶子之外的调用树中的每个节点,你只递归三次,所以在极限中平均分支因子是3.这给了我们一个Θ的调用树(3 ^ min( m n ))节点。最坏的情况发生在 m = n 时,所以我们可以调用Θ(3 ^ n )。

    这仍然只是复杂性的下限。为了全面了解,您还应该考虑递归调用之间完成的工作量。在这个天真的代码中,实际上是线性时间因为a[:-1]必须复制(在Θ( n )成本)几乎所有的a,给出Θ( n 3 ^ n )总复杂度。*

    [*我曾经在二元搜索中使用Python的切片捕获了一位CS教授,结果在时间Θ( n lg n )中运行。]