Skip to Content

Código Gray

El código Gray es un sistema de numeración binario donde dos valores sucesivos difieren en un solo bit.

Denotemos por G(n)G(n) la representación del número nn usando el código Gray. La secuencia de códigos Gray para números de 3 bits es: 000, 001, 011, 010, 110, 111, 101, 100, así que G(4)=(110)2=6G(4) = (110)_2 = 6. Por ejemplo, G(3)=(010)2G(3) = (010)_2 y G(4)=(110)2G(4) = (110)_2 difieren en exactamente un bit, el bit más a la izquierda. De forma similar, G(4)=110G(4) = 110 y G(5)=(111)2G(5) = (111)_2 difieren en exactamente un bit, el más a la derecha. Esto vale para todos los números sucesivos.

Este código lo inventó Frank Gray en 1953.

Encontrar el código Gray

Miremos los bits del número nn y los bits del número G(n)G(n). Nótese que el ii-ésimo bit de G(n)G(n) vale 1 solo cuando el ii-ésimo bit de nn vale 1 y el bit i+1i + 1 vale 0, o al revés (el ii-ésimo bit vale 0 y el bit i+1i + 1 vale 1). Así, G(n)=n(n>>1)G(n) = n \oplus (n >> 1):

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

Encontrar el código Gray inverso

Dado el código Gray gg, restaurar el número original nn.

Nos moveremos de los bits más significativos a los menos significativos (el bit menos significativo tiene índice 1 y el más significativo tiene índice kk). La relación entre los bits nin_i del número nn y los bits gig_i del número gg:

nk=gk,nk1=gk1nk=gkgk1,nk2=gk2nk1=gkgk1gk2,nk3=gk3nk2=gkgk1gk2gk3,nkamp;=gk,nk1amp;=gk1nk=gkgk1,nk2amp;=gk2nk1=gkgk1gk2,nk3amp;=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}

La forma más fácil de escribirlo en código es:

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

Aplicaciones prácticas

Los códigos Gray tienen algunas aplicaciones útiles, a veces bastante inesperadas:

  • El código Gray de nn bits forma un ciclo hamiltoniano en un hipercubo, donde cada bit corresponde a una dimensión.

  • Los códigos Gray se usan para minimizar los errores en la conversión de señales digital-analógica (por ejemplo, en sensores).

  • El código Gray se puede usar para resolver el problema de las Torres de Hanoi. Sea nn la cantidad de discos. Empezar con el código Gray de longitud nn que consiste de todos ceros (G(0)G(0)) y moverse entre códigos Gray consecutivos (de G(i)G(i) a G(i+1)G(i+1)). Sea el ii-ésimo bit del código Gray actual el que representa el nn-ésimo disco (el bit menos significativo corresponde al disco más chico y el más significativo al disco más grande). Como exactamente un bit cambia en cada paso, podemos tratar el cambio del ii-ésimo bit como mover el ii-ésimo disco. Nótese que hay exactamente una opción de movimiento para cada disco (excepto el más chico) en cada paso (excepto las posiciones de inicio y fin). Siempre hay dos opciones de movimiento para el disco más chico, pero hay una estrategia que siempre lleva a la respuesta: si nn es impar, la secuencia de movimientos del disco más chico se ve como ftrftr...f \to t \to r \to f \to t \to r \to … donde ff es la varilla inicial, tt es la varilla terminal y rr es la varilla restante, y si nn es par: frtfrt...f \to r \to t \to f \to r \to t \to ….

  • Los códigos Gray también se usan en la teoría de algoritmos genéticos.

Problemas de práctica