Мне нужен алгоритм, который дает один экземпляр цикла в ориентированном графе, если таковой имеется. Может ли кто-нибудь показать мне направление? В псевдокоде или, что предпочтительнее, в 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]]
, который включает в себя цикл, который я хочу, но также включает дополнительные ребра, которые не имеют отношения к циклу.