Поиск самого длинного цикла в ориентированном графе с использованием DFS

Мне нужно найти самый длинный цикл в ориентированном графе, используя DFS.

Я когда-то видел эту статью в Википедии, описывающую способ сделать это, и я думаю, что она подошла к проблеме, похожей на маркировку node с одним из трех состояний: node еще не посетил, закончил поиск node, и node посетили, но еще не закончили посещение.

Я был бы признателен, если бы кто-нибудь мог поделиться ссылкой со мной. Кстати, это не алгоритм Тарьяна.

Проблема ниже - это то, что я пытаюсь решить, если вы хотите узнать.

Две цифры, указанные в первой строке, - это N и M, каждая из которых представляет количество узлов и количество направленных ребер.

Из второй строки заданы M наборов из двух цифр A и B, что означает, что node A и B связаны, но вы можете пересекать только node от A до B.

input.txt:

7 9  
1 2  
2 3  
3 1  
3 4  
4 5  
5 1  
5 6  
6 7  
7 2  

Ответ в этом случае равен 6, так как 2 > 3 > 4 > 5 > 6 > 7 > 2.

Ответ 1

Я думаю, что самый длинный элементарный цикл (или схема) лучше терминологии, чем самый длинный цикл.

Во всяком случае, этот pdf файл может оказаться полезным: Поиск всех элементарных схем на графике с графикой

В этом вопросе stackoverflow на один год есть много ссылок на связанные проблемы и алгоритмы:  Поиск всех циклов в ориентированном графе

Ответ 2

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

Что касается алгоритма, то простым способом решить проблему является возврат в исходное состояние --- запуск в узлах я = 1 до n и всегда изучение всех циклов, начинающихся с конкретного node i. Как только это будет сделано, вы устраните node я и продолжите для остальной части графика, начиная с node я + 1. Возможно, вы захотите сделать что-то вроде node -coloring в DFS, чтобы отличать узлы, которые вы никогда не хотите посещать, и те, которые вы посещали по пути в этом конкретном проходе. Вы также можете поместить что-то вроде отметки времени на узлах, подобно времени обнаружения, но в этом случае вам нужно писать эти времена каждый раз, когда вы обнаруживаете node, так как большинство узлов будут обнаружены много раз. Перечисленные выше документы могут быть полезны, и есть больше способов сделать это наверняка.

Ответ 3

Эта проблема NP-Complete, и для нее не было многочленного алгоритма времени. Какова размер вашей проблемы? Я имею в виду, сколько узлов будет во входном графе?

задача самого длинного цикла сводится к проблеме гамильтонова цикла: http://mathworld.wolfram.com/HamiltonianCycle.html

Ответ 4

У меня есть ответ, объясняющий простой способ найти все циклы в ориентированном графе, используя Python и networkX в другом сообщении. Поиск всех циклов в ориентированном графе

Решение выведет список, содержащий все циклы ориентированного графа.

Вы можете использовать этот вывод, чтобы найти самый длинный цикл, который показан ниже:

import networkx as nx

# Create Directed Graph
G=nx.DiGraph()

# Add a list of nodes:
G.add_nodes_from(["1","2","3","4","5","6","7","9"])

# Add a list of edges:
G.add_edges_from([("7","9"),("1","2"),("2","3"),("3","1"),("3","4"),("4","5"),("5","1"),("5","6"),("6","7"),("7","2")])

#Return a list of cycles described as a list o nodes
all_cycles = list(nx.simple_cycles(G))

#Find longest cycle
answer = []
longest_cycle_len = 0
for cycle in all_cycles:
    cycle_len = len(cycle)
    if cycle_len>longest_cycle_len:
        answer =cycle
        longest_cycle_len = cycle_len

print "Longest Cycle is {} with length {}.".format(answer,longest_cycle_len)

Ответ: Самый длинный цикл: ['3', '4', '5', '6', '7', '2'] длиной 6.

Если вам интересно, верните исходный ответ. Это старая дискуссия со многими ответами, и это поможет принести новое решение.