Коды Грея для перестановок — различия между версиями
ZeRoGerc (обсуждение | вклад) (→Источники информации) |
ZeRoGerc (обсуждение | вклад) |
||
| Строка 114: | Строка 114: | ||
|style="background-color:#FFF;padding:2px 30px"| <tex>\{2, 1, 3\} </tex> | |style="background-color:#FFF;padding:2px 30px"| <tex>\{2, 1, 3\} </tex> | ||
|} | |} | ||
| + | |||
| + | == Реализация в нерекурсивном виде. Алгоритм Джонсона-Троттера == | ||
== Сведение задачи построения кода Грея для перестановок к графам == | == Сведение задачи построения кода Грея для перестановок к графам == | ||
Версия 00:15, 7 декабря 2014
Коды Грея для перестановок(англ. Gray code for permutation) — упорядочение перестановок, при котором соседние перестановки отличаются только элементарной транспозицией.
Элементарная транспозиция(англ. Adjacent transposition) — перестановка местами двух соседних элементов.
Содержание
- 1 Построение кода Грея для перестановок
- 2 Пример применения алгоритма
- 3 Псевдокод получения кода Грея
- 4 Примеры кодов Грея для перестановок
- 5 Реализация в нерекурсивном виде. Алгоритм Джонсона-Троттера
- 6 Сведение задачи построения кода Грея для перестановок к графам
- 7 См. также
- 8 Источники информации
Построение кода Грея для перестановок
Будем строить код Грея для длины . Предположим, что нам известен код Грея для перестановок длиной . Возьмем первую перестановку из известного нам кода. Она имеет следующий вид:
Сначала запишем число в начало этой перестановки, после чего будем двигать его вправо элементарными транспозициями (подчёркнуты пары переставляемых элементов).
Получим различных перестановок, отличающихся одной элементарной транспозицией. Возьмем следующую перестановку из кода Грея для перестановок длины и припишем в конце число . Эта перестановка отличается на одну элементарную транспозицию (последние элементы совпадают, а префиксы длины отличаются на элементарную транспозицию). Пусть она имеет следующий вид:
Элемент записываем в конец и начинаем "двигать" его влево:
Продолжаем аналогично. Для каждой перестановки дописываем в один конец (поочерёдно), и с помощью элементарных транспозиций двигаем в другой конец, при этом добавляя каждую промежуточную перестановку в список.
Таким образом получаем для каждой перестановки длиной (всего штук) по новых перестановок, в сумме перестановок. Все они различны, так как для любых двух перестановок из нового кода Грея элемент стоит на разных позициях,а если стоит на одной и той же позиции, то эти перестановки образованы от разных перестановок длиной . Так же все соседние перестановки отличаются ровно в одной элементарной транспозиции. Итого, мы получили список из различных перестановок длиной , причём соседние отличаются в одной элементарной транспозиции.
Пример применения алгоритма
Рассмотрим код Грея для длины :
Тогда следуя алгоритму полученный код будет выглядеть так (подчёркнуты пары переставляемых элементов):
- — берем первую перестановку и добавляем в начало тройку
- — двигаем до последней позиции
- — берем следующую перестановку и записываем тройку в конец
- — двигаем в начало
Код Грея получен.
Псевдокод получения кода Грея
Получаем код Грея рекурсивно, в базовом случае возвращаем список из одной перестановки .
list<permutation> gray_code(n):
if n == 1
return [{1}] //возращаем список из одной перестановки
else
list<permutation> result = [] //пустой список
list<permutation> perms = gray_code(n - 1) //perms — перестановки из n - 1 элемента
bool backward = false //переменная которая говорит с какой стороны заполнять перестановку
(for perm in perms) //perm — текущая перестановка
if backward
permutation current = concat(perm, {n}) //дописываем {n} в конец perm
result.append(current) //добавляем в ответ перестановку current
(for i = n downto 2)
swap(current[i - 1], current[i]) //переставляем n
result.append(current) //добавляем в ответ перестановку current
else
permutation current = concat({n}, perm) //дописываем {n} в начало perm
result.append(current) //добавляем в ответ перестановку current
(for i = 1 to n - 1)
swap(current[i], current[i + 1]) //переставляем n
result.append(current) //добавляем в ответ перестановку current
backward = !backward //меняем состояние backward
return result //возвращаем ответ в виде списка
Примеры кодов Грея для перестановок
Перестановки для n = 2
| Номер | Перестановка |
|---|---|
Перестановки для n = 3
| Номер | Перестановка |
|---|---|
Реализация в нерекурсивном виде. Алгоритм Джонсона-Троттера
Сведение задачи построения кода Грея для перестановок к графам
Последовательность перестановок, полученная с помощью данного алгоритма имеет интересную интерпретацию. Так, если рассмотреть граф, вершины которого соответствуют всем перестановкам и в котором две вершины, соответствующие перестановкам и , соединены ребром, если образуется из однократной транспозицией соседних элементов, то полученная последовательность является гамильтоновым путем в этом графе.
См. также
Источники информации
- Романовский И.В. Дискретный Анализ - Санкт-Петербург, 2003. - стр. 39-41 - ISBN 5-94157-330-8
- Федоряева Т.И. Комбинаторные алгоритмы - Новосибирск, 2011. - стр. 36-46 - ISBN 978-5-4437-0019-9
- Ананий Левитин, Алгоритмы. Введение в разработку и анализ - Москва. Санкт-Петербург. Киев, 2006. - стр. 226 - 229 - ISBN 5-8459-0987-2