Монотонный код Грея
| Определение: |
| Монотонный код Грея (англ. Monotonic Gray Code) — способ построения кода Грея, при котором , что содержит на или больше единиц, чем . |
Монотонный код Грея преимущественно используется в теории связанных сетей, например для минимизации ожидания линейным массивом процессоров.[1]
Содержание
Алгоритм построения
Для начала определим такое понятие, как вес двоичного кода, им будет являтся количество в данном двоичном коде. Очевидно, что нельзя построить код Грея в котором бы вес всегда возрастал. Неплохим решением этой проблемы будет обход всех кодов со смежными с данным весами.
Мы можем формализовать модель монотонных кодов Грея рассматривая разбиение гиперкуба , вершины в котором являются двоичными кодами, на уровни с одинаковым весом вершин.
для . Для всех уровней выполняется соотношение .
Пусть подграф , который является объединением двух смежных уровней, т. е. , и пусть множество граней . Тогда монотонным кодом Грея будет являтся Гамильтонов путь в , при котором любое множество вершин такие, что , то идет перед .
Ниже на катринке Гамильтонов путь в гиперкубе для , построенный по алгоритму Саважа-Винклера (англ. Savage-Winkler).[2]
Элегантная идея построения -ичного монотонного кода Грея состоит в том, чтобы рекурсивно строить подпути длинны включающих вершины .
Определим и , когда или и . То есть это объединение множеств с приписанной в начале 1 и с приписанным в начале нулем.
Здесь это определенная перестановка элементов множества к которому она применена, а это путь к котрому была применена пересатновка . Существует два варианта построить монотонный код грея по путям .
Назовем их и . Будем строить их таким образом:
Выбор перестановки обусловлен тем, чтобы получившиеся коды соответсвовали требованиям кода Грея и поэтому эта перестановка равна .
Чтобы лучше разобратся в том, как сторится этот код и работает перестановка следует рассмотреть таблицу ниже.
Монотонный код Грея может быть эффективно сгенерирован по этому алгоритму за время . Легче всего написать этот алгоритм используя сопрограмму.
Псевдокод
|
rotateRight(x, n): // Вспомогательная функция для генерации перестановки, циклически сдвигает битовый вектор направо раз. Принимает и возвращает котреж (англ. tuple). Кортеж аналог списка, но в кортеже нельзя менять элементы, можно только добавлять. return x[-n:] + x[:-n] pi(n): // Рекурсивная генерация -ой перестановки. Возвращает перестановку в виде кортежа. Если n становится меньше дописывает в начало кортежа и возвращает его. if n <= 1: return (0,) x = pi(n - 1) + (n - 1,) return rotate_right(tuple(x[k] for k in x), 1) p(n, j, reverse = false): // Рекурсивная генерация пути . Принимает , а так же дополнительный параметр определяющий надо-ли переворачивать кортеж. if n == 1 and j == 0: if not reverse: yield (0,) yield (1,) else: yield (1,) yield (0,) elif j >= 0 and j < n: perm = pi(n - 1) if not reverse: for x in p(n - 1, j - 1): yield (1,) + tuple(x[k] for k in perm) for x in p(n - 1, j): yield (0,) + x else: for x in p(n - 1, j, reverse=True): yield (0,) + x for x in p(n - 1, j - 1, reverse=True): yield (1,) + tuple(x[k] for k in perm) monotonic(n): // Генерация монотонного кода Грея при помощи уже написанной сопрограммы p. for i in range(n): for x in (p(n, i) if i % 2 == 0 else p(n, i, reverse=True)): yield x
|
Визуализация работы алгоритма
Для
Для


