UNIVERSIDAD POLITÉCNICA DE PACHUCA ALGORITMO DE COMPRESIÓN DE HUFFMAN En 1952, David Huffman propuso un método estadístico que permitía asignar un código binario a los diversos símbolos a comprimir (píxeles o caracteres, por ejemplo). La longitud de cada código no es idéntica para todos los símbolos: se asignan códigos cortos a los símbolos utilizados con más frecuencia (los que aparecen más a menudo), mientras que los símbolos menos frecuentes reciben códigos binarios más largos. La expresión Código de Longitud Variable (VLC) se utiliza para indicar este tipo de código porque ningún código es el prefijo de otro. De este modo, la sucesión final de códigos con longitudes variables será en promedio más pequeña que la obtenida con códigos de longitudes constantes. El codificador Huffman crea una estructura arbórea ordenada con todos los símbolos y la frecuencia con que aparecen. Las ramas se construyen en forma recursiva comenzando con los símbolos menos frecuentes. La construcción del árbol se realiza ordenando en primer lugar los símbolos según la frecuencia de aparición. Los dos símbolos con menor frecuencia de aparición se eliminan sucesivamente de la lista y se conectan a un nodo cuyo peso es igual a la suma de la frecuencia de los dos símbolos. El símbolo con menor peso es asignado a la rama 1, el otro a la rama 0 y así sucesivamente, considerando cada nodo formado como un símbolo nuevo, hasta que se obtiene un nodo principal llamado raíz. El código de cada símbolo corresponde a la sucesión de códigos en el camino, comenzando desde este carácter hasta la raíz. De esta manera, cuanto más dentro del árbol esté el símbolo, más largo será el código. Se trata de un algoritmo que puede ser usado para compresión o encriptación de datos. Esta compresión es mayor cuando la variedad de caracteres diferentes que aparecen es menor. Por ejemplo: si el texto se compone únicamente de números o mayúsculas, se conseguirá una compresión mayor. Para recuperar el fichero original es necesario conocer el código asignado a cada carácter, así como su longitud en bits, si ésta información se omite, y el receptor del fichero la conoce, podrá recuperar la información original. De este modo es posible utilizar el algoritmo para encriptar ficheros. Mecanismo del algoritmo: • • • • Contar cuantas veces aparece cada carácter en el fichero a comprimir. Y crear una lista enlazada con la información de caracteres y frecuencias. Ordenar la lista de menor a mayor en función de la frecuencia. Convertir cada elemento de la lista en un árbol. Fusionar todos estos árboles en uno único, para hacerlo se sigue el siguiente proceso, mientras la lista de árboles contenga más de un elemento: o Con los dos primeros árboles formar un nuevo árbol, cada uno de los árboles originales en una rama. o Sumar las frecuencias de cada rama en el nuevo elemento árbol. MAESTRÍA EN TIC´S MFGP Página 1 UNIVERSIDAD POLITÉCNICA DE PACHUCA Insertar el nuevo árbol en el lugar adecuado de la lista según la suma de frecuencias obtenida. Para asignar el nuevo código binario de cada carácter sólo hay que seguir el camino adecuado a través del árbol. Si se toma una rama cero, se añade un cero al código, si se toma una rama uno, se añade un uno. Se recodifica el fichero según los nuevos códigos. o • • EJEMPLO La tabla describe el alfabeto a codificar, junto con las frecuencias de sus símbolos. En el gráfico se muestra el árbol construido a partir de este alfabeto siguiendo el algoritmo descrito. Símbolo Frecuencia A 0,15 B 0,30 C 0,20 D 0,05 E 0,15 F 0,05 G 0,10 Se puede ver con facilidad cuál es el código del símbolo E: subiendo por el árbol se recorren ramas etiquetadas con 1, 1 y 0; por lo tanto, el código es 011. Para obtener el código de D se recorren las ramas 0, 1, 1 y 1, por lo que el código es 1110. La operación inversa también es fácil de realizar: dado el código 10 se recorren desde la raíz las ramas 1 y 0, obteniéndose el símbolo C. Para descodificar 010 se recorren las ramas 0, 1 y 0, obteniéndose el símbolo A. Limitaciones Para poder utilizar el algoritmo de Huffman es necesario conocer de antemano las frecuencias de aparición de cada símbolo, y su eficiencia depende de lo próximas a las frecuencias reales que sean las estimadas. Algunas implementaciones del algoritmo de Huffman son adaptativas, actualizando las frecuencias de cada símbolo conforme recorre el texto. La eficiencia de la codificación de Huffman también depende del balance que exista entre los hijos de cada nodo del árbol, siendo más eficiente conforme menor sea la diferencia de frecuencias entre los dos hijos de cada nodo. MAESTRÍA EN TIC´S MFGP Página 2 UNIVERSIDAD POLITÉCNICA DE PACHUCA Ejemplos: • • La codificación binaria es un caso particular de la codificación de Huffman que ocurre cuando todos los símbolos del alfabeto tienen la misma frecuencia. Se tiene pues que la codificación binaria es la más eficiente para cualquier número de símbolos equiprobables. El algoritmo de Huffman aplicado sobre un alfabeto de dos símbolos asignará siempre un 1 al primero y un 0 al segundo, independientemente de la frecuencia de aparición de dichos símbolos. En este caso nunca se realiza compresión de los datos, mientras que otros algoritmos sí podrían conseguirlo. Una manera de resolver este problema consiste en agrupar los símbolos en palabras antes de ejecutar el algoritmo. Por ejemplo, si se tiene la cadena de longitud 64 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB El algoritmo de Huffman aplicado únicamente a los símbolos devuelve el código: 1111111111111111111111111111111111111111111111111111111111111110 También de longitud 64. Sin embargo, si antes de utilizar el algoritmo, se agrupan los símbolos en las palabras "AA", "AB" y "B" (que se codifican como 1, 01 y 00), el algoritmo devuelve la siguiente cadena: 111111111111111111111111111111101; que tiene longitud 32, la mitad que si no se hubiera agrupado. Si observa el árbol de Huffman, se puede comprobar que la diferencia de frecuencias entre las ramas del árbol es menor que en el caso anterior. MAESTRÍA EN TIC´S MFGP Página 3