Коды Грея для перестановок — различия между версиями
м (→Псевдокод получения Грея) |
(→Построение кода Грея для перестановок) |
||
| Строка 19: | Строка 19: | ||
Будем строить код Грея для длины <tex>n = k</tex>. Предположим, что нам известен код Грея для перестановок длиной <tex>k - 1</tex>. Возьмем первую перестановку из известного нам кода. Она имеет следующий вид: <tex>\{a_1, a_2, a_3, \dots, a_{k-1}\}</tex> | Будем строить код Грея для длины <tex>n = k</tex>. Предположим, что нам известен код Грея для перестановок длиной <tex>k - 1</tex>. Возьмем первую перестановку из известного нам кода. Она имеет следующий вид: <tex>\{a_1, a_2, a_3, \dots, a_{k-1}\}</tex> | ||
| − | Сначала запишем <tex>k</tex> в начало этой перестановки, после чего будем двигать его вправо элементарными транспозициями (подчёркнуты пары переставляемых элементов). | + | Сначала запишем число <tex>k</tex> в начало этой перестановки, после чего будем двигать его вправо элементарными транспозициями (подчёркнуты пары переставляемых элементов). |
* <tex>\{\underline{k, a_1}, a_2, a_3, \dots, a_{k-1}\}</tex> | * <tex>\{\underline{k, a_1}, a_2, a_3, \dots, a_{k-1}\}</tex> | ||
| Строка 28: | Строка 28: | ||
* <tex>\{a_1, a_2, a_3, \dots, a_{k-1}, k\}</tex> | * <tex>\{a_1, a_2, a_3, \dots, a_{k-1}, k\}</tex> | ||
| − | Получим <tex>k</tex> различных перестановок, отличающихся одной элементарной транспозицией. Возьмем следующую | + | Получим <tex>k</tex> различных перестановок, отличающихся одной элементарной транспозицией. Возьмем следующую перестановку из кода Грея для перестановок длины <tex>k - 1</tex> и припишем в конце число <tex>k</tex>. Эта перестановка отличается на одну элементарную транспозицию (последние элементы совпадают, а префиксы длины <tex>k - 1</tex> отличаются на элементарную транспозицию). Пусть она имеет следующий вид: |
| − | <tex>\{ | + | <tex>\{b_1, b_2,b_3, \dots, b_{k-1}\}</tex> |
Элемент <tex>k</tex> записываем в конец и начинаем "двигать" его влево: | Элемент <tex>k</tex> записываем в конец и начинаем "двигать" его влево: | ||
| − | * <tex>\{ | + | * <tex>\{b_1, b_2, b_3, \dots, \underline{b_{k-1}, k}\}</tex> |
| − | * <tex>\{ | + | * <tex>\{b_1, b_2, b_3, \underline{\dots, k}, b_{k-1}\}</tex> |
| − | * <tex>\{ | + | * <tex>\{b_1, b_2, \underline{b_3, k}, \dots, b_{k-1}\}</tex> |
| − | * <tex>\{ | + | * <tex>\{b_1, \underline{b_2, k}, b_3, \dots, b_{k-1}\}</tex> |
| − | * <tex>\{\underline{ | + | * <tex>\{\underline{b_2, k}, b_1, b_3, \dots, b_{k-1}\}</tex> |
| − | * <tex>\{k, | + | * <tex>\{k, b_1, b_2, b_3, \dots, b_{k-1}\}</tex> |
| − | + | Продолжаем аналогично. Для каждой перестановки дописываем <tex>k</tex> в один конец (поочерёдно), и с помощью элементарных транспозиций двигаем в другой конец, при этом добавляя каждую промежуточную перестановку в список. | |
| − | + | Таким образом получаем для каждой перестановки длиной <tex>k - 1</tex> (всего <tex>(k - 1)!</tex> штук) по <tex>k</tex> новых перестановок, в сумме <tex>k\cdot(k - 1)! = k!</tex> перестановок. Все они различны, так как для любых двух перестановок из нового кода Грея элемент <tex>k</tex> стоит на разных позициях,а если <tex>k</tex> стоит на одной и той же позиции, то эти перестановки образованы от разных перестановок длиной <tex>k - 1</tex>. Так же все соседние перестановки отличаются ровно в одной элементарной транспозиции. Итого, мы получили список из <tex>k!</tex> различных перестановок длиной <tex>k</tex>, причём соседние отличаются в одной элементарной транспозиции. | |
== Пример применения алгоритма == | == Пример применения алгоритма == | ||
Версия 10:25, 12 января 2012
Содержание
Определения
| Определение: |
| Коды Грея для перестановок — упорядочение перестановок, при котором соседние перестановки отличаются только элементарной транспозицией. Элементарная транспозиция — транспозиция двух соседних элементов. |
Примеры кодов Грея для перестановок
Построение кода Грея для перестановок
Будем строить код Грея для длины . Предположим, что нам известен код Грея для перестановок длиной . Возьмем первую перестановку из известного нам кода. Она имеет следующий вид:
Сначала запишем число в начало этой перестановки, после чего будем двигать его вправо элементарными транспозициями (подчёркнуты пары переставляемых элементов).
Получим различных перестановок, отличающихся одной элементарной транспозицией. Возьмем следующую перестановку из кода Грея для перестановок длины и припишем в конце число . Эта перестановка отличается на одну элементарную транспозицию (последние элементы совпадают, а префиксы длины отличаются на элементарную транспозицию). Пусть она имеет следующий вид:
Элемент записываем в конец и начинаем "двигать" его влево:
Продолжаем аналогично. Для каждой перестановки дописываем в один конец (поочерёдно), и с помощью элементарных транспозиций двигаем в другой конец, при этом добавляя каждую промежуточную перестановку в список.
Таким образом получаем для каждой перестановки длиной (всего штук) по новых перестановок, в сумме перестановок. Все они различны, так как для любых двух перестановок из нового кода Грея элемент стоит на разных позициях,а если стоит на одной и той же позиции, то эти перестановки образованы от разных перестановок длиной . Так же все соседние перестановки отличаются ровно в одной элементарной транспозиции. Итого, мы получили список из различных перестановок длиной , причём соседние отличаются в одной элементарной транспозиции.
Пример применения алгоритма
Рассмотрим код Грея для длины :
Тогда следуя алгоритму полученный код будет выглядеть так (подчёркнуты пары переставляемых элементов):
- — берем первую перестановку и добавляем в начало тройку
- — двигаем до последней позиции
- — берем следующую перестановку и записываем тройку в конец
- — двигаем в начало
Код Грея получен.
Псевдокод получения кода Грея
Получаем код Грея рекурсивно, в базовом случае () возвращаем список из одной перестановки .
gray_code(n):
if n == 1:
return = [{1}]
else:
result = []
perms = gray_code(n - 1)
backward = false
for perm in perms:
if backward:
current = concat(perm, {n})
result.append(current)
for (i = n; i > 1; i--):
swap(current[i - 1], current[i])
result.append(current)
else:
current = concat({n}, perm)
result.append(current)
for (i = 1; i < n; i++):
swap(current[i], current[i + 1])
result.append(current)
backward = !backward
return result
Сведение задачи построения кода Грея для перестановок к графам
Последовательность перестановок, полученная с помощью данного алгоритма имеет интересную интерпретацию. Так, если рассмотреть граф, вершины которого соответствуют всем перестановкам и в котором две вершины, соответствующие перестановкам и , соединены ребром, если образуется из однократной транспозицией соседних элементов, то полученная последовательность является гамильтоновым путем в этом графе.
См. также
Литература
- Романовский, И.В. Дискретный Анализ - Санкт-Петербург 2003 стр. 39-41