Нижегородский государственный университет им. Н.И.Лобачевского
Опубликован: 27.09.2006 | Доступ: свободный | Студентов: 3512 / 124 | Оценка: 4.44 / 4.11 | Длительность: 13:45:00
Специальности: Программист, Математик
Лекция 8:

Эйлеровы и гамильтоновы циклы

< Лекция 7 || Лекция 8: 123 || Лекция 9 >

В худшем случае время работы этого алгоритма тоже растет с факториальной скоростью. Например, для графа K_{n-1} +K_{1} (граф с двумя компонентами связности, одна из которых - полный граф с n-1 вершиной, другая - изолированная вершина), если в качестве стартовой выбрана не изолированная вершина, то будут рассмотрены все {(n-2)!} простых путей длины n-2 в большой компоненте. Вместе с тем, если перед поиском гамильтонова цикла исходный граф проверить на связность, то ответ будет получен быстро. Можно пойти дальше и при обходе дерева путей поверять на связность каждый встречающийся "остаточный граф", т.е. граф, получающийся из исходного удалением всех вершин рассматриваемого пути. Если этот граф несвязен, то этот путь не может быть продолжен до гамильтонова пути. Поэтому можно не исследовать соответствующую ветвь дерева, а вернуться к рассмотрению более короткого пути, удалив последнюю вершину (т.е. сделать "шаг назад" в поиске в глубину). Можно пойти еще дальше и заметить, что если некоторая вершина x DFS-дерева с корнем a является развилкой, т.е. имеет не менее двух сыновей, то в подграфе исходного графа, полученном удалением всех предков этой вершины, кроме нее самой, она будет шарниром. Поэтому путь от a до x в DFS-дереве не может быть продолжен до гамильтонова пути. Эти соображения приводят к следующей модификации алгоритма: обходим граф поиском в глубину с построением DFS-дерева, затем находим в этом дереве самую нижнюю развилку (развилку с наименьшим глубинным номером). Если ни одной развилки нет, то само DFS-дерево представляет собой гамильтонов путь и остается только проверить наличие ребра, соединяющего начало и конец пути. Если же x - развилка, то возвращаемся из x в предшествующую вершину пути, помечаем все вершины, кроме собственных предков вершины x, как непосещенные и возобновляем поиск в глубину с этого места.

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

Пусть граф 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, то гамильтонов цикл существует. Очевидный недостаток данного алгоритма - необходимость хранения большого количества промежуточной информации.

< Лекция 7 || Лекция 8: 123 || Лекция 9 >
Петр Петров
Петр Петров

произведение графов К(2)*О(4) фактически 4 отдельных графа К(2)?

Александр Лаврентьев
Александр Лаврентьев

много инструкций вида if - then - else

Например Procedure DFS(a) опишите каким образом следует понимать вложенность инструкций. Как в языке С ? 

т.е. следующее 

if (...) then (...)

if (...) then (...)

else(...)

 

раскрывается как 

if (...) then (...)

if (...) then (...)

         else(...)

или так :

if (...) then

 {  (...)

     if (...) then (...)

              else(...)

}

обьясните пожалуйста.