С несколькими циклами между 2 узлами

#algorithm #graph #depth-first-search #cyclic-graph

#алгоритм #График #поиск в глубину #циклический граф

Вопрос:

Пытаюсь найти все циклы в a directed graph , через DFS . Но возникла проблема.


Проблема

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

Это связано с тем, что при посещении узла я пропускаю его, таким образом, этот более короткий цикл пропускается. Но, если я не пропущу посещенный узел, поиск DFS будет повторяться вечно.


Пример

График:

 1 -> [2, 4]
2 -> [3]
3 -> [4]
4 -> [1]
  

Существует 2 цикла между 1 и 4 :

  • (A) 1 -> 2 -> 3 -> 4 -> 1
  • (B) 1 -> 4 -> 1

Цикл B не может быть обнаружен, если A обнаружен первым, потому 4 что будет пропущен из-за посещения, и он никогда не возвращается к 1.


Текущие идеи

  • Одним из возможных решений является запуск с каждого узла, даже если он уже посещен. Но я хочу лучшее решение.
  • Вычислить и запомнить хэш пути, пропустить только тогда, когда существует тот же хэш? Это займет немного памяти, верно? И, все еще возможно, что 2 разных пути с одинаковым хэшем ведут к одному и тому же узлу, это не может полностью решить проблему.

Есть идеи?

Ответ №1:

Кредиты: https://www.hackerearth.com/practice/notes/finding-all-elementry-cycles-in-a-directed-graph /

 integer list array A(n);logical array marked(n);integer stack current_stack ;integer stack marked_stack;/* A(n) is the array of list wich is adjacency list representation*/
 integer procedure intialize(); /*initialize the values*/
    begin;
    for i in n do 
         marked(i):=false
integer procedure print_cycles();
    begin
        for i in current_stack do
            print i ;       
logical procedure backtrack(k) do
    begin
        logical flag=false;
        current_stack->push(k);
        marked_stack->push(k);
        marked(n):=true;
        for i in A(k) do
            if i < s; /* To find only disticnt cycles in topological manner*/
               delete A(i);
            if i==s; /Cycle found */
                print_cycles()
            if marked(i):= false;
                backtrack(n); /*continue dfs*/
        if flag :=true;
            for i in marked_stack do /*unmark the elements that have been visited in any of the cycles starting from s*/
                marked(i):=false;
        current_stack->pop(k);
        backtrack:=flag
    end   backtrack(k)
begin 
    integer procedure backtrack_Util();
        begin
            for s in n do
               backtrack(s);
               while marked_stack(s)->empty do
                    for i in marked_stack do
                        marked(i):=false
     end backtrack_Util()
  

Мы хотим найти отдельные циклы. Следовательно, нам нужно посещать вершины в некотором порядке. В этом порядке нам нужно найти циклы, начинающиеся с этой вершины, и цикл не должен содержать никаких вершин, которые находятся перед начальной вершиной в порядке. Как получить этот порядок? Слова topological manner в одном из комментариев выше неоднозначны, topological sort что не так. Я думаю, что мы можем выбрать порядок так же просто, как номер вершины, например 0,1,2, .., v. Допустим, мы хотим найти цикл, начинающийся с 2. Чтобы избежать нахождения повторяющихся циклов, мы не будем использовать вершины 0 и 1. Если существует какой-либо цикл, состоящий из ребер от 2 до 1 или от 2 до 0, он уже был бы учтен при нахождении циклов, начинающихся с 0 или 1.


Позвольте мне представить конкретную ссылку, которая поможет вам с этой задачей. Это алгоритм Джонсона. По-видимому, это самый быстрый способ выполнить задачу.

На странице 3 упоминается:

Чтобы избежать дублирования цепей, вершина v блокируется, когда она добавляется к некоторому элементарному пути, начинающемуся с s. Он остается заблокированным до тех пор, пока каждый путь от v до s пересекает текущий элементарный путь в вершине, отличной от s. Кроме того, вершина не становится корневой вершиной для построения элементарных путей, если она не является наименьшей вершиной хотя бы в одном элементарном контуре.

Вы также можете посмотреть это видео на YouTube для большего понимания.

Я думаю, что эта информация приемлема.

Комментарии:

1. Вероятно, это не сработает, потому topology sort что работает с DAG, который является ациклическим. Но входной график содержит циклы, поэтому …