Как определить, есть ли у данного графа цикл, содержащий все его узлы? Есть ли в предложенном алгоритме недостатки?

У меня есть связанный, ненаправленный граф с N узлами и 2N-3 ребрами. Вы можете рассматривать граф так, как будто он построен на существующем исходном графе, который имеет 3 узла и 3 ребра. Каждый узел добавлен в граф и имеет 2 соединения с существующими узлами в графе. Когда все узлы добавлены к графу (всего добавлено N-3 узлов), строится окончательный граф.

Первоначально меня спрашивают, какое максимальное количество узлов в этом графе можно посетить ровно один раз (за исключением начального узла), то есть каково максимальное количество узлов, содержащихся в наибольшем гамильтоновом пути данного графа? (Хорошо, сказать, что наибольший гамильтонов путь - неверная фраза, но, учитывая характер вопроса, мне нужно найти максимальное количество узлов, которые посещаются один раз, и поездка заканчивается на начальном узле. Я думал, что это может быть рассматривается как подграф, который является гамильтоновым и состоит из максимального числа узлов, таким образом, наибольший возможный гамильтонов путь).

Поскольку меня не просят найти путь, я должен сначала проверить, существует ли гамильтонов путь для данного количества узлов. Я знаю, что планарные графы и циклический график s (C n) являются гамильтоновы графы (я также знаю теорему Оре для гамильтоновых графов, но с графом я буду работать on не будет плотным графом с большой вероятностью, что делает теорему Оре практически бесполезной в моем случае). Поэтому мне нужно найти алгоритм для проверки того, является ли граф циклическим графом, т.е. существует ли цикл, который содержит все узлы данного графа.

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

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

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

Изменить

Я понял с помощью комментария (спасибо за н.м.):

Граф циклов состоит из одного цикла, имеет N ребер и N вершин. Если существует цикл, содержащий все узлы данного графа, это гамильтонов цикл. - н.м.

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

Поразмыслив, я подумал, что каким бы ни было количество узлов, граф кажется гамильтоновым из-за критериев добавления узлов. Проблема в том, что я не могу быть уверенным и не могу этого доказать. Изменяет ли добавление узлов таким образом, то есть добавление новых узлов с 2 ребрами, которые соединяют добавленный узел с существующими узлами, гамильтоново свойство графа? Если это не меняет гамильтонова свойства, то как? Если это изменится, то как же так? Спасибо.

ИЗМЕНИТЬ №2

Я снова понял, что построение графа описанным мной способом может изменить гамильтоново свойство. Рассмотрим вводные данные следующим образом:

1 3
2 3
1 5
1 3

эти входные данные говорят, что 4-й узел подключен к узлу 1 и узлу 3, 5-й узел - к узлу 2 и узлу 3. . .

4-й и 7-й узлы подключены к одним и тем же узлам, что снижает максимальное количество узлов, которые можно посетить ровно один раз, на 1. Если я обнаруживаю эти коллизии (НЕ, включая ввод, такой как 3 3, который является примером, который вы предложили, поскольку проблема гласит, что недавно добавленные ребра подключены к 2 другим узлам) и уменьшите максимальное количество узлов, начиная с N, я считаю, что могу получить правильный результат .

Видите ли, я не выбираю связи, они даны мне, и я должен найти макс. количество узлов.

Я думаю, подсчет одинаковых соединений при построении графика и вычитание количества одинаковых соединений из N даст правильный результат? Можете ли вы подтвердить это или в этом алгоритме есть изъян?


person Varaquilex    schedule 06.04.2013    source источник
comment
Почему планарные графы должны быть гамильтоновыми? Любое дерево плоско, но, конечно, не гамильтоново.   -  person G. Bach    schedule 07.04.2013
comment
может быть лучше подходит для math.stackexchange.com   -  person linski    schedule 07.04.2013
comment
Я бы сказал примерно следующее: ostermiller.org/find_loop_singly_linked_list.html   -  person drum    schedule 07.04.2013
comment
Также можно использовать cs.stackexchange.com   -  person drum    schedule 07.04.2013
comment
Граф циклов состоит из одного цикла, имеет N ребер и N вершин. Если существует цикл, содержащий все узлы данного графа, это гамильтонов цикл.   -  person n. 1.8e9-where's-my-share m.    schedule 07.04.2013
comment
Вы имеете в виду, что каждый узел за пределами начального треугольника добавляется итеративно, и добавленный k-й узел имеет ровно два ребра к k-1 + 3 предыдущим узлам, или что каждый из добавленных n-3 узлов имеет два ребра к начальному треугольник? Кроме того, не могли бы вы объяснить, что вы имеете в виду, когда говорите, что имеете дело с плотными графами? Обычно плотные графы определяются как имеющие | E | в Θ (| V | ²).   -  person G. Bach    schedule 07.04.2013
comment
Мне любопытно, почему не сработала DFS? Похоже, вы могли бы отсортировать узлы по количеству возрастающих граней как эвристику ...   -  person dan    schedule 07.04.2013
comment
@ G.Bach Да, они добавляются итеративно. K-й узел имеет ровно 2 ребра по сравнению с предыдущими k-1 + 3 ребрами. Что я имел в виду о плотных графах, см. в этом SO вопрос. В этом случае, я думаю, мне следует проверить гамильтоновость при добавлении ребер, а не исследовать весь граф. Не так ли лучше?   -  person Varaquilex    schedule 07.04.2013
comment
@ Volkanİlbeyli Я неправильно понял ваш OP, я думал, вы сказали, что будете иметь дело с плотными графами.   -  person G. Bach    schedule 07.04.2013


Ответы (3)


Чтобы добавить некоторые пояснения к этой теме: поиск гамильтонова цикла является NP-полным, что означает, что поиск самого длинного цикла также является NP-полным, потому что, если мы можем найти самый длинный цикл в любом графе, мы можем найти гамильтонов цикл подграфа индуцированы вершинами, лежащими на этом цикле. (См. Также, например, этот документ относительно проблема самого длинного цикла)

Мы не можем использовать здесь критерий Дирака: Дирак говорит нам только minimum degree >= n/2 -> Hamiltonian Cycle, это подразумевает в противоположном направлении того, что нам нужно. Обратный способ определенно неверен: возьмем цикл по n вершинам, каждая вершина в нем имеет ровно степень 2, независимо от размера круга, но она имеет (является) HC. Что вы можете сказать от Дирака, так это то, что no Hamiltonian Cycle -> minimum degree < n/2, который здесь бесполезен, поскольку мы не знаем, есть ли у нашего графа HC или нет, поэтому мы не можем использовать импликацию (тем не менее, каждый график, который мы строим в соответствии с тем, что описал OP будет иметь вершину степени 2, а именно последнюю вершину, добавленную к графу, поэтому для произвольного n мы имеем минимальную степень 2).

Проблема в том, что вы можете построить как графы произвольного размера с HC, так и графы произвольного размера без HC. Для первой части: если исходный треугольник - это A, B, C и добавленные вершины пронумерованы от 1 до k, то соедините 1-ю добавленную вершину с A и C, а k + 1-ю вершину с A и k-ю. вершина для всех k> = 1. Цикл A,B,C,1,2,...,k,A. Для второй части соедините обе вершины 1 и 2 с A и B; этот граф не имеет HC.

Также важно отметить, что свойство наличия HC может меняться от одной вершины к другой во время построения. Вы можете как создать, так и уничтожить свойство HC при добавлении вершины, поэтому вам придется проверять его каждый раз, когда вы добавляете вершину. Простой пример: возьмите граф после добавления 1-й вершины и добавьте вторую вершину вместе с ребрами к тем же двум вершинам треугольника, с которыми была соединена 1-я вершина. Это строит из графа с HC граф без HC. Наоборот: добавьте теперь третью вершину и соедините ее с 1 и 2; это строится из графа без HC или графа с HC.
Сохранение последнего известного HC во время построения вам не поможет, потому что оно может полностью измениться. У вас может быть HC после добавления 20-й вершины, а затем не иметь его для k в [21,2000] и снова иметь один для добавленной вершины 2001-го. Скорее всего, HC, который у вас был на 23 вершинах, вам не сильно поможет.

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

person G. Bach    schedule 06.04.2013
comment
Я был +1. Я считаю, что есть способ проверить свойство HP при построении графика, поскольку он построен на основе простого правила, отличного от алгоритмов, перечисленных в Википедии. Вы так не думаете? - person Varaquilex; 08.04.2013
comment
Я не совсем уверен. Вы можете как создать, так и уничтожить свойство HP при добавлении вершины, поэтому вам придется проверять его каждый раз, когда вы добавляете вершину. Сохранение последнего известного HP во время строительства на самом деле вам не поможет, потому что оно может полностью измениться. У вас может быть HP после добавления 20-й вершины, а затем не иметь одного для k в [21,2000] и снова иметь один для добавленной вершины 2001-го. Скорее всего, HP, которые у вас были на 23 вершинах, вам не сильно помогут. - person G. Bach; 08.04.2013
comment
Дело в том, что я ищу максимальное количество узлов, которые можно посетить, когда вы начинаете со случайного узла, посещаете все (возможные) другие и заканчиваете поездку, с которой я начал. Поэтому я как бы ищу гамильтоновы циклы в подграфах. В вашем примере я бы искал гамильтонов цикл во всем графе, чего, собственно, нет. Поэтому существует алгоритм (я думаю, что на этот раз я его нашел, опубликую завтра после некоторого тестирования), проверяющий добавленные узлы и вершины, сохраняющий некоторые проблемные узлы в списке и решающий проблему таким образом. - person Varaquilex; 08.04.2013
comment
См. Первый абзац моего ответа; если вы можете эффективно найти подграф с гамильтоновым путем (или циклом), то вы можете сделать это для всего графа, если он гамильтонов. - person G. Bach; 08.04.2013
comment
@ Volkanİlbeyli Чтобы прояснить это: я не говорю, что то, о чем вы просите, не может быть выполнено эффективно, может быть, это возможно; но это невозможно сделать эффективно, используя любой из алгоритмов, которые дает любой из ответов. Если вы хотите решить эту проблему, вам нужно будет найти свойства графов, с которыми вы работаете, которые сделают вашу проблему проще, чем общая проблема Гамильтона Путь / Цикл. - person G. Bach; 08.04.2013

В этой задаче мы имеем connected, non-directed граф с N узлами и 2N-3 ребрами. Рассмотрим график, приведенный ниже,

            A
           / \
          B _ C
         ( )  
          D 

График не имеет гамильтонова цикла. Но График построен в соответствии с вашими правилами добавления узлов. Поэтому поиск гамильтонова цикла может не дать вам решения. Более того, даже если это возможно, обнаружение гамильтонова цикла является проблемой NP-Complete со сложностью O (2 N). Так что подход может быть не идеальным.

Я предлагаю использовать модифицированную версию Floyd's Cycle Finding algorithm (также называемую алгоритмом Tortoise and Hare).

Модифицированный алгоритм:

1. Initialize a List CYC_LIST to ∅.

2. Add the root node to the list CYC_LIST and set it as unvisited. 

3. Call the function Floyd() twice with the unvisited node in the list CYC_LIST for each of the two edges. Mark the node as visited.

4. Add all the previously unvisited vertices traversed by the Tortoise pointer to the list CYC_LIST.

5. Repeat steps 3 and 4 until no more unvisited nodes remains in the list.

6. If the list CYC_LIST contains N nodes, then the Graph contains a Cycle involving all the nodes.

Алгоритм вызывает алгоритм поиска цикла Флойда максимум 2N раз. Алгоритм поиска цикла Флойда требует линейного времени (O (N)). Таким образом, сложность модифицированного алгоритма составляет O (N 2), что намного лучше, чем экспоненциальное время, используемое подходом, основанным на гамильтоновом цикле.

Одна из возможных проблем с этим подходом состоит в том, что он будет обнаруживать closed paths вместе с циклами, если не будут реализованы более строгие критерии проверки.

Ответ на редактирование № 2

Рассмотрим график, приведенный ниже,

            A------------\
           / \            \
          B _ C            \
          |\ /|             \
          | D |             F
          \   /            /
           \ /            / 
            E------------/

Согласно вашему алгоритму у этого графа нет цикла, содержащего все узлы. Но в этом графе есть цикл, содержащий все узлы.

A-B-D-C-E-F-A

Так что я думаю, что в вашем подходе есть изъян. Но предположим, что если ваш алгоритм верен, он намного лучше, чем мой подход. Так как мой занимает O (n 2) времени, тогда как ваш занимает всего O (n).

person Deepu    schedule 07.04.2013
comment
Я думаю, вы неправильно поняли мой алгоритм. Видите ли, мой алгоритм сначала предполагает, что у вас есть N узлов в гамильтоновом цикле, а затем начинает строить граф (считывает ввод, на самом деле ничего не создается). Он просто сравнивает входные данные и, если видит столкновение, уменьшает количество узлов в гамильтоновом цикле. Таким образом, согласно структуре данных, выполнение задачи может занять O (n ‹sup› 2 ‹/sup›) времени. Теперь рассмотрим ваш пример: входной файл должен быть таким для этого графа: 2 2 (BB) 2 3 (DC) Однако я сказал, что новые узлы подключены к 2 другим узлам, что означает, что .. . - person Varaquilex; 07.04.2013
comment
входной файл НЕ может содержать такую ​​строку, как 2 2 (B B) в вашем случае. Поэтому, исправляя алгоритм в OP, удаляя строки типа 2 2 во входных данных, мой алгоритм, кажется, работает правильно, не так ли? - person Varaquilex; 07.04.2013
comment
Этот ответ тоже кажется неправильным; если я вас правильно понимаю, вы предлагаете обнаружить цикл, охватывающий все вершины графа в O (n ^ 2), что будет означать, что проблема гамильтонова пути разрешима за полиномиальное время. В любом случае алгоритм Флойда не обнаруживает самые длинные циклы (что подразумевает обнаружение гамильтоновых путей, если они есть), а только циклы. - person G. Bach; 08.04.2013
comment
@Г. Бах: Нет, я не предполагал, что P = NP :). В этом случае есть некоторые ограничения на добавление новых вершин в граф. Только для таких графиков мой подход будет иметь эффект. Более того, я уже упоминал, что он может выйти из строя, если есть закрытый путь. - person Deepu; 08.04.2013

Ниже я добавил три дополнительных узла (3,4,5) в исходный граф, и мне кажется, что я могу добавлять новые узлы бесконечно долго, сохраняя свойство гамильтонова цикла. Для графика ниже цикл будет 0-1-3-5-4-2-0

  1---3---5
 / \ / \ /
0---2---4

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

person sowrov    schedule 07.04.2013
comment
Дело в том, что Я не буду строить график, он будет построен в соответствии с заданными входными данными. Следовательно, это может быть как вы описали, так и что-то другое. Так что я должен это проверить при его создании. Я обновлю вопрос, вы его видите? - person Varaquilex; 07.04.2013