Временная сложность перечисления n-вершинного подграфа

У меня есть алгоритм для создания списка всех возможных подграфов на 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 ответ

Решение

Похоже, что в алгоритме есть ошибка, потому что после рекурсивного вызова, возможно, что узлы, которые появляются в комбинации, также появятся в connectedSoFar, поэтому проверка того, что connectedSoFar.size () + сочетание.size () равно n, кажется неправильной, так как может считать узел дважды.

В любом случае, для анализа алгоритма у вас есть 2d элементов в powerset; каждая операция в ветви "elase" занимает O(n) времени, потому что connectedSoFar и комбинация вместе не могут содержать более n узлов. Добавление элементов в connectedSoFar тогда занимает O(n log n) времени, потому что | комбинация | ≤ н. Итерация по узлам комбинации происходит O(n) раз; внутри него есть операция O(d) для построения хэш-множества k, а затем рекурсивный вызов.

Обозначим тогда сложность процедуры через X(n), где n - параметр. У тебя есть

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

потому что в рекурсивном вызове вы добавили в граф хотя бы одну вершину, поэтому на практике параметр n в рекурсивном вызове уменьшается практически как минимум на одну.

Упростите это до

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

потому что d постоянная, отметьте D = 2d, исключите постоянную 1, и вы получите

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

который вы можете проанализировать как

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

показывая, что твой алгоритм действительно является временным боровом:)

Другие вопросы по тегам