Алгоритм нахождения Гамильтонова цикла в условиях теорем Дирака и Оре — различия между версиями
Novik (обсуждение | вклад) (→Псевдокод) |
Novik (обсуждение | вклад) (→Псевдокод) |
||
| Строка 13: | Строка 13: | ||
== Псевдокод == | == Псевдокод == | ||
| − | Функция <tex>findHamiltonianCycle</tex> получает на вход | + | Функция <tex>findHamiltonianCycle</tex> получает на вход граф и находит гамильтонов цикл в нем. |
{| width = 100% | {| width = 100% | ||
|- | |- | ||
| | | | ||
| − | '''function''' <tex>\mathtt{findHamiltonianCycle}(queue) | + | '''function''' <tex>\mathtt{findHamiltonianCycle}(G):</tex> |
| + | <tex>\mathtt{Queue}</tex> <tex>\mathtt{queue}</tex> | ||
| + | '''for''' <tex> v \in V</tex>: <font color = "green">// Добавляем все вершины графа в очередь</font> | ||
| + | <tex>\mathtt{queue.pushBack}(v)</tex> | ||
'''for''' k = 0...n*(n - 1) | '''for''' k = 0...n*(n - 1) | ||
| − | '''if''' <tex>( | + | '''if''' <tex>(\mathtt{queue.at}(0), \mathtt{queue.at}(1)) \notin E</tex> <font color = "green">// Проверяем существования ребра между первой и второй вершинами очереди</font> |
| − | <tex>i = 2</tex> | + | <tex>\mathtt{i} = 2</tex> |
| − | '''while''' <tex>( | + | '''while''' <tex>(\mathtt{queue.at}(0), \mathtt{queue.at}(i)) \notin E</tex> '''or''' <tex>(\mathtt{queue.at}(1), \mathtt{queue.at}(i + 1)) \notin E</tex> |
| − | <tex>i</tex>++ <font color = "green">// Ищем индекс удовлетворяющую условию вершины</font> | + | <tex>\mathtt{i}</tex>++ <font color = "green">// Ищем индекс удовлетворяющую условию вершины</font> |
| − | <tex> | + | <tex>\mathtt{queue.swapSubQueue}(2, i)</tex> <font color = "green">// Разворачиваем часть перестановки от 2-й до найденной позиции включительно</font> |
| − | <tex> | + | <tex>\mathtt{queue.pushBack}(\mathtt{queue.top}())</tex> |
| − | <tex> | + | <tex>\mathtt{queue.pop}()</tex> |
|} | |} | ||
Версия 20:48, 8 ноября 2015
Содержание
| Задача: |
| Пусть дан граф , удовлетворяющий условию теоремы Оре или теоремы Дирака. Требуется найти в нем гамильтонов цикл. |
Описание алгоритма
Поступим следующим образом: заведем очередь и положим в нее все вершины нашего графа (не важно в каком порядке). Пусть . Тогда раз будем делать следующую операцию:
- Пусть — это голова очереди, — следующая за ней вершина и так далее. Если между первой и второй вершиной в очереди есть ребро в графе , то перемещаем первую вершину в конец очереди и переходим к следующей итерации.
- Если между первой и второй вершиной в очереди ребра нет, то найдем вершину , где , такую что, ребра (так как у нас для графа выполнена либо теорема Оре, либо теорема Дирака, то такая вершина обязательно найдется; чуть позже докажем это явно). После чего поменяем в очереди местами вершины и , и , и , и так далее, пока (то есть пробегает все значения от до значения заданного неравенством). Теперь у нас появилось ребро между первой и второй вершинами в очереди (теперь вторая вершина, это та, которая была до разворота на -й позиции), а также, гарантированно существует ребро между -й и -й вершинами очереди. После этого, так же как и в первом случае, оправляем первую вершину в конец очереди.
Таким образом после итераций, мы получаем последовательность (вершины лежащие в очереди), где любые 2 соседние вершины соединены ребром, все вершины графа находятся в этой последовательности, и более того, каждая ровно один раз, а также существует ребро между последней и первой вершинами очереди, а это и значит, что мы решили поставленную задачу.
Псевдокод
Функция получает на вход граф и находит гамильтонов цикл в нем.
function for : // Добавляем все вершины графа в очередь for k = 0...n*(n - 1) if // Проверяем существования ребра между первой и второй вершинами очереди while or ++ // Ищем индекс удовлетворяющую условию вершины // Разворачиваем часть перестановки от 2-й до найденной позиции включительно |
Доказательство алгоритма
| Лемма: |
Каждый раз, когда нам надо искать вершину , где , такую что , такая вершина действительно существует. |
| Доказательство: |
| Рассмотрим множество , состоящее из индексов вершин, смежных с , и множество , индексов вершин смежных с . Заметим, что , а , тогда , а значит , в то же время (по условию теоремы Оре или теоремы Дирака). Из этого следует, что , а это и значит, что искомая вершина существует. |
| Лемма: |
После итераций между каждой парой соседних вершин очереди существует ребро. |
| Доказательство: |
| Достаточно заметить, что каждую итерацию алгоритма, мы, в случае отсутствия ребра, между и увеличиваем количество пар соседних в очереди вершин, между которыми есть ребро, как минимум на (это прямое следствие условия поиска нужной вершины, в случае отсутствия ребра), для поиска такой пары требуется не более итераций. Таких пар изначально не более , откуда следует, что после итераций, второе условие будет выполнено. |
| Теорема: |
Алгоритм находит гамильтонов цикл. |
| Доказательство: |
| Из предыдущих лемм следует корректность алгоритма. |
Сложность алгоритма
Поиск вершины, удовлетворяющей заданному условию работает за , а таких поисков будет осуществлено не более чем . Оставшиеся итерации выполняются за . Тогда алгоритм выполняется за .