Вопрос 11

Задача поиска гамильтонова цикла в графе
Гамильтоновым циклом (путем) называют простой цикл (путь), содержащий все вершины графа. В графе, изображенном на рис. 8.1 слева, гамильтоновым циклом является, например, последовательность Описание: 1, Описание: 2, Описание: 3, Описание: 5, Описание: 4, Описание: 1. В графе, изображенном в центре, нет гамильтоновых циклов, но есть гамильтоновы пути, например, Описание: 2,1,3,5,4. В правом графе нет и гамильтоновых путей.
Описание: http://www.intuit.ru/department/algorithms/gaa/8/8-1.gif

Рис. 8.1. 
Внешне определение гамильтонова цикла похоже на определение эйлерова цикла. Однако есть кардинальное различие в сложности решения соответствующих задач распознавания и построения. Мы видели, что имеется достаточно простой критерий существования эйлерова цикла и эффективный алгоритм его построения. Для гамильтоновых же циклов (и путей) неизвестно никаких просто проверяемых необходимых и достаточных условий их существования, а все известные алгоритмы требуют для некоторых графов перебора большого числа вариантов.
Гамильтонов цикл представляет собой, с комбинаторной точки зрения, просто перестановку вершин графа. При этом в качестве начальной вершины цикла можно выбрать любую вершину, так что можно рассматривать перестановки с фиксированным первым элементом. Самый бесхитростный план поиска гамильтонова цикла состоит в последовательном рассмотрении всех этих перестановок и проверке для каждой из них, представляет ли она цикл в данном графе. Такой способ действий уже при не очень большом числе вершин становится практически неосуществимым ввиду быстрого роста числа перестановок - имеется Описание: (n-1)!перестановок из Описание: nэлементов с фиксированным первым элементом.
Более рациональный подход состоит в рассмотрении всевозможных простых путей, начинающихся в произвольно выбранной стартовой вершине Описание: a, до тех пор, пока не будет обнаружен гамильтонов цикл или все возможные пути не будут исследованы. По сути дела, речь тоже идет о переборе перестановок, но значительно сокращенном - если, например, вершина Описание: bне смежна с вершиной Описание: a, то все Описание: (n-2)!перестановок, у которых на первом месте стоит Описание: a, а на втором Описание: b, не рассматриваются.
Рассмотрим этот алгоритм подробнее. Будем считать, что граф задан окрестностями вершин: для каждой вершины Описание: xзадано множество вершин, смежных с Описание: x. На каждом шаге алгоритма имеется уже построенный отрезок пути, он хранится в стеке PATH. Для каждой вершины Описание: x, входящей в PATH, хранится множество Описание: N(x)всех вершин, смежных с Описание: x, которые еще не рассматривались в качестве возможных продолжений пути из вершины Описание: x. Когда вершина Описание: xдобавляется к пути, множество Описание: N(x)полагается равным Описание: V(x). В дальнейшем рассмотренные вершины удаляются из этого множества. Очередной шаг состоит в исследовании окрестности последней вершины Описание: xпути PATH. Если Описание: N(x)\ne \varnothingи в Описание: N(x)имеются вершины, не принадлежащие пути, то одна из таких вершин добавляется к пути. В противном случае вершина Описание: xисключается из стека. Когда после добавления к пути очередной вершины оказывается, что путь содержит все вершины графа, остается проверить, смежны ли первая и последняя вершины пути, и при утвердительном ответе выдать очередной гамильтонов цикл.
Этот алгоритм очень похож на алгоритм поиска в глубину и отличается от него по существу только тем, что открытая вершина, когда вся ее окрестность исследована, не закрывается, а опять становится новой (исключается из стека). В начале все вершины новые. Процесс заканчивается, когда все вершины опять станут новыми. На самом деле это и есть поиск в глубину, только не в самом графе, а в дереве путей. Вершинами этого дерева являются всевозможные простые пути, начинающиеся в вершине Описание: a, а ребро дерева соединяет два пути, один из которых получается из другого добавлением одной вершины в конце. На рис. 8.2 показаны граф и его дерево путей из вершины Описание: 1.
Описание: http://www.intuit.ru/department/algorithms/gaa/8/8-2.gif

Рис. 8.2. 
Рассмотрим другой алгоритм, выясняющий существование гамильтонова цикла, по сути близкий к поиску в ширину и имеющий не столь быстро (хотя все же быстро) растущую оценку трудоемкости.
Пусть граф Описание: Gзадан матрицей смежности Описание: A=\left\| A(i,j)\right\|. Выберем произвольно стартовую вершину Описание: aи определим для каждого Описание: k=0,1\ldots, n-2функцию Описание: H_{k} (x,X), где значениями переменной Описание: xявляются вершины, отличные от Описание: a, а значениями переменной Описание: X- Описание: k-элементные подмножества множества Описание: VG-\{ a\}, причем вершина Описание: xне должна принадлежать множеству Описание: X. Эти функции определяются так: полагаем Описание: H_{k} (x,X)=1, если существует простой путь длины Описание: k+1из вершины Описание: aв вершину Описание: x, проходящий только через вершины из множества Описание: X, и Описание: H_{k} (x,X)=0, если такого пути не существует. Тогда
Описание: H_{0} (x,\varnothing)=A(a,x) \qquad \text{для всех } x,
а для Описание: k>0
Описание: H_{k} (x,X)=\mathop{\vee}\limits_{y\in X} H_{k-1} (y,X-y)A(y,x). }
Таким образом, зная все значения функции Описание: H_{k-1}, мы можем вычислить все значения функции Описание: H_{k}, причем для вычисления одного значения требуется выполнить Описание: 2k-1логических операций. Общее количество логических операций для вычисления всех этих функций составит
Описание: (n-1)\suml_{k=1}^{n-2}\begin{pmatrix} {n-2} \\ k \end{pmatrix} (2k-1)=(n-1)(2^{n-2} (n-3)+1)=O(n^{2} 2^{n}).

После того, как будет вычислена функцияОписание: H_{n-2}, останется только для всех Описание: x, для которых Описание: H_{n-2} (x,X)=1(Описание: X в этом случае определяется однозначно), выяснить, чему равно Описание: A(x,a)- если хотя бы в одном случае это 1, то гамильтонов цикл существует. Очевидный недостаток данного алгоритма - необходимость хранения большого количества промежуточной информации.
Алгоритм 2. Поиск гамильтоновых циклов

  1. выбрать произвольно вершину Описание: a
  2. Описание: a\Rightarrow PATH
  3. Описание: N(a):=V(a)
  4. while Описание: PATH\ne \varnothingdo
  5. Описание: x\, :={\rm top}(PATH)
  6. if Описание: N(x)\ne \varnothing
  7. then взять Описание: y\in N(x)
  8. Описание: N(x):=N(x)-y
  9. if вершина Описание: yне находится в PATH
  10. then Описание: y\Rightarrow PATH
  11. Описание: N(y):=V(y)
  12. if PATH содержит все вершины
  13. then if Описание: yсмежна с Описание: a
  14. then выдать цикл
  15. else удалить вершину Описание: xиз PATH

На Главную

Hosted by uCoz