Vous êtes sur la page 1sur 4

Codage de Human

Alexandre Brabant source : Serge Bays

1 Introduction
1.1 Objectif
Ce TP a pour but de proposer une application de la notion d'arbre binaire au codage de Human.
Il s'agit de construire un arbre de Human (à partir des eectifs de chacun des caractères présents dans
la chaîne à coder) et de l'utiliser ensuite pour coder et décoder la chaîne de caractères en question.

1.2 Prérequis
 Programmation en langage python : bases + tuples et dictionnaires
 Récursivité : écrire un programme récursif ; analyser le fonctionnement d'un programme récursif.
 Programmation objet : classes, attributs, méthodes. Être capable d'utiliser une classe en tant
que structure de données d'un programme.
 Arbres binaires : noeuds, racines, feuilles, sous-arbres gauches, sous-arbres droits.

1.3 Qu'est-ce que le codage de Human ?


Le codage de Human est un algorithme de compression de données sans perte qui utilise un code à
longueur variable pour représenter un symbole de la source (par exemple un caractère dans un chier).
Le code est déterminé à partir d'une estimation des probabilités d'apparition des symboles de source,
un code court étant associé aux symboles de source les plus fréquents.
Le codage de Human a été inventé par David Albert Human, lors de sa thèse de doctorat au MIT
(Massachusetts Institute of Technology) en 1952.
Les premiers Macintosh de la société Apple utilisaient un code inspiré de Human pour la représenta-
tion des textes à une époque où la mémoire vive restait encore un composant coûteux.
Le codage de Human est utilisé dans presque toutes les applications qui impliquent la compression et
la transmission de données numériques comme les modems, les réseaux informatiques et la télévision
à haute dénition. source Wikipedia

1
2 Principe du codage de Human
Le principe du codage de Human est le suivant : plutôt que de coder chaque caractère sur 8 bits
(codage ASCII étendu), on utilise moins de bits pour les caractères les plus fréquents et plus de bits
pour les caractères les moins fréquents.

2.1 Exemple
Considérons par exemple un message ne contenant que quatre caractères diérents avec les eectifs
suivants : (A,4), (B,1), (C,3) et (D,2).
Nous commençons par le caractère le plus fréquent et codons donc le A par 0.
Nous ne pouvons pas coder un autre caractère, par exemple le C avec le seul 1 ou avec 01. En eet
une suite débutant par 01 est alors ambigüe : est-ce une chaîne qui commence par AC ou par A suivi
d'un autre caractère dont le codage commence par 1 ? Nous codons donc le C par 10.
On en déduit que le codage d'un caractère ne doit pas être le préxe du codage d'un autre caractère.
Donc après le codage du A et du C, le codage des deux autres caractères doit commencer par 11. Nous
choisissons 110 pour le B et 111 pour le D.
Finalement le codage est le suivant : (A,0), (B,110), C(10) et D(111).

Considérons une suite quelconque, par exemple 1110101010000110 et vérions que le système de codage
ne génère aucune ambiguïté possible. La seule possibilité est la séparation : 111 0 10 10 10 0 0 0 110.
Le message est donc D A C C C A A A B.

Pour ce message de 9 caractères, codé sur 16 bits contre 9 × 8 = 72 bits avec le codage ASCII, le gain
72
est considérable. Le quotient = 4, 5 est appelé le taux de compression.
16
Cependant, avec seulement quatre caractères, on aurait pu envisager de les coder chacun sur 2 bits, soit
00, 01, 10 et 11. Dans ce cas le total serait de 9 × 2 = 18 bits pour le message. Le taux de compression
18
= 1, 125 est tout de même supérieur à 1.
16

2.2 Arbre de Human


Nous avons procédé sur un exemple en choisissant un codage pour le caractère le plus fréquent, puis
le caractère suivant dans l'ordre des eectifs décroissants.
En pratique, on construit un arbre en suivant le chemin inverse. Chaque caractère représente une
feuille. On part des deux caractères les moins fréquents que l'on fusionne pour obtenir un noeud. A
chaque étape, on procède à une fusion. Voici ce qu'on obtient, en trois étapes, avec l'exemple :

3 6 10

B :1 D :2 C :3 3 A :4 6

B :1 D :2 C :3 3

B :1 D :2

2
3 Mise en pratique
Vous allez écrire un programme Python qui génère l'arbre de Human d'un message donné en entrée.
Voici le déroulement possible :
 une étude statistique du message conduit à l'établissement de l' alphabet pondéré  du message.
 génération de l'arbre de Human correspondant à l'alphabet pondéré.
 parcours de l'arbre pour éditer le code binaire de l'alphabet.
 codage du message

3.1 Structures de données


 une chaîne de caractère contenant le message à coder ;
 deux listes alphabet et effectifs de mêmes longueurs contenant respectivement les caractères
(distincts) présents dans le message et leurs eectifs dans le message ;
 la classe Noeud (voir cours sur les arbres binaires) ;
 une liste lstNoeuds pour stocker les noeuds/feuilles créés au fur et à mesure du processus.

3.2 Création de l'arbre


3.2.1 fabrication des feuilles

Tout d'abord il faut remplir la liste lstNoeuds avec autant de feuilles qu'il y a de caractères dans la
liste alphabet. Pour une feuille donnée, sa valeur est le couple (caractère,eectif) correspondant. La
fonction lstFeuilles(alphabet,effectifs) renvoie une liste de noeuds ainsi crée.

3.2.2 une fonction intermédiaire

La fonction supprMin(lstNoeuds) supprime (et renvoie) le noeud ayant le plus petit eectif dans la
liste lstNoeuds passée en argument.

3.2.3 fonction principale

La fonction creArbre(alphabet,effectifs)sert a créer l'arbre de Human. Ses entrées sont deux


listes, supposées de même longueur, contenant respectivement les caractères (distincts) dans le mes-
sage et leurs eectifs dans le message a coder.
Voici comment cette fonction procède pour construire l'arbre de Human :

tant que la liste de noeuds contient au moins deux éléments faire


Retirer les deux noeuds avec les plus petits effectifs;
les relier avec un nouveau noeud marqué avec la somme
des effectifs des deux fils.
Ajouter le nouveau noeud dans la liste.
n tant que

3.2.4 tests

Après avoir codé chaque fonction, n'oubliez pas de la tester avant de passer à la fonction suivante.
Pour ce faire pour pourrez réutiliser les méthodes et fonctions écrites à l'occasion du cours/exercices
sur les arbres binaires.

3
3.3 Encodage / décodage
3.3.1 création du code

Pour obtenir le code binaire de chaque caractère, on descend l'arbre à partir de la racine jusqu'aux
feuilles en rajoutant à chaque fois au code un 0 ou un 1 selon la branche suivie.

Voici ce que cela donne sur l'arbre de Human de l'exemple précédent :

A :0 1

C :10 11

B :110 D :111

La fonction récursive creCode(noeud,code,codes) prend en entrée la racine de l'arbre de Human et


renvoie un dictionnaire codes, contenant dans l'ordre les codages (binaires) des caractères de l'alphabet
du message considéré. code est une chaîne contenant le code du chemin parcouru jusqu'au noeud et
codes est le dictionnaire qui se rempli au fur et a mesure avec les encodages.

3.3.2 Encodage

Avant tout, il faut construire les deux listes alphabet et effectifs propres au message. Pour ce faire,
vous pouvez réutiliser la fonction occurrences du TP  Fréquences-mots  dans lequel vous avez ana-
lysé le texte du tour du monde en 80 jours.

Ensuite, vous écrivez la fonction encode(message) qui renvoie le code de Human du message accom-
pagné de l'arbre de Human correspondant.
Par exemple l'appel encode('wikipedia') peut renvoyer la chaîne '000110011101001110011101' et
l'arbre :
[[[[('w', 1)](, 2)[('k', 1)]](, 4)[[('p', 1)](, 2)[('e', 1)]]](, 9)[[[('d', 1)](, 2)[('a', 1)]](, 5)[('i', 3)]]]

3.3.3 Decodage

Enn vous réaliserez une fonction decode(messageCode,HuffmanTree) qui décode le message codé
messageCode à l'aide de son arbre de Human HuffmanTree.

Vous aimerez peut-être aussi