MATH202 TP #2

Compression de données avec l'algorithme LZ78

Objectifs

  • Comprendre l'algorithme LZ78;
  • Manipulation de listes en Python;
  • Comprendre l'impact du choix d'une structure de données dans le temps d'exécution d'un algorithme.

Le TP doit être fait en binôme.

Codeur: Responsable pour l'implementation.

Navigateur: Responsable pour veiller à la qualité du code (?)

Organisation

Sprint 1

Sprint 2

Sprint 3

10

60

110

120

170

180

0

40min

10min

On bosse

On discute

Le binôme doit alterner les rôles de codeur et de navigateur à chaque sprint

Si ta tata tasse ta tata, ta tata tassée sera

si_ta_tata_tasse_ta_tata_ta_tata_tassee_sera

,'s'

,'i'

,'t'

,'a'

,'_t'

,'at'

,'a_'

,'ta'

,'ss'

,'e'

,'_ta'

,'_tat'

,'a_t'

,'a_ta'

,'tas'

,'se'

,'e_'

,'ser' ]

,'_'

1

2

3

[ ''

0

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

dico:

code:

[ 0,'s',

0,'i',

0,'_',

0,'t',

0,'a',

3,'t',

5,'t',

5,'_',

4,'a',

1,'s',

0,'e',

6,'a',

12,'t',

8,'t',

14,'a',

9,'s',

1,'e',

11,'_',

18,'r'

s

i

_

t

a

t

a

_

t

a

_

t

a

s

s

e

_

t

a

t

a

_

t

a

_

t

a

t

a

_

t

a

t

a

s

s

e

e

s

_

e

r

a

_

,'ta_'

20

9,'_',

,5]

LZ78

Algorithme de compression de données

entrée:

Compression

s=dico[0]+'s'

_t=dico[3]+'t'

Un bon Anglais ne plaisante jamais, quand il s’agit d’une chose aussi sérieuse qu’un pari, répondit Phileas Fogg. Je parie vingt mille livres contre qui voudra que je ferai le tour de la terre en quatre-vingts jours ou moins, soit dix-neuf cent vingt heures ou cent quinze mille deux cents minutes. Acceptez-vous ?

Avant LZ78 : 440723 octets   (430 kB)
Après LZ78:  253266 octets   (247 kB)

Taux compression:  (430-247)/430 = 0.42

Jules Verne, Le tour du monde en 80 jours.

LZ78

Algorithme de compression de données

entrée:

[ 0,'a',0,'b',0,'r',1,'c',1,'d',1,'b',3,'a' ]

dico:

Décompression

0

original:

LZ78

Algorithme de compression de données

1

2

3

4

5

6

7

[ 0,'a'

,0,'b'

,0,'r'

,1,'c'

,1,'d'

,1,'b'

,3,'a' ]

[''

,'a'

,'b'

,'r'

,'ac'

,'ad'

,'ab'

,'ra']

a

b

r

ac

ad

ab

ra

Sprint #1

Objectifs: Questions 1, 2 et 3

Mini-Activité

Quiz

Quiz:

Lisez le code suivant

Qu'est-ce qu'il ira afficher?

A) Erreur

B) 9,9,0

C) 10,9,10

D) 9,9,Erreur

liste = [ i for i in range(10) ]

print( liste[-1] )
print( liste[9] )
print( liste[10] )

Resultat

Quiz:

Lisez le code suivant

Qu'est-ce qu'il ira afficher?

A) Erreur

B) 2,8,2

C) 2,4,6

D) 3,9,3

liste = [ i for i in range(10) ]
print( liste[ 2:8:2 ] )

Resultat

Quiz:

Lisez le code suivant

Qu'est-ce qu'il ira afficher?

A) Erreur

B) 1,2,3,4,5,6,7

C) 0,1,2,3,4,4,4

D) 0,1,2,3,4,5,6

liste = [ i if i < 4 else 4  for i in range(10) ]
print( liste[:7] )

Resultat

Quiz:

Lisez le code suivant

Qu'est-ce qu'il ira afficher?

A) 3

B) 9

C) 7

D) 1

liste = [ 3,1,5,9,4,2,7 ]
x = itertools.reduce( lambda x,y: x if x > y else y, liste )
print(x)

Resultat

Sommaire

Indexation de listes:

Le dernière élément:

Expression dans liste:

Une ligne if:

liste[ début : fin : pas ]
liste[-1]
[fn(x) for x in iterable]
val_si_vrai if teste else val_si_faux

Pour computer la taux de compression il faut computer les nombres d'octets dans la liste alternée des entiers et caractères.

Dans la prochaine sprint on va converter la liste dans une chaine d'octets.

Et si l'entier dépasse 255?

b'\x00a\x00b\x00r\x01c\x01d\x01b\x03a'
lz78_compresse_bin("abracadabra")

\x00 : [0]10

\x0A : [10]10

\x10 : [16]10

\xFF : [255]10

LZ78

Algorithme de compression de données

[ 0,'a',0,'b',0,'r',1,'c',1,'d',1,'b',3,'a' ]

LZ78

Algorithme de compression de données

0

255

['',

,'a'

,'b'

,'r'

,'ac'

,'ad'

,'ab'

,'ra']

...

256

257

258

259

260

261

dico:

...\x00a

code:

\x00\x00b
\x00\x00r
\x00\xFFc
\x00\xFFd
\x00\xFFb
\x01\x01a

Et si l'entier dépasse 255?

[ ...

,0,'a'

,0,'b'

,0,'r'

,255,'c'

,255,'d'

,255,'b'

,257,'a' ]

Sprint #2

Objectifs: Questions 4, 5, 6 et 7

Question 5

lz78_compresse_bin

Mini-Activité

Peer Review (?)

Sprint #3

Objectifs: Questions 8, 9 et 10

bytearray(b'\x00a\x01a\x02a\x03a\x04a\x05a\x06a\x07a\x08a\ta\na\x0ba
\x0ca\ra\x0ea\x0fa\x10a\x11a\x12a\x13a\x14a\x15a\x16a\x17a\x18a\x19a
\x1aa\x1ba\x1ca\x1da\x1ea\x1fa a!a"a#a$a%a&a\'a(a)a*a+a,a-a.a/a0a1a
2a3a4a5a6a7a8a9a:a;a<a=a>a?a@aAaBaCaDaEaFaGaHaIaJaKaLaMaNaOaPaQaRaSa
TaUaVaWaXaYaZa[a\\a]a^a_a`aaabacadaeafagahaiajakalamanaoapaqarasataua
vawaxayaza{a|a}a~a\x7fa\x80a\x81a\x82a\x83a\x84a\x85a\x86a\x87a\x88a
\x89a\x8aa\x8ba\x8ca\x8da\x8ea\x8fa\x90a\x91a\x92a\x93a\x94a\x95a\x96a
\x97a\x98a\x99a\x9aa\x9ba\x9ca\x9da\x9ea\x9fa\xa0a\xa1a\xa2a\xa3a\xa4a
\xa5a\xa6a\xa7a\xa8a\xa9a\xaaa\xaba\xaca\xada\xaea\xafa\xb0a\xb1a\xb2a
\xb3a\xb4a\xb5a\xb6a\xb7a\xb8a\xb9a\xbaa\xbba\xbca\xbda\xbea\xbfa\xc0a
\xc1a\xc2a\xc3a\xc4a\xc5a\xc6a\xc7a\xc8a\xc9a\xcaa\xcba\xcca\xcda\xcea
\xcfa\xd0a\xd1a\xd2a\xd3a\xd4a\xd5a\xd6a\xd7a\xd8a\xd9a\xdaa\xdba\xdca
\xdda\xdea\xdfa\xe0a\xe1a\xe2a\xe3a\xe4a\xe5a\xe6a\xe7a\xe8a\xe9a\xeaa
\xeba\xeca\xeda\xeea\xefa\xf0a\xf1a\xf2a\xf3a\xf4a\xf5a\xf6a\xf7a\xf8a
\xf9a\xfaa\xfba\xfca\xfda\xfea\xffa\x01\x00a\x01\x01a\x01\x02a\x01\x03a
\x01\x04a\x01\x05a\x01\x06a\x01\x07a\x00\x14')

LZ78

Algorithme de compression de données

\ta
\na
\xff
>>> lz78_compresse_bin("a"*35000)
\x01\x00

LZ78

Algorithme de compression de données

Compression du texte Moby Dick (1,2Mb)

La vitesse du code actuel (avant la question 13) c'est  frustrant!

Pour comprimer Moby Dick il faut plusieurs minutes.

Le point de faiblesse c'est la structure de donné qu'on utilise.

L'algorithme serait 1000 fois (!!!) plus rapide si on utilise une hash (python dictionnaire) au lieu d'une liste pour garder le dictionnaire.

Temps d'exécution

en utilisant une liste: > 30 minutes

en utilisant une hash: 2 secondes

LZ78

Algorithme de compression de données

Compression du texte Moby Dick (1,2Mb)

Disons qu'on a une liste dico avec 10^6 éléments.

Chaque fois qu'on appelle la fonction position, dans le pire cas on doit lire tous les 10^6 éléments.

Imaginez qu'au lieu d'avoir une seule liste, on a 1000 liste de 1000 éléments chaque.

LZ78

Algorithme de compression de données

Compression du texte Moby Dick (1,2Mb)

dico: [e1,e2,...e10^6]

dico1: [e32,e41,e85...e951245]

dico2: [e17,e19,e39...e1000000]

dico1000: [e5,e23,e60...e977801]

.

.

.

tel que,

\displaystyle \bigcup_{1\leq i \leq 1000}{ \text{dico}_i } = \{e_1, \cdots e_{10^6} \}
\displaystyle \forall i \neq j \quad \text{dico}_i \cap \text{dico}_j = \emptyset

hash( e32 ) = 1

hash( e41 ) = 1

hash( e17 ) = 2

hash( e23 ) = 1000

hash( e85 ) = ?

Mini-Activité

Group Review

Math202 - TP2

By Daniel Martins Antunes

Math202 - TP2

Compression de données avec l'algorithme LZ78

  • 171