是否有一个例子可以使Union&在Omega(q log n)中按秩运行查找没有并集的算法?

时间:2014-07-19 10:30:54

标签: algorithm disjoint-sets

最近,我读了this,并对工会和时间的复杂性感到惊讶。只有路径压缩的查找算法为O((m+n) log n),其中m是“查找”查询的数量,n是“合并”查询的数量。

我对这种复杂性很感兴趣,(因为我通常在没有等级的情况下实现这个算法,即使我按照等级倒置应用了union,性能也不错!)并试图找到一个可以使时间复杂化的例子。但是由于路径压缩的强大功能,它真的很难......

是否有任何示例可以实现Omega((m+n) log n),或者这种复杂性只是理论,不实用?

2 个答案:

答案 0 :(得分:6)

是的,由于Michael J. Fischer in 1972,有一个匹配的下限(见第3节)。他的例子使用了深度log n的二叉树,其中深度为0的二叉树是单个节点,深度为k的二叉树是两个深度为k-1的二叉树,其中一个根指向另一个的根。 。通过反复将二叉树的根的并集指向单例并在最深的节点上执行查找,我们执行一个昂贵的(对数步骤)操作,使另一个嵌入的二叉树被利用。

Python演示:这会打印(k+1) * 2**k,其中kexample的参数,表示O(2**k)键上O(2**k)操作的近似操作计数。< / p>

p = {}

def find(a):
    global count
    b = a
    while (b in p):
        count += 1
        b = p[b]
    while (a in p):
        pa = p[a]
        p[a] = b
        a = pa
    return b

def union(a, b):
    p[find(a)] = find(b)

def deepest():
    maxd = (0, None)
    for (a, pa) in p.items():
        d = 1
        while (pa in p):
            d += 1
            pa = p[pa]
        maxd = max(maxd, (d, a))
    return maxd[1]

def example(k):
    global count, p
    count = 0
    p.clear()
    for a in range(((2 ** k) - 1), 0, (- 1)):
        union(a, (a & (a - 1)))
    r = 0
    for a in range((2 ** k), (2 ** (k + 1))):
        union(r, a)
        find(deepest())
        r = a
example(9)
print(count)

答案 1 :(得分:2)

  或者这种复杂性只是理论上的,而不是实际的吗?

是。 算法complexity是一个纯粹的理论构造,用于描述如何算法为不同的输入大小进行扩展(在这种情况下) ,发现和工会的数量。)

这并不能保证输入的特定实例所需的步骤数(例如:5查找和3联合) - 除了有限之外, 当然。事实上,big O notation使用任意大乘法常数的概念,这无助于计算精确的运行时间,但足以区分complexity classes中的算法。