Коды Грея для перестановок — различия между версиями
м (→Псевдокод получения Грея) |
(→Построение кода Грея для перестановок) |
||
Строка 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