n-顶点子图枚举的时间复杂度

时间:2011-05-29 11:29:45

标签: java algorithm graph time-complexity subgraph

我有一个算法,可以通过给定的顶点创建P顶点上所有可能子图的列表。这不完美 但我认为它应该工作正常。问题是当我试图计算它的时间复杂度时我迷失了。

我想起了T(p) = 2^d + 2^d * (n * T(p-1) )d=Δ(G), p=#vertices required, n=|V|。这真的只是猜测。 任何人都可以帮我这个吗?

使用的powerSet()算法应为O(2^d)O(d*2^d)

private void connectedGraphsOnNVertices(int n, Set<Node> connectedSoFar, Set<Node> neighbours, List<Set<Node>> graphList) {
    if (n==1) return;

    for (Set<Node> combination : powerSet(neighbours)) {
        if (connectedSoFar.size() + combination.size() > n || combination.size() == 0) {
            continue;
        } else if (connectedSoFar.size() + combination.size() == n) {
            Set<Node> newGraph = new HashSet<Node>();
            newGraph.addAll(connectedSoFar);
            newGraph.addAll(combination);
            graphList.add(newGraph);
            continue;
        }

        connectedSoFar.addAll(combination);
        for (Node node: combination) {
            Set<Node> k = new HashSet<Node>(node.getNeighbours());
            connectedGraphsOnNVertices(n, connectedSoFar, k, graphList);
        }
        connectedSoFar.removeAll(combination);
    }
}

1 个答案:

答案 0 :(得分:1)

看起来算法有一个错误,因为在递归调用之后,组合出现的节点也可能出现在connectedSoFar中,因此connectedSoFar.size()+ combination.size()等于n的检查似乎不正确,因为它可能会计算一个节点两次。

无论如何,除了分析算法,你在powerset中有2个 d 元素; “elase”分支中的每个操作都需要O(n)时间,因为connectedSoFar和组合在一起不能包含多于n个节点。然后将元素添加到connectedSoFar,因为|组合|需要O(n log n)时间≤n。组合节点上的迭代发生O(n)次;在其中有O(d)操作来构造散列集k然后递归调用。

然后用X(n)表示过程的复杂性,其中n是参数。

X(n)~2 d (n + n log n + n(d + X(n - 1)))

因为在递归调用中你已经为图形添加了至少一个顶点,所以在实践中,递归调用中的参数n实际上减少了至少一个。

将此简化为

X(n)~2 d (n(1 + d + log n + X(n - 1)))

因为d是常数,标记D = 2 d ,消除常数1,你得到

X(n)~D n(d + log n + X(n-1))

你可以分析为

X(n)〜(2 d n n! (d + log n)

显示您的算法实际上是时间耗费:)