Мне нужен алгоритм, который дает один экземпляр цикла в ориентированном графе, если таковой имеется. Может ли кто-нибудь показать мне направление? В псевдокоде или, что предпочтительнее, в Ruby?
Ранее я задавал похожий вопрос и, следуя приведенным там предложениям, реализовал алгоритм Кана в Ruby, который определяет, есть ли в графе цикл, но я хочу не только того, есть ли у него цикл, но и один возможный экземпляр такого цикла.
example_graph = [[1, 2], [2, 3], [3, 4], [3, 5], [3, 6], [6, 2]]
Алгоритм Кана
def cyclic? graph
## The set of edges that have not been examined
graph = graph.dup
n, m = graph.transpose
## The set of nodes that are the supremum in the graph
sup = (n - m).uniq
while sup_old = sup.pop do
sup_old = graph.select{|n, _| n == sup_old}
graph -= sup_old
sup_old.each {|_, ssup| sup.push(ssup) unless graph.any?{|_, n| n == ssup}}
end
!graph.empty?
end
Приведенный выше алгоритм сообщает, есть ли в графе цикл:
cyclic?(example_graph) #=> true
но я хочу не только это, но и пример такого цикла:
#=> [[2, 3], [3, 6], [6, 2]]
Если бы я вывел переменную graph
в приведенном выше коде в конце проверки, это дало бы:
#=> [[2, 3], [3, 4], [3, 5], [3, 6], [6, 2]]
который включает в себя нужный мне цикл, но также включает в себя дополнительные ребра, которые не имеют отношения к циклу.