Код Грея — одна із систем кодування інформації, в якій два послідовні коди відрізняються значенням лише одного біта.
Загальні відомості
Для кодування ознак можна скористатись найпростішим варіантом: двійковим значенням цієї ознаки. Тоді легко використовувати бітові рядки фіксованої довжини для подання всіх можливих значень цієї ознаки.
Наприклад, десяткові числа 7 і 8 можна легко закодувати у двійкові числа B(7)=011 і B(8)=100, використовуючи двійкову техніку. Проте, якщо ми хочемо переміститися з фенотипу 7 у фенотип 8, то повинні змінити всі три біти в їх зображенні від B(7)=011 до B(8)=100. Інакше кажучи, при роботі ГА необхідні три окремі дії для переміщення від розв'язку 7 до розв'язку 8, які призведуть до додаткових витрат часу. З іншого боку, якщо ми хочемо переміститися від розв'язку 7 до розв'язку 8, то нам необхідна лише одна операція. Це ускладнює використання ГА й погіршує його збіжність.
Щоб уникнути цього, краще використовувати кодування, в якому значення розрізняються на один біт. Таким є код Грея. Розглянемо принцип його побудови:
Десятковий Код Грея
0 0000
1 0001
нульовий розряд вичерпав свої ресурси (0,1)
ставиться «дзеркало» і від нього «відображаються» значення 0-го
розряду, але з одиницею в старшому розряді.
2 0011
3 0010
Так само і з рештою розрядів.
4 0110
5 0111
6 0101
7 0100
8 1100
9 1101
Використання
Використання кодів Грея засновано насамперед на тому, що він мінімізує ефект помилок при перетворенні аналогових сигналів у цифрові (наприклад, у багатьох видах датчиків).
Коди Грея часто застосовуються в датчиках-енкодерах. Їх використання зручно тим, що два сусідніх значення шкали сигналу відрізняються лише в одному розряді. Також вони використовуються для кодування номера доріжок в твердих дисках.
Код Грея можна використовувати також і для вирішення задачі про Ханойські вежі. Широко застосовуються коди Грея і в теорії генетичних алгоритмів для кодування генетичних ознак, які представлені цілими числами. Код Грея використовується для генерації сполучень методом обертових дверей.
Алгоритми перетворення
Перетворення двійкового коду в код Грея
Коди Грея легко виходять з двійкових чисел шляхом побітової операції «виключне АБО» з тим же числом, зрушеним вправо на один біт. Отже, i-й біт коду Грея Gi виражається через біти двійкового коду Bi наступним чином:
де — операція «виключне АБО»; біти нумеруються справа наліво, починаючи з молодшого. Нижче наведено алгоритм перетворення з двійкової системи числення в код Грея, записаний на мові C (мова програмування):
unsigned int grayencode(unsigned int g) { return g ^ (g >> 1); }
Той же алгоритм, записаний на мові Pascal:
function BinToGray(b:integer):integer; begin BinToGray:=b xor (b shr 1) end;
Приклад: перетворити двійкове число 10110 в код Грея.
10110 01011 ----- 11101
Перетворення коду Грея в двійковий код
Зворотний алгоритм — перетворення коду Грея в двійковий код — можна виразити рекурентною формулою
причому перетворення здійснюється побітно, починаючи зі старших розрядів, і значення Bi + 1, використовуване у формулі, обчислюється на попередньому кроці алгоритму. Дійсно, якщо підставити в цю формулу вищенаведений вираз для i-го біта коду Грея, отримаємо
Однак наведений алгоритм, пов'язаний з маніпуляцією окремими бітами, незручний для програмної реалізації, тому на практиці використовують видозмінений алгоритм:
де N — кількість бітів в коді Грея (для збільшення швидкодії алгоритму за N можна взяти номер старшого ненульового біта коду Грея); знак означає підсумовування за допомогою операції «виключне АБО», тобто
Дійсно, підставивши в формулу вираз для i-го біта коду Грея, отримаємо
Тут передбачається, що біт, що виходить за рамки розрядної сітки (), дорівнює нулю. Нижче приведена функція на мові С, що реалізує даний алгоритм. Вона здійснює послідовний зсув вправо і підсумовування вихідного двійкового числа, до тих пір, поки черговий зсув не обнулить доданок.
unsigned int graydecode(unsigned int gray) { unsigned int bin; for (bin = 0; gray; gray >>= 1) { bin ^= gray; } return bin; }
Той же самий алгоритм, записаний на мові Паскаль:
function GrayToBin(b:integer):integer; var g:integer; begin g:=0; while b>0 do begin g:=g xor b; b:=b shr 1; end; GrayToBin:=g; end;
Приклад: перетворити код Грея 11101 в двійковий код.
11101 01110 00111 00011 00001 ----- 10110
Швидке перетворення 8/16/24/32-разрядного значення коду Грея в двійковий код на мові BlitzBasic:
Function GRAY_2_BIN%(X%) Return X Xor ((X And $88888888) Shr 4) Xor ((X And $CCCCCCCC) Shr 2) Xor ((X And $EEEEEEEE) Shr 1) End Function
Генерація кода Грея
Код Грея для n біт може бути рекурсивно побудований на основі коду для n-1 біт шляхом перевертання списку біт (тобто записуванням кодів у зворотному порядку), конкатенації вихідного і перевернутого списків, дописування нулів на початку кожного коду у вихідному списку та одиниць — у початок кодів в перевернутому списку. Так, для генерації списку для n = 3 біт на підставі кодів для двох біт необхідно виконати наступні кроки:
Коди для n = 2 біт: | 00, 01, 11, 10 | |
Перевернутий список кодів: | 10, 11, 01, 00 | |
Об'єднаний список: | 00, 01, 11, 10 | 10, 11, 01, 00 |
До початкового списку дописані нулі: | 000, 001, 011, 010 | 10, 11, 01, 00 |
До перевернутого списку дописані одиниці: | 000, 001, 011, 010 | 110, 111, 101, 100 |
Нижче представлений один з алгоритмів створення послідовності коду Грея заданої глибини, записаний на мові Perl:
my $depth = 16; # generate 16 Gray codes, 4 bits wide each my @gray_codes = ( '0', '1' ); while(scalar(@gray_codes)<$depth) { my @forward_half=map{'0'.$_} @gray_codes; my @reverse_half=map{'1'.$_} reverse(@gray_codes); @gray_codes=(@forward_half,@reverse_half); }
Рекурсивна функція побудова коду Грея мовою C:
//n -- довжина що потрібна, //m -- показник на масив // всі коди довжиною менші за n //depth -- параметр рекурсії int gray (int n, int* m, int depth) { int i, t = (1 << (depth - 1)); if (depth == 0) m[0] = 0; else { //масив зберігає десяткові записи двійкових слів for (i = 0; i < t; i++) m[t + i] = m[t - i - 1] + (1 << (depth - 1)); } if (depth != n) gray(n, m, depth + 1); return 0; }
Швидке перетворення 8/16/24/32-разрядного бінарного коду в код Грея мовою BlitzBasic:
Function BIN_2_GRAY%(X%) Return X Xor ((X And $EEEEEEEE) Shr 1) End Function
Таблиця відповідності між двійковим кодом та кодом Грея
Ціле | Двійковий код | Код Грея |
---|---|---|
0 | 0000 | 0000 |
1 | 0001 | 0001 |
2 | 0010 | 0011 |
3 | 0011 | 0010 |
4 | 0100 | 0110 |
5 | 0101 | 0111 |
6 | 0110 | 0101 |
7 | 0111 | 0100 |
8 | 1000 | 1100 |
9 | 1001 | 1101 |
10 | 1010 | 1111 |
11 | 1011 | 1110 |
12 | 1100 | 1010 |
13 | 1101 | 1011 |
14 | 1110 | 1001 |
15 | 1111 | 1000 |
Див. також
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Kod Greya odna iz sistem koduvannya informaciyi v yakij dva poslidovni kodi vidriznyayutsya znachennyam lishe odnogo bita Fragment storinki patenta GreyaZagalni vidomostiDlya koduvannya oznak mozhna skoristatis najprostishim variantom dvijkovim znachennyam ciyeyi oznaki Todi legko vikoristovuvati bitovi ryadki fiksovanoyi dovzhini dlya podannya vsih mozhlivih znachen ciyeyi oznaki Napriklad desyatkovi chisla 7 i 8 mozhna legko zakoduvati u dvijkovi chisla B 7 011 i B 8 100 vikoristovuyuchi dvijkovu tehniku Prote yaksho mi hochemo peremistitisya z fenotipu 7 u fenotip 8 to povinni zminiti vsi tri biti v yih zobrazhenni vid B 7 011 do B 8 100 Inakshe kazhuchi pri roboti GA neobhidni tri okremi diyi dlya peremishennya vid rozv yazku 7 do rozv yazku 8 yaki prizvedut do dodatkovih vitrat chasu Z inshogo boku yaksho mi hochemo peremistitisya vid rozv yazku 7 do rozv yazku 8 to nam neobhidna lishe odna operaciya Ce uskladnyuye vikoristannya GA j pogirshuye jogo zbizhnist Shob uniknuti cogo krashe vikoristovuvati koduvannya v yakomu znachennya rozriznyayutsya na odin bit Takim ye kod Greya Rozglyanemo princip jogo pobudovi Desyatkovij Kod Greya 0 0000 1 0001 nulovij rozryad vicherpav svoyi resursi 0 1 stavitsya dzerkalo i vid nogo vidobrazhayutsya znachennya 0 go rozryadu ale z odiniceyu v starshomu rozryadi 2 0011 3 0010 Tak samo i z reshtoyu rozryadiv 4 0110 5 0111 6 0101 7 0100 8 1100 9 1101VikoristannyaKrugovij enkoder z tribitnim kodom Greya Vikoristannya kodiv Greya zasnovano nasampered na tomu sho vin minimizuye efekt pomilok pri peretvorenni analogovih signaliv u cifrovi napriklad u bagatoh vidah datchikiv Kodi Greya chasto zastosovuyutsya v datchikah enkoderah Yih vikoristannya zruchno tim sho dva susidnih znachennya shkali signalu vidriznyayutsya lishe v odnomu rozryadi Takozh voni vikoristovuyutsya dlya koduvannya nomera dorizhok v tverdih diskah Kod Greya mozhna vikoristovuvati takozh i dlya virishennya zadachi pro Hanojski vezhi Shiroko zastosovuyutsya kodi Greya i v teoriyi genetichnih algoritmiv dlya koduvannya genetichnih oznak yaki predstavleni cilimi chislami Kod Greya vikoristovuyetsya dlya generaciyi spoluchen metodom obertovih dverej Algoritmi peretvorennyaPeretvorennya dvijkovogo kodu v kod Greya Kodi Greya legko vihodyat z dvijkovih chisel shlyahom pobitovoyi operaciyi viklyuchne ABO z tim zhe chislom zrushenim vpravo na odin bit Otzhe i j bit kodu Greya Gi virazhayetsya cherez biti dvijkovogo kodu Bi nastupnim chinom G i B i B i 1 displaystyle G i B i oplus B i 1 de displaystyle oplus operaciya viklyuchne ABO biti numeruyutsya sprava nalivo pochinayuchi z molodshogo Nizhche navedeno algoritm peretvorennya z dvijkovoyi sistemi chislennya v kod Greya zapisanij na movi C mova programuvannya unsigned int grayencode unsigned int g return g g gt gt 1 Toj zhe algoritm zapisanij na movi Pascal function BinToGray b integer integer begin BinToGray b xor b shr 1 end Priklad peretvoriti dvijkove chislo 10110 v kod Greya 10110 01011 11101 Peretvorennya kodu Greya v dvijkovij kod Zvorotnij algoritm peretvorennya kodu Greya v dvijkovij kod mozhna viraziti rekurentnoyu formuloyu B i B i 1 G i displaystyle B i B i 1 oplus G i prichomu peretvorennya zdijsnyuyetsya pobitno pochinayuchi zi starshih rozryadiv i znachennya Bi 1 vikoristovuvane u formuli obchislyuyetsya na poperednomu kroci algoritmu Dijsno yaksho pidstaviti v cyu formulu vishenavedenij viraz dlya i go bita kodu Greya otrimayemo B i B i 1 G i B i 1 B i B i 1 B i B i 1 B i 1 B i 0 B i displaystyle B i B i 1 oplus G i B i 1 oplus B i oplus B i 1 B i oplus B i 1 oplus B i 1 B i oplus 0 B i Odnak navedenij algoritm pov yazanij z manipulyaciyeyu okremimi bitami nezruchnij dlya programnoyi realizaciyi tomu na praktici vikoristovuyut vidozminenij algoritm B k i k N G i displaystyle B k bigoplus limits i k N G i de N kilkist bitiv v kodi Greya dlya zbilshennya shvidkodiyi algoritmu za N mozhna vzyati nomer starshogo nenulovogo bita kodu Greya znak displaystyle oplus oznachaye pidsumovuvannya za dopomogoyu operaciyi viklyuchne ABO tobto i k N G i G k G k 1 G N 1 G N displaystyle bigoplus limits i k N G i G k oplus G k 1 oplus oplus G N 1 oplus G N Dijsno pidstavivshi v formulu viraz dlya i go bita kodu Greya otrimayemo B k i k N G i i k N B i B i 1 B k B k 1 B k 1 B k 2 B N 1 B N B N B N 1 displaystyle B k bigoplus limits i k N G i bigoplus limits i k N B i oplus B i 1 B k oplus B k 1 oplus B k 1 oplus B k 2 oplus oplus B N 1 oplus B N oplus B N oplus B N 1 B k B k 1 B k 1 B N B N B N 1 B k B N 1 B k displaystyle B k oplus B k 1 oplus B k 1 oplus oplus B N oplus B N oplus B N 1 B k oplus B N 1 B k Tut peredbachayetsya sho bit sho vihodit za ramki rozryadnoyi sitki B N 1 displaystyle B N 1 dorivnyuye nulyu Nizhche privedena funkciya na movi S sho realizuye danij algoritm Vona zdijsnyuye poslidovnij zsuv vpravo i pidsumovuvannya vihidnogo dvijkovogo chisla do tih pir poki chergovij zsuv ne obnulit dodanok unsigned int graydecode unsigned int gray unsigned int bin for bin 0 gray gray gt gt 1 bin gray return bin Toj zhe samij algoritm zapisanij na movi Paskal function GrayToBin b integer integer var g integer begin g 0 while b gt 0 do begin g g xor b b b shr 1 end GrayToBin g end Priklad peretvoriti kod Greya 11101 v dvijkovij kod 11101 01110 00111 00011 00001 10110 Shvidke peretvorennya 8 16 24 32 razryadnogo znachennya kodu Greya v dvijkovij kod na movi BlitzBasic Function GRAY 2 BIN X Return X Xor X And 88888888 Shr 4 Xor X And CCCCCCCC Shr 2 Xor X And EEEEEEEE Shr 1 End Function Generaciya koda Greya Kod Greya dlya n bit mozhe buti rekursivno pobudovanij na osnovi kodu dlya n 1 bit shlyahom perevertannya spisku bit tobto zapisuvannyam kodiv u zvorotnomu poryadku konkatenaciyi vihidnogo i perevernutogo spiskiv dopisuvannya nuliv na pochatku kozhnogo kodu u vihidnomu spisku ta odinic u pochatok kodiv v perevernutomu spisku Tak dlya generaciyi spisku dlya n 3 bit na pidstavi kodiv dlya dvoh bit neobhidno vikonati nastupni kroki Kodi dlya n 2 bit 00 01 11 10 Perevernutij spisok kodiv 10 11 01 00 Ob yednanij spisok 00 01 11 10 10 11 01 00 Do pochatkovogo spisku dopisani nuli 000 001 011 010 10 11 01 00 Do perevernutogo spisku dopisani odinici 000 001 011 010 110 111 101 100 Nizhche predstavlenij odin z algoritmiv stvorennya poslidovnosti kodu Greya zadanoyi glibini zapisanij na movi Perl my depth 16 generate 16 Gray codes 4 bits wide each my gray codes 0 1 while scalar gray codes lt depth my forward half map 0 gray codes my reverse half map 1 reverse gray codes gray codes forward half reverse half Rekursivna funkciya pobudova kodu Greya movoyu C n dovzhina sho potribna m pokaznik na masiv vsi kodi dovzhinoyu menshi za n depth parametr rekursiyi int gray int n int m int depth int i t 1 lt lt depth 1 if depth 0 m 0 0 else masiv zberigaye desyatkovi zapisi dvijkovih sliv for i 0 i lt t i m t i m t i 1 1 lt lt depth 1 if depth n gray n m depth 1 return 0 Shvidke peretvorennya 8 16 24 32 razryadnogo binarnogo kodu v kod Greya movoyu BlitzBasic Function BIN 2 GRAY X Return X Xor X And EEEEEEEE Shr 1 End FunctionTablicya vidpovidnosti mizh dvijkovim kodom ta kodom GreyaCile Dvijkovij kod Kod Greya 0 0000 0000 1 0001 0001 2 0010 0011 3 0011 0010 4 0100 0110 5 0101 0111 6 0110 0101 7 0111 0100 8 1000 1100 9 1001 1101 10 1010 1111 11 1011 1110 12 1100 1010 13 1101 1011 14 1110 1001 15 1111 1000Div takozhKodi Hemminga Kod Dzhonsona