Коды антигрея — различия между версиями
Martoon (обсуждение | вклад) м (→Доказательство корректности алгоритма) |
|||
| Строка 1: | Строка 1: | ||
| − | |||
| − | |||
{{Определение | {{Определение | ||
|definition= | |definition= | ||
Версия 13:35, 16 ноября 2013
| Определение: |
| Код антигрея (Anti-Gray Code) — такое упорядочивание -ичных векторов, что расстояние Хэмминга между двумя соседними векторами максимально. |
Код антигрея может использоваться для обнаружения неисправностей в устройстве при переходе в соседнее состояние. Часто используется в приборах, устанавливающихся на улице. Такое кодирование позволяет вовремя выявить поломку или какое-то загрязнение и своевременно устранить неисправность.
Содержание
Двоичный код антигрея
| Определение: |
| Двоичный код антигрея — такое упорядочивание двоичных векторов длины , что соседние отличаются не менее, чем в битах. |
Заметим, что для невозможно такое упорядочивание двоичных векторов, что соседние отличаются во всех битах. Объясняется это тем, что для двоичного вектора существует ровно один вектор, отличающийся во всех битах. А в последовательности их должно быть 2.
Пример
| n = 1 | n = 2 | n = 3 |
|---|---|---|
| 0 | 00 | 000 |
| 1 | 11 | 111 |
| 01 | 001 | |
| 10 | 110 | |
| 011 | ||
| 100 | ||
| 010 | ||
| 101 |
Алгоритм генерации
Возьмем двоичный зеркальный код Грея размером . Тогда для первых двоичных векторов будем:
- Печатать двоичный вектор
- Печатать его инверсию
Утверждается, что с помощью данного алгоритма мы напечатаем двоичный код антигрея.
Псевдокод
genBinAntiGray(n)
for i = 1 to 2^(n-1)
v = getMirrorGray(i, n)
print(v)
inverseBits(v)
print(v)
Доказательство корректности алгоритма
Обозначим за — -ый вектор в зеркальном коде Грея, — его инверсию. Тогда вектора будут располагаться в таком порядке:
...
...
- и отличаются во всех битах.
- Если и отличаются в -ом бите, то инверсия совпадает с только в -ом бите. То есть и отличаются во всех позициях, кроме -ой.
Троичный код антигрея
| Определение: |
| Троичный код антигрея — такое упорядочивание троичных векторов, что соседние отличаются во всех разрядах. |
В отличие от двоичного кода антигрея, здесь мы не сталкиваемся с проблемой однозначности "соседа" и можем привести такой код, соседние элементы которого будут отличаться во всех разрядах.
Пример
| n = 1 | n = 2 | n = 3 | ||
|---|---|---|---|---|
| 0 | 00 | 000 | 010 | 020 |
| 1 | 11 | 111 | 121 | 101 |
| 2 | 22 | 222 | 202 | 212 |
| 01 | 001 | 011 | 021 | |
| 12 | 112 | 122 | 102 | |
| 20 | 220 | 200 | 210 | |
| 02 | 002 | 012 | 022 | |
| 10 | 110 | 120 | 100 | |
| 21 | 221 | 201 | 211 | |
Алгоритм генерации
Упорядочим все троичные вектора лексикографически. Тогда для первых векторов будем выводить все его поразрядные циклические сдвиги.
Утверждается, что выполняя эти действия мы получим троичный код антигрея.
Псевдокод
genTernAntiGray(n)
for v = <000..0> to <022..2>
digitCircleShift(v)
while(v[0] != 0)
print(v)
digitCircleShift(v)
Заметим, что данный алгоритм можно обобщить на случай -ичного кода антигрея.
Доказательство корректности алгоритма
Обозначим -ый троичный вектор как , его первый и второй циклический сдвиги как и соответственно. Получаем вектора в следующем порядке:
...
...
- и , равно как и , отличаются во всех битах.
- Если говорить о векторах как о троичных числах, то получено из прибавлением единицы, это значит, что у несколько разрядов справа на единицу больше (по модулю ), чем у (по правилам сложения в столбик). С другой стороны получено из двумя циклическими сдвигами вперёд, что равносильно одному циклическому сдвигу назад. Таким образом, в числе некоторые биты такие же, как в , остальные на единицу больше; в числе все биты на один меньше по сравнению с , значит и различны во всех битах.
Подобные рассуждения можно провести для любого -ичного кода антигрея, где .