<?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=91.144.140.113&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=91.144.140.113&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/91.144.140.113"/>
		<updated>2026-04-29T15:14:29Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%93%D0%B0%D0%BC%D0%B8%D0%BB%D1%8C%D1%82%D0%BE%D0%BD%D0%BE%D0%B2%D1%8B_%D0%B3%D1%80%D0%B0%D1%84%D1%8B&amp;diff=63823</id>
		<title>Гамильтоновы графы</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%93%D0%B0%D0%BC%D0%B8%D0%BB%D1%8C%D1%82%D0%BE%D0%BD%D0%BE%D0%B2%D1%8B_%D0%B3%D1%80%D0%B0%D1%84%D1%8B&amp;diff=63823"/>
				<updated>2018-02-27T12:34:51Z</updated>
		
		<summary type="html">&lt;p&gt;91.144.140.113: /* Основные определения */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Файл:Hamiltonial.png|300px|thumb|right|Граф додекаэдра с выделенным циклом Гамильтона]]&lt;br /&gt;
==Основные определения==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Гамильтоновым путём''' (англ. ''Hamiltonian path'') называется простой путь, проходящий через каждую вершину графа ровно один раз.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = defCycle&lt;br /&gt;
|definition =&lt;br /&gt;
'''Гамильтоновым циклом''' (англ. ''Hamiltonian cycle'') называют замкнутый гамильтонов путь.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
Граф называется '''полугамильтоновым''' (англ. ''Semihamiltonian graph''), если он содержит гамильтонов путь.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = hamiltonian_graph&lt;br /&gt;
|definition =&lt;br /&gt;
Граф называется '''гамильтоновым''' (англ. ''Hamiltonian graph''), если он содержит гамильтонов цикл. &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;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;n \geqslant 3&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\deg\ v \geqslant n/2&amp;lt;/tex&amp;gt;  для любой вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; неориентированного графа  &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, то  &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} гамильтонов граф.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===[[Теорема Оре|Теорема Оре]]===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Если &amp;lt;tex&amp;gt;n \geqslant  3&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;\deg\ u + \deg\ v \geqslant n&amp;lt;/tex&amp;gt;  для любых двух различных несмежных вершин &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; неориентированного графа  &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt;, то  &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} гамильтонов граф.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===[[Теорема Поша|Теорема Поша]]===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = Поша&lt;br /&gt;
|statement = Пусть граф &amp;lt;tex&amp;gt; G &amp;lt;/tex&amp;gt; имеет &amp;lt;tex&amp;gt;n \geqslant 3&amp;lt;/tex&amp;gt; вершин и выполнены следующие два условия:&lt;br /&gt;
&lt;br /&gt;
*для всякого &amp;lt;tex&amp;gt;k,\, 1 \leqslant k &amp;lt; (n-1)/2&amp;lt;/tex&amp;gt;, число вершин со степенями, не превосходящими &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;, меньше чем &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;;&lt;br /&gt;
*для нечетного &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; число вершин степени &amp;lt;tex&amp;gt;(n-1)/2&amp;lt;/tex&amp;gt; не превосходит &amp;lt;tex&amp;gt;(n-1)/2&amp;lt;/tex&amp;gt;, &lt;br /&gt;
&lt;br /&gt;
тогда &amp;lt;tex&amp;gt; G &amp;lt;/tex&amp;gt; {{---}} гамильтонов граф.&lt;br /&gt;
}}&lt;br /&gt;
===[[Теорема_Редеи-Камиона|Теорема Редеи-Камиона]]===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|statement=&lt;br /&gt;
Любой сильносвязный [[Турниры|турнир]] {{---}} гамильтонов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===[[Теорема Гуйя-Ури]]===&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about=&lt;br /&gt;
Ghouila-Houri&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} сильносвязный ориентированный граф. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
    \deg^+ v \geqslant n/2 \\&lt;br /&gt;
    \deg^- v \geqslant n/2 \\&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
\end{matrix} \Bigg\} \Rightarrow &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tex&amp;gt; &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; {{---}} гамильтонов.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===[[Теорема Хватала|Теорема Хватала]]===&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about=&lt;br /&gt;
Хватал&lt;br /&gt;
|statement=&lt;br /&gt;
Пусть:&lt;br /&gt;
* &amp;lt;tex&amp;gt; G &amp;lt;/tex&amp;gt; {{---}} [[Отношение связности, компоненты связности|связный граф]],&lt;br /&gt;
* &amp;lt;tex&amp;gt; n = |VG| \geqslant 3 &amp;lt;/tex&amp;gt; {{---}} количество вершин,&lt;br /&gt;
* &amp;lt;tex&amp;gt; d_1 \leqslant  d_2 \leqslant  \ldots \leqslant  d_n &amp;lt;/tex&amp;gt; {{---}} его последовательность степеней.&lt;br /&gt;
Тогда если &amp;lt;tex&amp;gt; \forall k \in \mathbb N &amp;lt;/tex&amp;gt; верна импликация: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;tex&amp;gt; d_k \leqslant  k &amp;lt; n/2 \Rightarrow d_{n - k} \geqslant n - k, (*) &amp;lt;/tex&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
то граф &amp;lt;tex&amp;gt; G &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;
{{Задача&lt;br /&gt;
|definition = &lt;br /&gt;
'''Задача о коммивояжере''' (англ. ''Travelling salesman problem, TSP'') — задача, в которой коммивояжер должен посетить &amp;lt;tex&amp;gt; N &amp;lt;/tex&amp;gt; городов, побывав в каждом из них ровно по одному разу и завершив путешествие в том городе, с которого он начал. В какой последовательности ему нужно обходить города, чтобы общая длина его пути была наименьшей?&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Варианты решения  ====&lt;br /&gt;
&lt;br /&gt;
Задача о коммивояжере относится к классу [[NP-полнота задач о гамильтоновом цикле и пути в графах | NP-полных задач]]. Рассмотрим два варианта решения с экспоненциальным временем работы.&lt;br /&gt;
&lt;br /&gt;
=====  Перебор перестановок =====&lt;br /&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;O({N!}\times{N})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===== Динамическое программирование по подмножествам (по маскам) =====&lt;br /&gt;
&lt;br /&gt;
Задача о коммивояжере представляет собой поиск кратчайшего гамильтонова цикла в графе.&lt;br /&gt;
Зафиксируем начальную вершину &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; и будем искать гамильтонов цикл наименьшей стоимости — путь от &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt;, проходящий по всем вершинам (кроме первоначальной) один раз. Т.к. искомый цикл проходит через каждую вершину, то выбор &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; не имеет значения. Поэтому будем считать &amp;lt;tex&amp;gt;s = 0 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Подмножества вершин будем кодировать битовыми векторами, обозначим &amp;lt;tex&amp;gt;mask_i&amp;lt;/tex&amp;gt; значение &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ого бита в векторе &amp;lt;tex&amp;gt;mask&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Обозначим &amp;lt;tex&amp;gt;d[i][mask]&amp;lt;/tex&amp;gt; как наименьшую стоимость пути из вершины &amp;lt;tex&amp;gt;i&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;j&amp;lt;/tex&amp;gt;, для которых &amp;lt;tex&amp;gt;mask_j = 1&amp;lt;/tex&amp;gt; (т.е. &amp;lt;tex&amp;gt;d[i][mask]&amp;lt;/tex&amp;gt; уже  найденный оптимальный путь от &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой вершины до &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;-ой, проходящий через те вершины, где &amp;lt;tex&amp;gt;mask_j=1&amp;lt;/tex&amp;gt;. Если &amp;lt;tex&amp;gt;mask_j=0&amp;lt;/tex&amp;gt;,то эти вершины еще не посещены).&lt;br /&gt;
&lt;br /&gt;
Алгоритм поиска цикла будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
*Начальное состояние — когда находимся в &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;-й вершине, ни одна вершина не посещена, а пройденный путь равен &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt; (т.е. &amp;lt;tex&amp;gt;i = 0&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;mask = 0&amp;lt;/tex&amp;gt;). &lt;br /&gt;
*Для остальных состояний (&amp;lt;tex&amp;gt;i \ne 0&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;mask \ne 0&amp;lt;/tex&amp;gt;) перебираем все возможные переходы в &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ую вершину из любой посещенной ранее и выбираем минимальный результат.&lt;br /&gt;
*Если возможные переходы отсутствуют, решения для данной подзадачи не существует (обозначим ответ для такой подзадачи как &amp;lt;tex&amp;gt;\infty&amp;lt;/tex&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Стоимостью минимального гамильтонова цикла в исходном графе будет значение &amp;lt;tex&amp;gt; d[0][2^n-1]&amp;lt;/tex&amp;gt; — стоимость пути из &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;-й вершины в &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;-ю, при необходимости посетить все вершины. Данное решение требует &amp;lt;tex&amp;gt;O({2^n}\times{n})&amp;lt;/tex&amp;gt; памяти и &amp;lt;tex&amp;gt;O({2^n}\times{n^2})&amp;lt;/tex&amp;gt; времени.&lt;br /&gt;
&lt;br /&gt;
Для того, чтобы восстановить сам путь, воспользуемся соотношением &amp;lt;tex&amp;gt; d[i][mask] = w(i, j) + d[j][mask - 2^j] &amp;lt;/tex&amp;gt;,  которое выполняется для всех ребер, входящих в минимальный цикл . Начнем с состояния &amp;lt;tex&amp;gt; i = 0 &amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; mask = 2^n - 1&amp;lt;/tex&amp;gt;, найдем вершину &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, для которой выполняется указанное соотношение, добавим &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt; в ответ, пересчитаем текущее состояние как &amp;lt;tex&amp;gt;i = j&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; mask = mask - 2^j &amp;lt;/tex&amp;gt;. Процесс заканчивается в состоянии &amp;lt;tex&amp;gt;i = 0&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt; mask = 0 &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===== Оптимизация решения методом динамического программирования =====&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;dp[mask][i]&amp;lt;/tex&amp;gt; содержит булево значение — существует ли в подмножества &amp;lt;tex&amp;gt;mask&amp;lt;/tex&amp;gt; гамильтонов путь, заканчивающийся в вершине &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Сама динамика будет такая: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
d[mask][i] = \left\{\begin{array}{llcl}&lt;br /&gt;
1&amp;amp;;\ |mask| = 1,\ mask_i = 1\\&lt;br /&gt;
\bigvee_{mask[j]=1, (j, i) \in E}\limits d[mask \oplus 2^i][j] &amp;amp;;\ |mask| &amp;gt; 1,\ mask_i= 1 \\&lt;br /&gt;
 0&amp;amp;;\ otherwise\\&lt;br /&gt;
\end{array}\right.&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это решение требует &amp;lt;tex&amp;gt;O(2^nn)&amp;lt;/tex&amp;gt; памяти и &amp;lt;tex&amp;gt;O(2^nn^2)&amp;lt;/tex&amp;gt; времени. Эту оценку можно улучшить, если изменить динамику следующим образом.&lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;tex&amp;gt;d'[mask]&amp;lt;/tex&amp;gt; хранит маску подмножества всех вершин, для которых существует гамильтонов путь в подмножестве &amp;lt;tex&amp;gt;mask&amp;lt;/tex&amp;gt;, заканчивающихся в этой вершине. Другими словами, сожмем предыдущую динамику: &amp;lt;tex&amp;gt;d'[mask]&amp;lt;/tex&amp;gt; будет равно &amp;lt;tex&amp;gt;\sum_{i \in [0..n-1]}\limits d[mask][i] \cdot 2 ^i &amp;lt;/tex&amp;gt;. Для графа &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; выпишем &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; масок &amp;lt;tex&amp;gt;M_i&amp;lt;/tex&amp;gt;, для каждой вершины задающие множество вершин, которые связаны ребром в данной вершиной. То есть &amp;lt;tex&amp;gt;M_i = \sum_{j \in [0..n-1]}\limits 2^j \cdot ((i, j) \in E ? 1:0) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Тогда динамика перепишется следующим образом: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tex&amp;gt;&lt;br /&gt;
d'[mask] = \left\{\begin{array}{llcl}&lt;br /&gt;
mask &amp;amp;;\ |mask| = 1 \\&lt;br /&gt;
\sum_{i \in [0..n-1] \&amp;amp; mask_i=1}\limits 2^i \cdot ((d[mask \oplus 2^i] \&amp;amp; M_i) \neq 0?1:0) &amp;amp;;\ |mask| &amp;gt; 1 \\&lt;br /&gt;
 0&amp;amp;;\ otherwise\\&lt;br /&gt;
\end{array}\right.&lt;br /&gt;
&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Особое внимание следует уделить выражению &amp;lt;tex&amp;gt;d[mask \oplus 2^i] \&amp;amp; M_i&amp;lt;/tex&amp;gt; . Первая часть выражения содержит подмножество вершин, для которых существует гамильтонов путь, заканчивающихся в соответствующих вершинах в подмножестве &amp;lt;tex&amp;gt;mask&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;\&amp;amp;&amp;lt;/tex&amp;gt; не равен &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;), то, как нетрудно понять, в &amp;lt;tex&amp;gt;mask&amp;lt;/tex&amp;gt; существует гамильтонов путь, заканчивающийся в вершине &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Окончательная проверка состоит в сравнении &amp;lt;tex&amp;gt;d[2^n - 1]&amp;lt;/tex&amp;gt; c &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Это решение использует &amp;lt;tex&amp;gt;O(2^n)&amp;lt;/tex&amp;gt; памяти и имеет асимптотику &amp;lt;tex&amp;gt;O(2^nn)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
&lt;br /&gt;
Прежде чем писать код, скажем пару слов о порядке обхода состояний. Обозначим за &amp;lt;tex&amp;gt;|mask|&amp;lt;/tex&amp;gt; количество единиц в маске (иначе говоря количество пройденных вершин не считая текущей). Тогда, поскольку при рассмотрении состояния &amp;lt;tex&amp;gt;\langle i, mask \rangle&amp;lt;/tex&amp;gt; мы смотрим на состояния&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;\langle j, mask - 2^j \rangle&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;|mask| = |mask - 2^j| + 1&amp;lt;/tex&amp;gt;, то состояния с большим &amp;lt;tex&amp;gt;|mask|&amp;lt;/tex&amp;gt; должны быть посещены позже, чтобы к моменту вычисления текущего состояния были вычислены все те, которые используются для его подсчёта. &lt;br /&gt;
Однако если использовать рекурсию, об этом можно не беспокоиться  (и сэкономить немало кода, времени и памяти).&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;span style=&amp;quot;color:Green&amp;quot;&amp;gt;// все переменные используются из описания алгоритма, &amp;lt;tex&amp;gt;\infty&amp;lt;/tex&amp;gt; = бесконечность&amp;lt;/span&amp;gt;&lt;br /&gt;
  '''function''' findCheapest(i, mask):&lt;br /&gt;
    '''if''' d[i][mask] != &amp;lt;tex&amp;gt;\infty&amp;lt;/tex&amp;gt; &lt;br /&gt;
      '''return''' d[i][mask] &lt;br /&gt;
    '''for''' j = 0 .. n - 1&lt;br /&gt;
      '''if''' w(i, j) существует '''and''' j-ый бит mask == 1  &lt;br /&gt;
        d[i][mask] = '''min'''(d[i][mask], findCheapest(j, mask - &amp;lt;tex&amp;gt;2^j&amp;lt;/tex&amp;gt;) + w(i, j))&lt;br /&gt;
  '''return''' d[i][mask]&lt;br /&gt;
  &lt;br /&gt;
  '''function''' start():&lt;br /&gt;
    '''for''' i = 0 .. n - 1&lt;br /&gt;
      '''for''' mask = 0 .. &amp;lt;tex&amp;gt;2^n&amp;lt;/tex&amp;gt; - 1&lt;br /&gt;
       d[i][mask] = &amp;lt;tex&amp;gt;\infty&amp;lt;/tex&amp;gt;&lt;br /&gt;
    d[0][0] = 0&lt;br /&gt;
    ans = findCheapest(0, &amp;lt;tex&amp;gt;2^n&amp;lt;/tex&amp;gt; - 1)&lt;br /&gt;
    '''return''' ans&lt;br /&gt;
Дальше ищем сам цикл:&lt;br /&gt;
  '''function''' findWay():&lt;br /&gt;
    i = 0&lt;br /&gt;
    mask = &amp;lt;tex&amp;gt;2^n&amp;lt;/tex&amp;gt; - 1&lt;br /&gt;
    path.push(0)&lt;br /&gt;
    '''while''' mask != 0&lt;br /&gt;
      '''for''' j = 0 .. n - 1&lt;br /&gt;
        '''if''' w(i, j) существует '''and''' j-ый бит mask == 1 '''and''' d[i][mask] == d[j][mask - &amp;lt;tex&amp;gt;2^j&amp;lt;/tex&amp;gt;] + w(i, j) &lt;br /&gt;
          path.push(j)&lt;br /&gt;
          i = j&lt;br /&gt;
          mask = mask - &amp;lt;tex&amp;gt;2^j&amp;lt;/tex&amp;gt;&lt;br /&gt;
          '''continue'''&lt;br /&gt;
&lt;br /&gt;
==== Алгоритм нахождения гамильтонова цикла ====&lt;br /&gt;
Алгоритм нахождения гамильтонова цикла легко получить слегка изменив алгоритм нахождения минимального гамильтонова цикла.&lt;br /&gt;
В массиве  &amp;lt;tex&amp;gt;d[i][mask]&amp;lt;/tex&amp;gt; мы хранили расстояния, но сейчас нас не интересует какой длины будет это расстояние, так как главной задачей является нахождение цикла. В этом массиве мы теперь просто храним посещение вершин. И каждый раз, когда при запуске находим непосещенную вершину, то запускаем функцию рекурсивно от нее. Если она возвращает &amp;lt;tex&amp;gt; true&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;
*[[Задача о наибольшей возрастающей подпоследовательности]]&lt;br /&gt;
*[[Задача о рюкзаке]]&lt;br /&gt;
*[[Алгоритм нахождения Гамильтонова цикла в условиях теорем Дирака и Оре]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*Харари Ф. Теория графов: Пер. с англ. / Предисл. В. П. Козырева; Под ред. Г.П.Гаврилова. Изд. 4-е. — М.: Книжный дом &amp;quot;ЛИБРОКОМ&amp;quot;, 2009. — 60 с.&lt;br /&gt;
*Седжвик Р. Фундаментальные алгоритмы на C++. Алгоритмы на графах. — СПб: ООО «ДиаСофтЮП», 2002.&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Гамильтонов_граф Гамильтонов граф]&lt;br /&gt;
*[http://ru.wikipedia.org/wiki/Задача_коммивояжёра Задача коммивояжера в русской википедии]&lt;br /&gt;
*[http://de.wikipedia.org/wiki/Problem_des_Handlungsreisenden Задача коммивояжера в немецкой википедии]&lt;br /&gt;
*''Романовский И. В.'' Дискретный анализ. СПб.: Невский Диалект; БХВ-Петербург, 2003. ISBN 5-7940-0114-3&lt;br /&gt;
*''Кормен Т., Лейзерсон Ч., Ривест Р., Штайн К.'' Алгоритмы: построение и анализ, 2-е издание. М.: Издательский дом &amp;quot;Вильямс&amp;quot;, 2005. ISBN 5-8459-0857-4&lt;br /&gt;
&lt;br /&gt;
[[Категория:Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория:Обходы графов]]&lt;br /&gt;
[[Категория:Гамильтоновы графы]]&lt;br /&gt;
[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория:Динамическое программирование]]&lt;br /&gt;
[[Категория:Классические задачи динамического программирования]]&lt;/div&gt;</summary>
		<author><name>91.144.140.113</name></author>	</entry>

	</feed>