Найти количество путей заданной длины в неориентированном невзвешенном графе

'' пути-это количество ребер в пути.

учитывая источник и вершину назначения, я хочу найти количество путей сформировать исходную вершину до конечной вершины длиной k.

  • мы можем посещать каждую вершину столько раз, сколько хотим, поэтому, если путь от a до b выглядит так: a -> c -> b -> c -> b считается действительным. Это означает, что могут быть циклы и мы можем пойти через пункт назначения не один раз.

  • две вершины могут быть соединены более чем одним ребром. Так что если вершины a в вершину b соединены двумя ребрами, затем пути,a -> b через край 1 и a -> b via edge 2 считаются разными.

  • число вершин N равно

  • поскольку ответ может быть очень большим, следует сообщить по модулю некоторые число.

вот что я думал до сих пор:

можно использовать в ширину-поиск не помечая вершины как посещенные, на каждой итерации мы отслеживаем количество ребер "n_e", необходимых для этого пути, и продукт 'p' количества повторяющихся ребер, которые имеет каждое ребро на нашем пути.

поиск поиск должен завершиться, если n_e больше, чем k, если мы когда-либо достигнем места назначения с n_eравный k, мы прекращаем поиск и добавляем p для подсчета количества путей.

Я думаю, что мы могли бы использовать поиск по глубине вместо поиска по ширине, поскольку нам не нужен кратчайший путь, а размер Q, используемый в первом поиске по ширине, может быть недостаточно.

второй алгоритм, о котором я думаю, похож на для Floyd Warshall это используя этой подход . Только нам не нужен кратчайший путь, поэтому я не уверен, что это правильно.

проблема у меня с моего первого алгоритма заключается в том, что " К " может быть до 1000000000, а это значит, что мой поиск продлится до 10^9 краев и n_e ребро графа будет увеличиваться всего на 1 на каждом уровне, который будет очень медленным, и я не уверен, что это будет когда-нибудь завершить для больших входов.

поэтому мне нужен другой подход для решения этой проблемы; любая помощь будет очень признательна.

3 ответов


Итак, вот отличный трюк теории графов, который я помню для этого.

сделать матрицу смежности A. где A[i][j] 1, если существует ребро между i и j, и 0 в противном случае.

тогда количество путей длины k между i и j - просто [i][j] запись A^k.

Итак, чтобы решить проблему, build A и построить A^k, используя матричное умножение (обычный трюк для выполнения возведения в степень применяется здесь). Тогда просто найдите нужную запись.

EDIT: Ну, вам нужно сделать модульную арифметику внутри умножения матрицы, чтобы избежать проблем с переполнением, но это гораздо меньшая деталь.


на самом деле запись [i][j] a^k показывает общее различное "хождение", а не "путь" в каждом простом графике. Мы можем легко доказать это с помощью "математической индукции". Однако главный вопрос заключается в том, чтобы найти совершенно другой "путь" в данном графике. У нас есть довольно много разных алгоритмов для решения, но верхняя полоса выглядит следующим образом:

(n-2)(n-3)...(n-k) который "k" является заданным параметром, указывающим длину пути.


позвольте мне добавить еще немного контента выше ответы (как это расширенная проблема с которой я столкнулся). Расширенная проблема

найти количество путей длины k в данном неориентированном дереве.

решение просто для данной матрицы смежности A графика G найтик-1 иk а затем подсчитайте номер 1s в элементах над диагональю (или ниже.)

позвольте мне также добавить код python.

import numpy as np

def count_paths(v, n, a):
    # v: number of vertices, n: expected path length
    paths = 0    
    b = np.array(a, copy=True)

    for i in range(n-2):
        b = np.dot(b, a)

    c = np.dot(b, a)
    x = c - b

    for i in range(v):
        for j in range(i+1, v):
            if x[i][j] == 1:
                paths = paths + 1

    return paths

print count_paths(5, 2, np.array([
                np.array([0, 1, 0, 0, 0]),
                np.array([1, 0, 1, 0, 1]),
                np.array([0, 1, 0, 1, 0]),
                np.array([0, 0, 1, 0, 0]),
                np.array([0, 1, 0, 0, 0])
            ])