Vous êtes sur la page 1sur 6

TP 4 

: Codage Huffman

L'encodage Huffman est un algorithme de compression sans perte utilisé pour compresser
les données. C'est un algorithme développé par David A. Huffman. La compression ici signifie
utiliser moins de bits pour représenter les données.
Par exemple la chaîne « ABC » occupe 3 octets sans aucune compression. Supposons que si
le caractère A reçoit le code 00, le caractère B reçoit le code 01, le caractère C reçoit le code
10 à la suite de l'encodage. Pour stocker les mêmes données, nous n'aurions besoin que de 6
bits au lieu de 3 octets.

1. L’algorithme
Le codage de Huffman est un algorithme qui utilise la caractéristique de fréquence (ou
probabilité) des symboles et une structure arborescente binaire. Il se compose des 3 étapes
suivantes :

 Calcul de probabilité et ordre des symboles


 Transformation d'arbre binaire
 Attribution de codes aux symboles

2. Calcul de probabilité et ordre des symboles


Nous comptons le nombre de chaque symbole dans l'ensemble des données, puis nous
calculons la « probabilité » de chaque symbole en divisant ce nombre par le nombre total de
caractères dans les données. Comme il s'agit d'un algorithme utilisant la probabilité, les
symboles les plus courants (les symboles ayant une probabilité plus élevée) sont
généralement représentés en utilisant moins de bits que les symboles moins courants. C'est
l'un des avantages de l'encodage Huffman.
A titre d'exemple, pour les données suivantes ayant 5 symboles différents comme A B C D E,
nous avons les probabilités comme indiqué à droite :

1
Ensuite, nous ordonnons facilement les symboles en fonction de leurs probabilités
représentant chaque symbole comme un nœud et appelons cela notre « collection ».
Maintenant, nous sommes prêts à passer l'étape suivante.

3. Transformation d'arbre binaire


 De la collection, nous sélectionnons les deux nœuds avec la plus petite somme de
probabilités et les combinons dans un nouvel arbre dont la racine a la probabilité
égale à cette somme.
 Nous rajoutons le nouvel arbre dans la collection.
 Nous répétons ce processus jusqu'à ce qu'un arbre englobant toutes les probabilités
d'entrée ait été construit.

4. Attribution de codes aux symboles


Après avoir obtenu cet arbre binaire - appelé arbre de Huffman, la seule chose que nous
devons faire est d'attribuer 1 pour chaque fois que nous allons à l'enfant à droite et 0 pour
chaque fois que nous allons à l'enfant à gauche. Enfin, nous avons les symboles et leurs
codes obtenus par Huffman Encoding !

2
Nous pouvons jeter un coup d'œil et voir que même pour 21 caractères seulement, la
différence entre les données compressées et non compressées n'est pas négligeable.

5. Code python
https://github.com/YCAyca/Data-Structures-and-Algorithms-with-
Python/blob/main/Huffman_Encoding/huffman.py

# A Huffman Tree Node


class Node:
def __init__(self, prob, symbol, left=None, right=None):
# probability of symbol
self.prob = prob

# symbol
self.symbol = symbol

# left node
self.left = left

# right node
self.right = right

# tree direction (0/1)


self.code = ''

""" A helper function to print the codes of symbols by traveling


Huffman Tree"""

3
codes = dict()

def Calculate_Codes(node, val=''):


# huffman code for current node
newVal = val + str(node.code)

if(node.left):
Calculate_Codes(node.left, newVal)
if(node.right):
Calculate_Codes(node.right, newVal)

if(not node.left and not node.right):


codes[node.symbol] = newVal

return codes

""" A helper function to calculate the probabilities of symbols in


given data"""
def Calculate_Probability(data):
symbols = dict()
for element in data:
if symbols.get(element) == None:
symbols[element] = 1
else:
symbols[element] += 1
return symbols

""" A helper function to obtain the encoded output"""


def Output_Encoded(data, coding):
encoding_output = []
for c in data:
# print(coding[c], end = '')
encoding_output.append(coding[c])

string = ''.join([str(item) for item in encoding_output])


return string

""" A helper function to calculate the space difference between


compressed and non compressed data"""
def Total_Gain(data, coding):
before_compression = len(data) * 8 # total bit space to stor the
data before compression
after_compression = 0
symbols = coding.keys()
for symbol in symbols:
count = data.count(symbol)
after_compression += count * len(coding[symbol]) #calculate
how many bit is required for that symbol in total
print("Space usage before compression (in bits):",
before_compression)
print("Space usage after compression (in bits):",
after_compression)

def Huffman_Encoding(data):
symbol_with_probs = Calculate_Probability(data)
symbols = symbol_with_probs.keys()

4
probabilities = symbol_with_probs.values()
print("symbols: ", symbols)
print("probabilities: ", probabilities)

nodes = []

# converting symbols and probabilities into huffman tree nodes


for symbol in symbols:
nodes.append(Node(symbol_with_probs.get(symbol), symbol))

while len(nodes) > 1:


# sort all the nodes in ascending order based on their
probability
nodes = sorted(nodes, key=lambda x: x.prob)
# for node in nodes:
# print(node.symbol, node.prob)

# pick 2 smallest nodes


right = nodes[0]
left = nodes[1]

left.code = 0
right.code = 1

# combine the 2 smallest nodes to create new node


newNode = Node(left.prob+right.prob,
left.symbol+right.symbol, left, right)

nodes.remove(left)
nodes.remove(right)
nodes.append(newNode)

huffman_encoding = Calculate_Codes(nodes[0])
print("symbols with codes", huffman_encoding)
Total_Gain(data, huffman_encoding)
encoded_output = Output_Encoded(data,huffman_encoding)
return encoded_output, nodes[0]

def Huffman_Decoding(encoded_data, huffman_tree):


tree_head = huffman_tree
decoded_output = []
for x in encoded_data:
if x == '1':
huffman_tree = huffman_tree.right
elif x == '0':
huffman_tree = huffman_tree.left
try:
if huffman_tree.left.symbol == None and
huffman_tree.right.symbol == None:
pass
except AttributeError:
decoded_output.append(huffman_tree.symbol)
huffman_tree = tree_head

5
string = ''.join([str(item) for item in decoded_output])
return string

""" First Test """


data = "AAAAAAABCCCCCCDDEEEEE"
print(data)
encoding, tree = Huffman_Encoding(data)
print("Encoded output", encoding)
print("Decoded Output", Huffman_Decoding(encoding,tree))

6. Travail à Faire

- Identifiez et donnez le programme principal du code python donné.


- Donnez les fonctions du programme principal
- Expliquez l’objectif de chaque fonction et expliquez à chaque fois les entrées et les
sorties
- Donnez l’encodage du mot « ISTMT TUNIS »
- Tracez l’arbre correspondant.

NB : Rendre le travail sous forme de documents word. Le travail peut être effectué par un ou
deux étudiants.

Vous aimerez peut-être aussi