<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=217.66.156.108&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=217.66.156.108&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/217.66.156.108"/>
		<updated>2026-05-01T18:21:34Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BD%D0%B0%D1%85%D0%BE%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D1%8F_%D0%93%D0%B0%D0%BC%D0%B8%D0%BB%D1%8C%D1%82%D0%BE%D0%BD%D0%BE%D0%B2%D0%B0_%D1%86%D0%B8%D0%BA%D0%BB%D0%B0_%D0%B2_%D1%83%D1%81%D0%BB%D0%BE%D0%B2%D0%B8%D1%8F%D1%85_%D1%82%D0%B5%D0%BE%D1%80%D0%B5%D0%BC_%D0%94%D0%B8%D1%80%D0%B0%D0%BA%D0%B0_%D0%B8_%D0%9E%D1%80%D0%B5&amp;diff=55675</id>
		<title>Алгоритм нахождения Гамильтонова цикла в условиях теорем Дирака и Оре</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BD%D0%B0%D1%85%D0%BE%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D1%8F_%D0%93%D0%B0%D0%BC%D0%B8%D0%BB%D1%8C%D1%82%D0%BE%D0%BD%D0%BE%D0%B2%D0%B0_%D1%86%D0%B8%D0%BA%D0%BB%D0%B0_%D0%B2_%D1%83%D1%81%D0%BB%D0%BE%D0%B2%D0%B8%D1%8F%D1%85_%D1%82%D0%B5%D0%BE%D1%80%D0%B5%D0%BC_%D0%94%D0%B8%D1%80%D0%B0%D0%BA%D0%B0_%D0%B8_%D0%9E%D1%80%D0%B5&amp;diff=55675"/>
				<updated>2016-10-30T12:09:55Z</updated>
		
		<summary type="html">&lt;p&gt;217.66.156.108: В описании индексируемся с единицы, свап [2, i], в псевдокоде - с единицы [1, i). @Katsz&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
{{Задача&lt;br /&gt;
|definition = Пусть дан граф &amp;lt;tex&amp;gt;G = \left \langle {V, E} \right \rangle&amp;lt;/tex&amp;gt;, удовлетворяющий условию [[Теорема Оре|теоремы Оре]] или [[Теорема Дирака|теоремы Дирака]]. Требуется найти в нем гамильтонов цикл.&lt;br /&gt;
}}&lt;br /&gt;
== Описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Поступим следующим образом: заведем очередь и положим в нее все вершины нашего графа (не важно в каком порядке). Пусть &amp;lt;tex&amp;gt; n = \left | V \right |&amp;lt;/tex&amp;gt;. Тогда &amp;lt;tex&amp;gt;n(n -1)&amp;lt;/tex&amp;gt; раз будем делать следующую операцию:&lt;br /&gt;
&lt;br /&gt;
* Пусть &amp;lt;tex&amp;gt; v_1 &amp;lt;/tex&amp;gt; {{---}} это голова очереди, &amp;lt;tex&amp;gt; v_2 &amp;lt;/tex&amp;gt; {{---}} следующая за ней вершина и так далее. Если между первой и второй вершиной в очереди есть ребро в графе &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, то перемещаем первую вершину в конец очереди и переходим к следующей итерации.&lt;br /&gt;
* Если между первой и второй вершиной в очереди ребра нет, то найдем вершину &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;i &amp;gt; 2&amp;lt;/tex&amp;gt;, такую что, ребра &amp;lt;tex&amp;gt;v_1v_i, v_2v_{i+1} \in E&amp;lt;/tex&amp;gt; (так как у нас для графа выполнена либо [[Теорема Оре|теорема Оре]], либо [[Теорема Дирака|теорема Дирака]], то такая вершина обязательно найдется; чуть позже докажем это явно). После чего поменяем в очереди местами вершины &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;v_3&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{i-1}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;v_{2+j} &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{i-j}&amp;lt;/tex&amp;gt;, и так далее, пока &amp;lt;tex&amp;gt;2 + j &amp;lt; i - j&amp;lt;/tex&amp;gt; (то есть &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; пробегает все значения от &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; до значения заданного неравенством). Теперь у нас появилось ребро между первой и второй вершинами в очереди (теперь вторая вершина, это та, которая была до разворота на &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-й позиции), а также, гарантированно существует ребро между &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-й и &amp;lt;tex&amp;gt;(i+1)&amp;lt;/tex&amp;gt;-й вершинами очереди. После этого, так же как и в первом случае, оправляем первую вершину в конец очереди.&lt;br /&gt;
&lt;br /&gt;
Таким образом после &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; итераций, мы получаем последовательность (вершины лежащие в очереди), где любые 2 соседние вершины соединены ребром, все вершины графа находятся в этой последовательности, и более того, каждая ровно один раз, а также существует ребро между последней и первой вершинами очереди, а это и значит, что мы решили поставленную задачу.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
Функция &amp;lt;tex&amp;gt;\mathtt{findHamiltonianCycle}&amp;lt;/tex&amp;gt; получает на вход граф &amp;lt;tex&amp;gt; G &amp;lt;/tex &amp;gt; и находит гамильтонов цикл в нем.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex&amp;gt; queue &amp;lt;/tex&amp;gt; {{---}} очередь вершин графа &amp;lt;tex&amp;gt;G = \left \langle {V, E} \right \rangle&amp;lt;/tex&amp;gt;&lt;br /&gt;
{| width = 100%&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
    '''function''' findHamiltonianCycle(&amp;lt;tex&amp;gt;\left \langle {V, E} \right \rangle&amp;lt;/tex&amp;gt;):&lt;br /&gt;
      '''for''' &amp;lt;tex&amp;gt; v \in V&amp;lt;/tex&amp;gt;:                                          &amp;lt;font color = &amp;quot;green&amp;quot;&amp;gt;// Добавляем все вершины графа в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
        queue.pushBack(&amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt;)&lt;br /&gt;
      '''for''' k = 0..n * (n - 1)&lt;br /&gt;
        '''if''' (queue.at(0), queue.at(1)) &amp;lt;tex&amp;gt; \notin E&amp;lt;/tex&amp;gt;                &amp;lt;font color = &amp;quot;green&amp;quot;&amp;gt;// Проверяем существования ребра между первой и второй вершинами очереди&amp;lt;/font&amp;gt;&lt;br /&gt;
          i = 2                                             &lt;br /&gt;
          '''while''' (queue.at(0), queue.at(i)) &amp;lt;tex&amp;gt; \notin E&amp;lt;/tex&amp;gt; '''or''' (queue.at(1), queue.at(i + 1)) &amp;lt;tex&amp;gt; \notin E&amp;lt;/tex&amp;gt;&lt;br /&gt;
              i++                                         &amp;lt;font color = &amp;quot;green&amp;quot;&amp;gt;// Ищем индекс удовлетворяющую условию вершины&amp;lt;/font&amp;gt;&lt;br /&gt;
          queue.swapSubQueue(1, i)                        &amp;lt;font color = &amp;quot;green&amp;quot;&amp;gt;// Разворачиваем часть перестановки от 2-й до найденной позиции включительно&amp;lt;/font&amp;gt;&lt;br /&gt;
        queue.pushBack(queue.top())&lt;br /&gt;
        queue.pop()&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Доказательство алгоритма ==&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=Каждый раз, когда нам надо искать вершину &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;i &amp;gt; 2&amp;lt;/tex&amp;gt;, такую что &amp;lt;tex&amp;gt;v_1v_i, v_2v_{i+1} \in E&amp;lt;/tex&amp;gt;, такая вершина действительно существует.&lt;br /&gt;
|proof=Рассмотрим множество &amp;lt;tex&amp;gt;S = \{i\mid v_1v_i \in E\}&amp;lt;/tex&amp;gt;, состоящее из индексов вершин, смежных с &amp;lt;tex&amp;gt;v_1&amp;lt;/tex&amp;gt;, и множество &amp;lt;tex&amp;gt;T = \{i+1 \mid v_2v_{i+1} \in E\}&amp;lt;/tex&amp;gt;, индексов вершин смежных с &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt;. Заметим, что &amp;lt;tex&amp;gt;S \subset \{3, 4, \ldots, n\}&amp;lt;/tex&amp;gt;, а &amp;lt;tex&amp;gt;T \subset \{2, 3, \ldots, n - 1\}&amp;lt;/tex&amp;gt;, тогда &amp;lt;tex&amp;gt;S\cup T\subset \{2, 3, \ldots, n\} &amp;lt;/tex&amp;gt;, а значит &amp;lt;tex&amp;gt;\left\vert S\cup T\right\vert \leqslant n-1&amp;lt;/tex&amp;gt;, в то же время &amp;lt;tex&amp;gt;\left\vert S \right\vert + \left\vert T \right\vert = \operatorname{deg} v_1 + \operatorname{deg} v_2 \geqslant n&amp;lt;/tex&amp;gt; (по условию [[Теорема Оре|теоремы Оре]] или [[Теорема Дирака|теоремы Дирака]]). Из этого следует, что &amp;lt;tex&amp;gt;S\cap T\ne \varnothing&amp;lt;/tex&amp;gt;, а это и значит, что искомая вершина существует.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=После &amp;lt;tex&amp;gt;n(n - 1)&amp;lt;/tex&amp;gt; итераций между каждой парой соседних вершин очереди существует ребро.&lt;br /&gt;
|proof=Достаточно заметить, что каждую итерацию алгоритма, мы, в случае отсутствия ребра, между &amp;lt;tex&amp;gt;v_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{2}&amp;lt;/tex&amp;gt; увеличиваем количество пар соседних в очереди вершин, между которыми есть ребро, как минимум на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; (это прямое следствие условия поиска нужной вершины, в случае отсутствия ребра), для поиска такой пары требуется не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; итераций. Таких пар изначально не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, откуда следует, что после &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; итераций, второе условие будет выполнено.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=Алгоритм находит гамильтонов цикл.&lt;br /&gt;
|proof=Из предыдущих лемм следует корректность алгоритма.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Поиск вершины, удовлетворяющей заданному условию работает за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;, а таких поисков будет осуществлено не более чем &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Оставшиеся &amp;lt;tex&amp;gt;n(n - 2)&amp;lt;/tex&amp;gt; итерации выполняются за &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Тогда алгоритм выполняется за &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== См.также ==&lt;br /&gt;
*[[Гамильтоновы графы]]&lt;br /&gt;
*[[Теорема Оре]]&lt;br /&gt;
*[[теорема Дирака|Теорема Дирака]]&lt;br /&gt;
*[[Очередь]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
*[http://rain.ifmo.ru/cat/view.php/theory/graph-circuits-cuts/hamiltonian-2005 Дискретная математика: Алгоритмы {{---}} Гамильтоновы графы]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Обходы графов]]&lt;br /&gt;
[[Категория: Гамильтоновы графы]]&lt;/div&gt;</summary>
		<author><name>217.66.156.108</name></author>	</entry>

	</feed>