Алгоритм нахождения Гамильтонова цикла в условиях теорем Дирака и Оре — различия между версиями
Ak57 (обсуждение | вклад) (→Псевдокод) |
Ak57 (обсуждение | вклад) (→Псевдокод) |
||
Строка 17: | Строка 17: | ||
for i < n //перебираем все пары соседних вершин в перестановке | for i < n //перебираем все пары соседних вершин в перестановке | ||
if <tex> v_i v_{i+1} \in \mathbb{E} </tex> //если есть ребро | if <tex> v_i v_{i+1} \in \mathbb{E} </tex> //если есть ребро | ||
− | continue | + | continue //переходим к следующей паре |
else //иначе | else //иначе | ||
for <tex>v_j \in \mathbb{V} \setminus \{v_i, v_{i + 1}\}</tex> //перебираем все вершины | for <tex>v_j \in \mathbb{V} \setminus \{v_i, v_{i + 1}\}</tex> //перебираем все вершины | ||
if <tex>v_i v_j \in \mathbb{E}\ \mid \mid v_{i+1} v_{j+1} \in \mathbb{E}</tex> //если есть ребра <tex>v_i v_j,\ v_{i+1} v_{j+1} </tex> | if <tex>v_i v_j \in \mathbb{E}\ \mid \mid v_{i+1} v_{j+1} \in \mathbb{E}</tex> //если есть ребра <tex>v_i v_j,\ v_{i+1} v_{j+1} </tex> | ||
− | swap(<tex> i+1, j</tex>) | + | swap(<tex> i+1, j</tex>) //разворачиваем часть перестановки от <tex>\mathrm{i}+1 </tex> до <tex>\mathrm{j} </tex> |
− | continue | + | continue //переходим к следующей паре вершин |
|width = "310px" | | |width = "310px" | |
Версия 17:11, 10 октября 2013
Описание алгоритма
Алгоритм находит гамильтонов цикл в неориентированном графе , если выполняются условия теоремы Оре или выполнена теорема Дирака. Рассмотрим перестановку вершин , где . Если между каждой парой соседних вершин в перестановке существует ребро, то мы получили Гамильтонов цикл. В противном случае начнем последовательно рассматривать пары соседних вершин , начиная с пары .
Если между ними есть ребро, то переходим к следующей паре вершин
.Если же ребра нет, то найдем такую вершину
, что , и существуют ребра и . После чего перевернем часть перестановки от до включительно(считаем, что наша перестановка зациклиный список). Например, если , то и поменяются местами, а останется на месте.Псевдокод
i = 1 for i < n //перебираем все пары соседних вершин в перестановке if//если есть ребро continue //переходим к следующей паре else //иначе for //перебираем все вершины if //если есть ребра swap( ) //разворачиваем часть перестановки от до continue //переходим к следующей паре вершин |
Доказательство алгоритма
Заметим, что поскольку мы сделали нашу перестановку в виде зацикленного списка, то мы можем рассматривать перебор все пар соседних в перестановке вершин, как сдвиг указателя на начало списка. Тогда будем сдвигать указатель на нашу перестановку так, чтобы она начиналась с рассматриваемой пары
. Если теперь между первыми двумя вершинами есть ребро, то можем переходить к рассмотрению следующей пары, так как в этом случае мы ничего не делаем. Если же ребра нет, то докажем, что обязательно найдется вершина , такая что .Пусть теоремы Оре или теоремы Дирака, в зависимости от наших начальных условий. А значит , следовательно искомая вершина обязательно найдется. Поскольку каждый раз, когда у нас нет ребра между двумя обрабатываемыми вершинами, мы переворачиваем нашу последовательность так, чтобы после переворота и становились связанными ребром, то, рассмотрев все пары вершин в последовательности, мы добьемся того, что любые две соседние пары вершин будут связаны ребром, а это и значит что мы нашли цикл.
{ } и { } . Тогда , откуда . Но по условию