Коды Грея для перестановок — различия между версиями
ZeRoGerc (обсуждение | вклад) (→Псевдокод получения кода Грея) |
ZeRoGerc (обсуждение | вклад) (→Псевдокод получения кода Грея) |
||
Строка 54: | Строка 54: | ||
Получаем код Грея рекурсивно, в базовом случае <tex>n = 1</tex> возвращаем список из одной перестановки <tex>\{1\}</tex>. | Получаем код Грея рекурсивно, в базовом случае <tex>n = 1</tex> возвращаем список из одной перестановки <tex>\{1\}</tex>. | ||
− | gray_code(n): | + | '''list'''<permutation> gray_code(n): |
− | + | '''if''' n == 1 | |
− | + | '''return''' [{1}] <font color=darkgreen> //возращаем список из одной перестановки</font color=darkgreen> | |
− | + | '''else''' | |
− | + | '''list'''<permutation> result = [] <font color=darkgreen> //пустой список</font color=darkgreen> | |
− | + | '''list'''<permutation> perms = gray_code(n - 1) <font color=darkgreen> //perms {{---}} перестановки из n - 1 элемента</font color=darkgreen> | |
− | + | '''bool''' backward = false <font color=darkgreen> //переменная которая говорит с какой стороны заполнять перестановку</font color=darkgreen> | |
− | + | ('''for''' perm '''in''' perms) <font color=darkgreen> //perm {{---}} текущая перестановка</font color=darkgreen> | |
− | + | '''if''' backward | |
− | + | '''permutation''' current = concat(perm, {n})<font color=darkgreen> //дописываем {n} в конец perm</font color=darkgreen> | |
− | + | result.append(current)<font color=darkgreen> //добавляем в ответ перестановку current</font color=darkgreen> | |
− | + | ('''for''' i = n '''downto''' 2) | |
− | + | swap(current[i - 1], current[i])<font color=darkgreen> //переставляем n</font color=darkgreen> | |
− | + | result.append(current) <font color=darkgreen> //добавляем в ответ перестановку current</font color=darkgreen> | |
− | + | '''else''' | |
− | + | '''permutation''' current = concat({n}, perm) <font color=darkgreen> //дописываем {n} в начало perm</font color=darkgreen> | |
− | |||
− | |||
− | |||
result.append(current) <font color=darkgreen> //добавляем в ответ перестановку current</font color=darkgreen> | result.append(current) <font color=darkgreen> //добавляем в ответ перестановку current</font color=darkgreen> | ||
− | + | ('''for''' i = 1 '''to''' n - 1) | |
− | + | swap(current[i], current[i + 1]) <font color=darkgreen> //переставляем n</font color=darkgreen> | |
+ | result.append(current) <font color=darkgreen> //добавляем в ответ перестановку current</font color=darkgreen> | ||
+ | backward = !backward <font color=darkgreen> //меняем состояние backward</font color=darkgreen> | ||
+ | '''return''' result <font color=darkgreen>//возвращаем ответ в виде списка</font color=darkgreen> | ||
== Примеры кодов Грея для перестановок == | == Примеры кодов Грея для перестановок == |
Версия 23:26, 6 декабря 2014
Коды Грея для перестановок(англ. Gray code for permutation) — упорядочение перестановок, при котором соседние перестановки отличаются только элементарной транспозицией.
Элементарная транспозиция(англ. Adjacent transposition) — перестановка местами двух соседних элементов.
Содержание
Построение кода Грея для перестановок
Будем строить код Грея для длины код Грея для перестановок длиной . Возьмем первую перестановку из известного нам кода. Она имеет следующий вид:
. Предположим, что нам известенСначала запишем число
в начало этой перестановки, после чего будем двигать его вправо элементарными транспозициями (подчёркнуты пары переставляемых элементов).Получим
различных перестановок, отличающихся одной элементарной транспозицией. Возьмем следующую перестановку из кода Грея для перестановок длины и припишем в конце число . Эта перестановка отличается на одну элементарную транспозицию (последние элементы совпадают, а префиксы длины отличаются на элементарную транспозицию). Пусть она имеет следующий вид:
Элемент
записываем в конец и начинаем "двигать" его влево:Продолжаем аналогично. Для каждой перестановки дописываем
в один конец (поочерёдно), и с помощью элементарных транспозиций двигаем в другой конец, при этом добавляя каждую промежуточную перестановку в список.Таким образом получаем для каждой перестановки длиной
(всего штук) по новых перестановок, в сумме перестановок. Все они различны, так как для любых двух перестановок из нового кода Грея элемент стоит на разных позициях,а если стоит на одной и той же позиции, то эти перестановки образованы от разных перестановок длиной . Так же все соседние перестановки отличаются ровно в одной элементарной транспозиции. Итого, мы получили список из различных перестановок длиной , причём соседние отличаются в одной элементарной транспозиции.Пример применения алгоритма
Рассмотрим код Грея для длины
:Тогда следуя алгоритму полученный код будет выглядеть так (подчёркнуты пары переставляемых элементов):
- — берем первую перестановку и добавляем в начало тройку
- — двигаем до последней позиции
- — берем следующую перестановку и записываем тройку в конец
- — двигаем в начало
Код Грея получен.
Псевдокод получения кода Грея
Получаем код Грея рекурсивно, в базовом случае
возвращаем список из одной перестановки .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