Пример цикла в ориентированном графе.

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

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

5
задан Community 23 May 2017 в 12:32
поделиться