Перейти до основного вмісту

Код Грея

Код Грея — це двійкова система числення, у якій два сусідні значення відрізняються лише в одному біті.

Позначимо через G(n)G(n) представлення числа nn у коді Грея. Послідовність кодів Грея для 3-бітових чисел така: 000, 001, 011, 010, 110, 111, 101, 100, тож G(4)=(110)2=6G(4) = (110)_2 = 6. Наприклад, G(3)=(010)2G(3) = (010)_2 і G(4)=(110)2G(4) = (110)_2 відрізняються рівно в одному біті — найлівішому. Аналогічно, G(4)=110G(4) = 110 і G(5)=(111)2G(5) = (111)_2 відрізняються рівно в одному біті — найправішому. Це справджується для всіх послідовних чисел.

Цей код винайшов Frank Gray у 1953 році.

Знаходження коду Грея

Розгляньмо біти числа nn і біти числа G(n)G(n). Зауважимо, що ii-й біт G(n)G(n) дорівнює 1 лише тоді, коли ii-й біт числа nn дорівнює 1, а i+1i + 1-й біт дорівнює 0, або навпаки (ii-й біт дорівнює 0, а i+1i + 1-й біт дорівнює 1). Отже, G(n)=n(n>>1)G(n) = n \oplus (n >> 1):

int g (int n) {
return n ^ (n >> 1);
}

Знаходження оберненого коду Грея

Маючи код Грея gg, відновимо початкове число nn.

Рухатимемося від старших бітів до молодших (молодший біт має індекс 1, а старший біт — індекс kk). Зв'язок між бітами nin_i числа nn і бітами gig_i числа gg:

nk=gk,nk1=gk1nk=gkgk1,nk2=gk2nk1=gkgk1gk2,nk3=gk3nk2=gkgk1gk2gk3,\begin{align} n_k &= g_k, \\ n_{k-1} &= g_{k-1} \oplus n_k = g_k \oplus g_{k-1}, \\ n_{k-2} &= g_{k-2} \oplus n_{k-1} = g_k \oplus g_{k-1} \oplus g_{k-2}, \\ n_{k-3} &= g_{k-3} \oplus n_{k-2} = g_k \oplus g_{k-1} \oplus g_{k-2} \oplus g_{k-3}, \vdots \end{align}

Найпростіше це записати в коді так:

int rev_g (int g) {
int n = 0;
for (; g; g >>= 1)
n ^= g;
return n;
}

Практичні застосування

Коди Грея мають кілька корисних застосувань, інколи доволі несподіваних:

  • Код Грея з nn бітів утворює гамільтонів цикл на гіперкубі, де кожен біт відповідає одному виміру.

  • Коди Грея використовують для мінімізації помилок під час цифро-аналогового перетворення сигналів (наприклад, у сенсорах).

  • Код Грея можна застосувати для розв'язання задачі про Ханойські вежі. Нехай nn позначає кількість дисків. Почнемо з коду Грея довжини nn, який складається з самих нулів (G(0)G(0)), і рухаймося між послідовними кодами Грея (від G(i)G(i) до G(i+1)G(i+1)). Нехай ii-й біт поточного коду Грея відповідає nn-му диску (молодший біт відповідає найменшому диску, а старший біт — найбільшому). Оскільки на кожному кроці змінюється рівно один біт, ми можемо трактувати зміну ii-го біта як переміщення ii-го диска. Зауважимо, що для кожного диска (крім найменшого) на кожному кроці (крім початкової та кінцевої позицій) існує рівно один варіант переміщення. Для найменшого диска завжди є два варіанти переміщення, але існує стратегія, яка завжди приводить до відповіді: якщо nn непарне, то послідовність переміщень найменшого диска має вигляд ftrftr...f \to t \to r \to f \to t \to r \to ... (де ff — початковий стрижень, tt — кінцевий стрижень, а rr — стрижень, що залишився), а якщо nn парне: frtfrt...f \to r \to t \to f \to r \to t \to ....

  • Коди Грея також використовують у теорії генетичних алгоритмів.

Задачі для практики

Відеоматеріали