Алгоритм построения Эйлерова цикла — различия между версиями
Helm (обсуждение | вклад) (→Рекурсивная реализация) |
Helm (обсуждение | вклад) (→Описание алгоритма) |
||
Строка 1: | Строка 1: | ||
== Описание алгоритма == | == Описание алгоритма == | ||
− | Алгоритм находит [[Эйлеров цикл, Эйлеров путь, Эйлеровы графы, Эйлеровость орграфов|Эйлеров цикл]] как в [[Ориентированный граф|ориентированном | + | Алгоритм находит [[Эйлеров цикл, Эйлеров путь, Эйлеровы графы, Эйлеровость орграфов|Эйлеров цикл]] как в [[Ориентированный граф|ориентированном]], так и в неориентированном графе. Перед запуском алгоритма необходимо [[Эйлеров цикл, Эйлеров путь, Эйлеровы графы, Эйлеровость орграфов|проверить граф на эйлеровость]]. Чтобы построить [[Эйлеров цикл, Эйлеров путь, Эйлеровы графы, Эйлеровость орграфов|Эйлеров путь]], нужно запустить алгоритм из вершины с нечетной степенью.<br> |
Алгоритм напоминает поиск в глубину. Главное отличие состоит в том, что пройденными помечаются не вершины, а ребра графа. Начиная со стартовой вершины <tex>v</tex> строим путь, добавляя на каждом шаге не пройденное еще ребро. Вершины пути накапливаются в стеке <tex>S</tex>. Когда наступает момент, что для текущей вершины <tex>w</tex> все инцидентные ей ребра уже пройдены, записываем вершины из <tex>S</tex> в ответ, пока не встретим вершину, которой инцидентны не пройденные еще ребра. Тогда продолжаем путь вперед по не посещенным ребрам. | Алгоритм напоминает поиск в глубину. Главное отличие состоит в том, что пройденными помечаются не вершины, а ребра графа. Начиная со стартовой вершины <tex>v</tex> строим путь, добавляя на каждом шаге не пройденное еще ребро. Вершины пути накапливаются в стеке <tex>S</tex>. Когда наступает момент, что для текущей вершины <tex>w</tex> все инцидентные ей ребра уже пройдены, записываем вершины из <tex>S</tex> в ответ, пока не встретим вершину, которой инцидентны не пройденные еще ребра. Тогда продолжаем путь вперед по не посещенным ребрам. | ||
Версия 22:42, 8 марта 2012
Содержание
Описание алгоритма
Алгоритм находит Эйлеров цикл как в ориентированном, так и в неориентированном графе. Перед запуском алгоритма необходимо проверить граф на эйлеровость. Чтобы построить Эйлеров путь, нужно запустить алгоритм из вершины с нечетной степенью.
Алгоритм напоминает поиск в глубину. Главное отличие состоит в том, что пройденными помечаются не вершины, а ребра графа. Начиная со стартовой вершины строим путь, добавляя на каждом шаге не пройденное еще ребро. Вершины пути накапливаются в стеке . Когда наступает момент, что для текущей вершины все инцидентные ей ребра уже пройдены, записываем вершины из в ответ, пока не встретим вершину, которой инцидентны не пройденные еще ребра. Тогда продолжаем путь вперед по не посещенным ребрам.
Псевдокод
findPath(v): S.clear() S.add(v) while not stack.isEmpty(): w := S.top() if E contains(w, u): S.add(u) remove(w, u) else: S.pop() print w
Доказательство
Пусть
Покажем, что это маршрут содержащий все ребра.
Допустим, что в момент окончания работы алгоритма имеются еще не пройденные ребра. Поскольку граф связен, должно существовать хотя бы одно непройденное ребро, инцидентное посещенной вершине. Но тогда эта вершина не могла быть удалена из , и не мог стать пустым.
Будем говорить, что ребро представлено в или , если в какой-то момент работы алгоритма вершины и находятся рядом. Каждое ребро графа представлено в . Допустим в какой-то момент из в перемещена вершина , а следующей в лежит . Возможны 2 варианта:
- На следующем шаге перемещена в . Тогда представлено в .
- Сначала будет пройдена некоторая последовательность ребер, начинающаяся в вершине . Ввиду четности степеней эта последовательность может закончиться только в вершине , а значит она следующей попадет в и будет представлено в .
Отсюда понятно, что последовательность вершин в
Рекурсивная реализация
findPath(v): for (v, u) from E remove(v, u) findPath(u) print v
Время работы
Если реализовать удаление ребер за
, то алгоритм будет работать за .