• Aucun résultat trouvé

Files de priorité

N/A
N/A
Protected

Academic year: 2022

Partager "Files de priorité"

Copied!
15
0
0

Texte intégral

(1)

Amphi 7 1

Plan

• Files de priorité

• Représentation par tas

• Tri par tas

• Codes préfixes

• Codage de Huffman

• Codage de Huffman adaptatif

Amphi 7 2

Files de priorité

Une file de priorité est un type abstrait de données

opérant sur un ensemble ordonné, et muni des opérations suivantes :

• trouver le maximum,

• insérer un élément,

• retirer le maximum.

En inversant l'ordre, on obtient un type abstrait permettant de trouver le minimum et de le retirer.

Files de priorité

Exemples d'utilisation :

• Ordonnancement des tâches d'un système d'exploitation.

• Application boursière (d'après Rolf Ingold)

• Contrôle aérien

• etc.

Trouvé sur le Web ...

Perle donne l’avantage aux applications critiques en implantant la gestion des niveaux de priorité sur sa gamme de routeurs.

Afin d’améliorer les performances des réseaux en fonction des applications, Perle Systems a implanté dans ses routeurs un nouveau mode de gestion des files d’attente. Celui-ci permet à l’administrateur réseau de définir quatre niveaux de priorité (haute, normale, moyenne ou basse) pour une interface ou un protocole donnés. Tous les paquets qui entrent dans le routeur sont affectés à une file d’attente en fonction d’un degré d’urgence défini au préalable. Les paquets affectés à la file ayant une priorité haute sont transmis les premiers. Lorsque cette file est vide, c’est le tour des paquets affectés à la file ayant la priorité immédiatement inférieure. Ce système permet de ne pas retarder la transmission des données prioritaires lorsque le réseau est encombré.

(2)

Amphi 7 5

Trouvé aussi sur le Web: application boursière

• Une commande comprend trois champs (action, prix, quantité), où action est un achat ou une vente, prix est le prix proposé et quantité est le nombre d’actions.

• Une cote donne l’offre la plus haute et la demande la plus basse.

• Lorsqu'une transaction survient, on effectue une série de suppressions dans la liste des commandes.

• Les commandes peuvent être annulées à tout moment.

Amphi 7 6

Structure de données pour le marché boursier

Une structure pour les offres, une pour les demandes.

Opérations supportées :

supprimer(demande) supprimer(offre)

Annuler

retirerMax() retirerMin()

Transaction

max() min()

Cote

insere(prix, quantité) insere(prix, quantité)

Commande

Demandes Offres

Actions

Source: Cours du Prof. Rolf Ingold de l'université de Fribourg

Implantation des files de priorité

Implantation Trouver Insérer Retirer

max max

Tableau non ordonné O(n) O(1) O(n) Liste non ordonnée O(n) O(1) O(1)*

Tableau ordonné O(1) O(n) O(1)

Liste ordonnée O(1) O(n) O(1)

Tas O(1) O(log n) O(log n)

* après avoir trouvé

Plan

• Files de priorité

• Représentation par tas

• Tri par tas

• Codes préfixes

• Codage de Huffman

• Codage de Huffman adaptatif

(3)

Amphi 7 9

Arbre binaire tassé

0 1

0

0

0

0

1

1 1

Un arbre binaire est dit tassé si son code est un segment initial pour l'ordre des mots croisés.

Code : {#, 0, 1, 00, 01, 10, 11, 000, 001, 010}

La hauteur d'un arbre tassé à n noeuds est !log2 n".

Amphi 7 10

Structure de tas (heap en anglais)

Un tas est un arbre binaire tassé tel que le contenu de chaque nœud soit supérieur ou égal à celui de ses fils.

4 8

6 12

7 15

23

5 1

2

Représentation par tableau

4 8

6 12

7 15

23

5 1

2 0

1 2

3 4 5 6

7 8 9

Numéro d'un nœud (en largeur) = indice du tableau

23 15 7 12 5 6 1 4 8 2 11 3 0 1 2 3 4 5 6 7 8 9 10 11

Racine : nœud 0 Pour un nœud i, Parent : !(i-1)/2"

Fils gauche : 2i+1 Fils droit : 2i+2

Les tas en Java

23 15 7 12 5 6 1 4 8 2 11 3 0 1 2 3 4 5 6 7 8 9 10 11

class Tas {

int[] a;

int nTas;

Tas(int n) {...}

int maximum() {...}

void ajouter(int v) {...}

void supprimer(){...}

}

(4)

Amphi 7 13

Constructeur

Le constructeur crée un tableau

class Tas {

int[] a;

int nTas;

Tas(int n) {

nTas = 0;

a = new int[n];

} ...

}

Amphi 7 14

Maximum

Le maximum est le contenu de la racine.

class Tas {...

int maximum() {

return a[0];

} }

Complexité : O(1).

23 15 7 12 5 6 1 4 8 2 11 3 0 1 2 3 4 5 6 7 8 9 10 11

Insertion

23 15 7 12 5 6 1 4 8 2 21 0 1 2 3 4 5 6 7 8 9 10 11

• Placer le nouveau nœud dans la première position libre (10)

• Permuter avec le parent jusqu'à l'obtention d'un tas

4 8

6 12

7 15

23

5 1

2 0

1 2

3 4 5 6

7 8 9

21

10 Complexité : 0(log n)

Après insertion de 21

4 8

6 12

7 21

23

15 1

2 0

1 2

3 4 5 6

7 8 9

2321 7 12 15 6 1 4 8 2 5 0 1 2 3 4 5 6 7 8 9 10 11 5

10

(5)

Amphi 7 17

Insertion en Java

void ajouter(int v) {

int i = nTas;

++nTas;

while (i > 0 && a[(i-1)/2] <= v) {

a[i] = a[(i-1)/2];

i = (i-1)/2;

}

a[i] = v;

}

Amphi 7 18

Retirer le maximum

2 4

9 8

11 15

16

14 3

7 0

1 2

3 4 5 6

7 8 9

• Donner à la racine la valeur du dernier nœud.

• Supprimer le dernier nœud.

• Echanger avec le plus grand fils jusqu'à l'obtention d'un tas.

16 15 11 8 14 9 3 2 4 7 10 3 0 1 2 3 4 5 6 7 8 9 10 11 10

10 Complexité : O(log n)

Retirer le maximum

2 4

9 8

11 15

10

14 3

7 0

1 2

3 4 5 6

7 8 9

En Java

void supprimer() {

int v = a[0] = a[--nTas];

int i = 0;

while (2*i + 1 < nTas) { int j = 2*i + 1;

if (j + 1 < nTas && a[j+1] > a[j]) ++j;

if (v >= a[j]) break;

a[i] = a[j];

i = j;

}

a[i] = v;

}

(6)

Amphi 7 21

Plan

• Files de priorité

• Représentation par tas

• Tri par tas

• Codes préfixes

• Codage de Huffman

• Codage de Huffman adaptatif

Amphi 7 22

Tri par tas (heapsort)

On part d'un tableau vide a. On commence par

construire un tas en ajoutant successivement au tas vide les éléments a[0], a[1], ...

On répète ensuite les opérations suivantes : - prendre le maximum,

- le retirer du tas,

- le mettre à droite du tas Complexité : O(n log n)

Trier (9, 2, 11, 7, 4, 14, 3, 16, 8, 10, 15)

9

2 9

9 2

11

2

9 7

11

4 2

7 9 11

9 4 2

11 7

14

...

On ajoute un à un les éléments:

Trier (5, 2, 11, 7, 4, 14, 3, 16, 8, 10, 15)

2 4

9 8

11 15

16

14 3

7 0

1 2

3 4 5 6

7 8 9

16 15 11 8 14 9 3 2 4 7 10 0 1 2 3 4 5 6 7 8 9 10 10

10

Une fois le tas obtenu...

(7)

Amphi 7 25

Trier (5, 2, 11, 7, 4, 14, 3, 16, 8, 10, 15)

2 4

9 8

11 14

15

10 3

7 0

1 2

3 4 5 6

7 8 9

15 14 11 8 10 9 3 2 4 7 16 0 1 2 3 4 5 6 7 8 9 10

On retire les éléments un à un.

Amphi 7 26

Trier (5, 2, 11, 7, 4, 14, 3, 16, 8, 10, 15)

2 4

9 8

11 10

14

7 3

0

1 2

3 4 5 6

7 8

14 10 11 8 7 9 3 2 4 15 16 0 1 2 3 4 5 6 7 8 9 10

On retire les éléments un à un.

Trier (5, 2, 11, 7, 4, 14, 3, 16, 8, 10, 15)

2

4 8

9 10

11

7 3

0

1 2

3 4 5 6

7

11 10 9 8 7 4 3 2 14 15 16 0 1 2 3 4 5 6 7 8 9 10

On retire les éléments un à un.

...

Tri par tas (heapsort) en Java

static int[] triParTas(int[] a) {

int n = a.length;

Tas t = new Tas(n);

for (int i = 0; i < n; i++) t.ajouter(a[i]);

for (int i = n-1; i >= 0; --i) {

int v = t.maximum();

t.supprimer();

a[i] = v;

}

return a;

}

(8)

Amphi 7 29

Plan

• Files de priorité

• Représentation par tas

• Tri par tas

• Codes préfixes

• Codage de Huffman

• Codage de Huffman adaptatif

Amphi 7 30

Codes préfixes

Un ensemble P de mots non vides est un code préfixe si aucun mot de P n'est préfixe propre d'un autre mot de P.

Exemple : P = {0, 100, 101, 111, 1100, 1101}

Un mot admet au plus une décomposition comme produit de mots de P. La décomposition, si elle existe, s'obtient en lisant le mot de gauche à droite.

101010110111010110001010101001010100

Codes préfixes

Un ensemble fini de mots

est un code préfixe si et seulement si c'est le code des feuilles d'un arbre binaire.

0 1

0

0

0

0 1

1 1

Code des feuilles : {00, 010, 101, 110}

Codes préfixes

Un code préfixe P est complet si tout mot est

préfixe d'un produit de mots de P.

Le code préfixe

{0, 100, 101, 111, 1100, 1101}

est complet :

1001010101011110110011011100101110 On peut compléter ce mot par 1.

(9)

Amphi 7 33

Codes préfixes complets

Un arbre binaire est dit

complet si ses nœuds internes sont d'arité 2.

0 1

0

0

0 1

1 1

Code des feuilles : {00, 010, 011, 10, 11}

Un arbre binaire est complet ssi le code de ses feuilles est un code préfixe complet.

Amphi 7 34

Codage par code préfixe

Codage :

a --> 00 d --> 10 b --> 010 r --> 11 c --> 011

b c

d

a r

0 1

0

0

0 1

1 1

abracadabra <-->

0001011000110010000101100 Décodage : unique par

lecture de gauche à droite.

Plan

• Files de priorité

• Représentation par tas

• Tri par tas

• Codes préfixes

• Codage de Huffman

• Codage de Huffman adaptatif

Compression de Huffman

Problème. Coder un texte à l'aide d'un code préfixe en minimisant la taille du texte codé.

Exemples avec abracadabra

(1) a : 00, b : 010, c : 011, d : 10, r : 11.

0001011000110010000101100 --> 25 (2) a : 1, b : 000, c : 0010, d : 0011, r : 01 10000110010100111000011 --> 23

Remarque. La taille ne dépend que de la fréquence d'apparition de chaque lettre. 5 a, 2 b, 1 c, 1 d, 2 r

(10)

Amphi 7 37

Construction de l'arbre de Huffman (1)

Initialisation. Pour chaque lettre, un arbre réduit à sa racine. Sa valeur est la fréquence de la lettre.

Itération. On fusionne les deux arbres de valeur minimale. La nouvelle racine a pour valeur la somme des valeurs des racines des deux arbres.

5 2 1 1 3

a b c d e

1 1

c d

2

Amphi 7 38

Construction de l'arbre de Huffman (2)

5 2 3

a b e

1 1

c d

2

(1)

5 3

a 2

b

e

1 1

c d

2 4

5 (2)

a 3 2

b

e

1 1

c d

2 4

7

(3)

c d

5

a 3 2

b

e

1 1

2 4

7 12

(4)

Codage a = 0 b = 100 c = 1010 d = 1011 e = 11

Utilisation de l'algorithme de Huffman.

• Le codage de Huffman donne un code préfixe optimal. (admis)

• Utilisé dans le fax et dans JPEG (compression d'images)

• On peut coder par groupes de 2 lettres ou plus (bitmaps).

• Il y a des techniques de compression sans perte de données nettement plus efficaces (codage

arithmétique, Ziv-Lempel, etc.)

Choix de la représentation de données.

• Si la taille de l'alphabet est N, l' arbre de Huffman est de taille 2N-1. On le représente ici par un tableau, où (le père de la racine est 0)

j si i est fils droit de j pere[i] =

-j si i est fils gauche de j

La création de l'arbre est contrôlée par un tas-min, dont les clés sont les fréquences des lettres.

• Note : on pourrait aussi utiliser deux files.

(11)

Amphi 7 41

Huffman en Java (1)

class Huffman { // Arbre à 2N - 1 nœuds final static int N = 26, M = 2*N - 1;

static int[] pere = new int[M];

static int[] freq = new int[M];

public static void main(String[] args) {

String s = args[0] ; calculFrequences(s);

creerArbre();

String[] tas = faireTable();

afficherCode(s, table);

} }

Amphi 7 42

Calcul des fréquences

static void calculFrequences(String s) {

for (int i = 0; i < s.length(); i++) freq[s.charAt(i) - 'a']++;

}

static int nombreLettres() {

int n = 0;

for (int i = 0; i < N; i++) if (freq[i] > 0)

n++;

return n;

}

Un tas-min avec clés

• Un tas-min est un tas pour l'ordre > . Autrement dit, le minimum est à la racine et le contenu de chaque nœud est inférieur au contenu de son fils gauche et de son fils droit.

• Un tas avec clés gère des données avec priorités : – les données sont dans le tableau (ici tas) – les priorités sont dans un deuxième tableau (ici

freq)

Un tas-min avec clés en Java

class Tas {

int[] tas; // contient les caractères int nTas = 0;

int[] freq; // fréquences des caractères Tas(int taille, int[] freq)

{

this.freq = freq;

nTas = 0;

tas = new int[taille];

} ...

}

(12)

Amphi 7 45

Ajouter à un tas-min (avec clé)

void ajouter(int v) {

int i = nTas;

++nTas;

while (i > 0 &&

freq[tas[(i-1)/2]] >= freq[v]) {

tas[i] = tas[(i-1)/2];

i = (i-1)/2;

}

tas[i] = v;

}

Amphi 7 46

void supprimer() {

int v = tas[0] = tas[--nTas];

int i = 0;

while (2*i + 1 < nTas) { int j = 2*i + 1;

if (j + 1 < nTas &&

freq[tas[j+1]] < freq[tas[j]]) ++j;

if (freq[v] <= freq[tas[j]]) break;

tas[i] = tas[j];

i = j;

}

tas[i] = v;

}

Supprimer dans un tas-min (avec clé)

int minimum() {

return tas[0];

}

Minimum

static void creeArbre() {

int n = nombreLettres();

Tas tas = new Tas(2*n - 1, freq);

for (int i = 0; i < N; ++i) if (freq[i] > 0)

tas.ajouter(i);

int n = tas.nTas;

// A suivre ...

}

Création de l'arbre

(13)

Amphi 7 49

static void creeArbre() { // ...

for (int i = N; i < N+n-1; ++i) {

int x = tas.minimum();

tas.supprimer();

int y = tas.minimum();

tas.supprimer();

freq[i] = freq[x] + freq[y];

pere[x] = -i;

pere[y] = i;

tas.ajouter(i);

} }

Création de l'arbre (2)

Amphi 7 50

static String code(int i) {

if (pere[i] == 0) return "";

return code(Math.abs(pere[i])) + ((pere[i] < 0) ? 0 : 1);

}

Codage

Transmission du code. Première solution

a : 0 b : 1010 c : 100 d : 1011 e : 11

a

e c

b d

On code le parcours préfixe : nœud interne 0, feuille 1

01[a]001[c]01[b]1[d]1[e]

où [x] est le code ASCII de x.

Transmission du code. Deuxième solution

7 6

2 1 2

3 5 11

a : 1 18

b : 0101 c : 011 d : 0100 e : 00

On calcule, puis on transmet des fréquences fictives donnant le même code de Huffman ! Ici 7, 1, 2, 2, 6, codées sur un petit nombre de bits.

43 41

14 12 13

a

c e

b d

25 39 80

123

a

c e

b d

(14)

Amphi 7 53

Plan

• Files de priorité

• Représentation par tas

• Tri par tas

• Codes préfixes

• Codage de Huffman

• Codage de Huffman adaptatif

Amphi 7 54

L'algorithme de Huffman adaptatif.

Inconvénients de l'algorithme de Huffman.

• Il faut lire le texte entièrement avant de lancer la compression.

• Il faut transmettre le code trouvé.

La version adaptative corrige ces défauts. Principe :

• On envoie le code d'un caractère c.

• La fréquence de c est incrémentée. On met à jour l'arbre de Huffman (voir plus loin).

• Le décodage mime le codage (même mise à jour).

Mise à jour de l'arbre.

On maintient une liste de parcours des nœuds - compatible avec l'ordre des clés

- dans lequel deux frères sont toujours consécutifs.

11

a 11 5 3 2 c e

b d

5 10

21 32

6 5

1 f

2

4 3 6 5

7 8

9 10

11

On démontre que, dans un arbre de Huffman, on peut toujours trouver un ordre de parcours possédant ces

propriétés.

Mise à jour après incrémentation.

Deux types d'opérations

• Partant de la feuille dont la clé est incrémentée, on remonte vers la racine en incrémentant les clés des nœuds rencontrés.

• Avant l'incrémentation, chaque nœud est permuté avec le dernier nœud de même clé dans l'ordre de parcours.

(15)

Amphi 7 57

Mise à jour après incrémentation.

11

a 11 5 3 3 c e

b d

5 10

21 32

6 5

1 f

2

3 4 6 5

7 8

9 10

11

11

a 11

6

c e 3 3

b d

5 10

21 32

5 6

f 2 1

3 4 6 5

7 8

9 10

11

Après incrément du nœud 1, avant incrément de son père.

Après incrément du nœud 5, avant incrément de son père.

Amphi 7 58

Mise à jour après incrémentation.

11 12

a

6

c e

3 3

b d

5 10

21 33

6

5

f

1

2 3 4

5

6 7

9

8 10 11

Après incrément des nœuds 1, 5, 9, 11.

Le nouvel ordre de parcours vérifie bien les deux propriétés.

Algorithme de Huffman. Statistiques

Contes de Grimm Données techniques Bits

Huffman + Code Total

H. Adaptatif

Codage par digrammes Huffman

+ Code Total

H. Adaptatif

700 000 439 613 522 440 135 440 164 383 264 10 880 394 144 393 969

700 000 518 361 954 519 315 519 561 442 564 31 488 474 052 472 534

Références

Documents relatifs

Insérer à la prochaine place libre dans l’arbre qui doit rester parfait, puis faire remonter le long de la branche jusqu’à satisfaire la contrainte sur les priorités. Complexité

Les décès, les handicaps tels que les amputations et la perte de qualité de vie sont des résultats possibles sur le plan de la santé qui pourraient être utilisés dans le cas

Sur route mouillée, cette distance de freinage est deux fois plus grande que sur route sèche à vitesse égale.. Recopie et complète le tableau à double

Aussi, telle n’est pas le cas, on recherche l’élément le plus grand à la gauche de cet élément (où l’élément le plus petit à la droite de cet élément) qui ne peut

• Un tas avec clés gère des données avec priorités : – les données sont dans le tableau (ici tas). – les priorités sont dans un deuxième tableau

Amphibiens Grenouille  verte

Cette op´ eration permet de diminuer la cl´ e d’un ´ el´ ement pr´ esent dans la file.. Nous allons donc pr´ esenter ce mod` ele en d´ etail, mais nous commen¸cons par pr´

Cette publication régulière de fi- ches dans notre bulletin nous a d'ailleurs valu la proposition de Freinet de vouloir bien nous occuper de la Commission du