Application des arbres binaires. Plan Compter les arbres binaires Tétrarbres (quad trees) Problème des n corps Recherche dans un intervalle Recherche dans un nuage de points Recherche dans un arbre d intervalles Amphi 8 1
Rappel : un arbre binaire est soit vide, soit union disjointe d'une racine, d'un sous-arbre gauche et d'un sous-arbre droit. Si b n est le nombre d'arbres binaires distincts à n nœuds, on a donc : La série B(x) = Compter les arbres binaires (1) Σ b 0 = 1 b n = b i b n-i-1 Σn 0 b n x n n-1 i = 0 vérifie l'identité xb 2 (x) - B(x) + 1 = 0 Amphi 8 2
La résolution de l'équation xb 2 (x) - B(x) + 1 = 0 donne b n = = d'où b n ~ π -1/2 4 n n -3/2 + O(4 n n -5/2 ) Compter les arbres binaires (2) 1 n+1 ( 2n) n (2n)! n!(n+1)! (1) Dans un arbre, nombre de nœuds = 1 + nombre d'arcs (2) Dans un arbre binaire complet (tout nœud est d'arité 0 ou 2), nombre de feuilles = 1 + nombre de nœuds internes Amphi 8 3
Application des arbres binaires. Plan Compter les arbres binaires Tétrarbres (quad trees) Problème des n corps Recherche dans un intervalle Recherche dans un nuage de points Recherche dans un arbre d intervalles Amphi 8 4
Une image est : soit de couleur uniforme Une vision hiérarchique des images soit formée de quatre images NO NE SO SE SO NO NE SE Amphi 8 5
Tétrarbres (quad trees) Une image 2 n x 2 n est subdivisée itérativement en quadrants jusqu'au niveau du pixel. NO NE SO SE Amphi 8 6
Tétrarbre associé à une image Amphi 8 7
Une échelle de 32 couleurs Amphi 8 8
Tétrarbre associé à une image Merci à Luc Maranget... Amphi 8 9
Tétrabres en Java (1) class Tetrarbre { boolean couleur; // version noir et blanc boolean estfeuille; Tetrarbre so, no, ne, se; // Constructeur des feuilles Tetrarbre(boolean couleur) { this.estfeuille = true; this.couleur = couleur; }... Amphi 8 10
Tétrarbres en Java (2)... // Constructeur des nœuds internes Tetrarbre(Tetrarbre so, Tetrarbre no, Tetrarbre ne, Tetrarbre se) { this.estfeuille = false; this.so = so; this.no = no; this.ne = ne; this.se = se; } } static boolean[][] image; // pixels Amphi 8 11
Tétrarbres en Java (3) static boolean estmonochrome( Tetrarbre so, Tetrarbre no, Tetrarbre ne, Tetrarbre se) { return (so.estfeuille && no.estfeuille && ne.estfeuille && se.estfeuille && so.couleur == no.couleur && so.couleur == ne.couleur && so.couleur == se.couleur); } Amphi 8 12
t = taille/2 pixel (i, j) i j j + t NO NE i + t SO SE Amphi 8 13
Tétrarbres en Java (4) static Tetrarbre fairearbre(int taille, int i, int j) { if (taille == 1) return new Tetrarbre(image[i][j]); int t = taille/2; Tetrarbre so = fairearbre(t, i+t, j); Tetrarbre no = fairearbre(t, i, j); Tetrarbre ne = fairearbre(t, i, j+t); Tetrarbre se = fairearbre(t, i+t, j+t); if (estmonochrome(so, no, ne, se)) return new Tetrarbre(so.couleur); return new Tetrarbre(so, no, ne, se); } Amphi 8 14
Codage On code l'arbre par un parcours préfixe. Les nœuds internes sont codés 0 et les feuilles 1. Après chaque 1, on code la couleur de la feuille (0 pour blanc, 1 pour bleu). Equivaut au code : 0 11 10 On pourrait améliorer le code : 0110101110110011101110100111010111101010010111001011101111 Amphi 8 15 00 01 1
Tétrabres en Java (5) static void parcours(tetrarbre a) { if (a!= null) { if (a.estfeuille) System.out.print("1" + ((a.couleur)? "1" : "0")); else // nœud interne System.out.print("0"); parcours(a.so); parcours(a.no); parcours(a.ne); parcours(a.se); } } Amphi 8 16
Autre avantage des tétrarbres On peut changer facilement la couleur d'une image. Faire une rotation d'un quart de tour. NO NE NE SE SO SE NO SO SO NO NE SE NO NE SE SO Amphi 8 17
Application des arbres binaires. Plan Compter les arbres binaires Tétrarbres (quad trees) Problème des n corps Recherche dans un intervalle Recherche dans un nuage de points Recherche dans un arbre d intervalles Amphi 8 18
Problème des n corps Objectif : simuler le comportement de n particules (force de gravité ou électrostatique). Solution directe, itérer les calculs suivants : les n(n-1) forces F(p, q) entre 2 particules p et q, la résultante des forces pour chaque particule, le mouvement résultant pour une unité de temps. Trop lent pour n grand. Calcul hiérarchique calculs exacts pour des particules proches; on assimile les particules distantes à leur barycentre. Amphi 8 19
Algorithme de Barnes-Hut Octabres: c'est la version 3D des tétrarbres : un cube est divisé récursivement en 8 cubes. Calcul de la force F(p, C), sur la particule p, issue du cube C de coté c et de barycentre b. Si C ne contient qu'une particule q, F(p, C) = F(p, q) Si la distance de p à b est > α.c (par ex. α = 2 ou 3), F(p, C) = F(p, b) Sinon F(p, C) = résultante (F(p, C 1 ),..., F(p, C 8 )) où C 1,..., C 8 sont les 8 sous-cubes de C. A Hierarchical O(n log n) force calculation algorithm, J. Barnes and P. Hut, Nature, v. 324, Décembre 1986 Amphi 8 20
2 1 3 4 5 6 7 8 9 10 11 12 1 Tétrarbre associé 1 4 2 3 2 4 1 3 4 3 4 2 3 8 1 3 1 4 2 4 12 4 5 6 7 9 2 4 10 11
Réalisation Données : pour chaque cube, la masse totale et le barycentre. Ce calcul peut se faire récursivement. Gestion de l'octarbre L'arbre est reconstruit à chaque unité de temps. Cas le pire en O(n 2 ). En pratique, arbre de hauteur O(log n). Pour une distribution uniforme en 3D, le nombre d'interactions à calculer est 28πα 3 ~ (n log 2 n) soit ~ 263(n log 2 n) pour α = 3 9 Amphi 8 22
Résultats expérimentaux Simulation d'un système de 5000 particules : 10 fois plus rapide qu'avec l'algorithme direct. L'algorithme est facilement parallélisable. La simulation réaliste d'une galaxie nécessite des millions d'étoiles. On connaît un algorithme en O(n). En 1994, on a simulé 10 7 particules pour 10 3 pas de calcul (une semaine de calcul sur 500 processeurs...) Amphi 8 23
Application des arbres binaires. Plan Compter les arbres binaires Tétrarbres (quad trees) Problème des n corps Recherche dans un intervalle Recherche dans un nuage de points Recherche dans un arbre d intervalles Amphi 8 24
Recherche en une dimension Problème : Compter les éléments d un ensemble d entiers qui sont dans un intervalle donné [min, max]. Exemple : E = {7, 9, 10, 12, 15, 20} Entre 12 et 19, il y a 2 éléments. L ensemble est donné par un arbre binaire de recherche. Le prétraitement se fait en O(n log n), la recherche se fait en temps O(r + log n) où r est le nombre d'éléments trouvés. Amphi 8 25
Exemple 10 Entre 8 et 19, il y a 4 éléments. 3 9 6 7 12 15 20 25 On peut couper les sous-arbres issus de 3 (à gauche de 7) et de 25 (à droite de 20). 5 Amphi 8 26
Exemple plus compliqué 50 Entre 25 et 75 7 30 40 60 80 90 55 65 70 72 79 Amphi 8 27
static int compter(arbre a, int min, int max) { int total = 0; if (a == null) return total; if (a.contenu >= min) total += compter(a.filsg, min, max); if (a.contenu >= min && a.contenu <= max) total++; if (a.contenu <= max) total += compter(a.filsd, min, max); return total; } En Java Amphi 8 28
Application des arbres binaires. Plan Compter les arbres binaires Tétrarbres (quad trees) Problème des n corps Recherche dans un intervalle Recherche dans un nuage de points Recherche dans un arbre d intervalles Amphi 8 29
Recherche en deux dimensions Problème : Etant donné un ensemble de points dans le plan, déterminer ceux qui sont dans une zone donnée. Exemples : Trouver les villes à moins de 100 km de Tours Trouver les personnes entre 25 et 29 ans qui gagnent entre 1000 et 2000 euros par mois. Amphi 8 30
Recherche en deux dimensions J G A C H E K D I Problème : Nombre de points dans un rectangle donné. F B L Solution en deux étapes 1. Prétraitement : un arbre pour le nuage de points 2. Réponse : une recherche dans l arbre Amphi 8 31
Arbres pour des points class Point { // Conflit avec MacLib! int x, y; Point(int a, int b) { x = a; y = b; } } class Arbre { Point p; Arbre filsg, filsd; Arbre(Arbre g, Point v, Arbre d) { filsg = g; p = v; filsd = d; } } Amphi 8 32
Arbre pour un nuage de points Construire un arbre comme suit le premier point coupe le plan en deux, horizontalement. les points coupent des secteurs horizontalement aux niveaux pairs, et verticalement aux niveaux impairs. Amphi 8 33
Exemple J G A C H E K D I A F B L Amphi 8 34
Exemple J G A C H E K D I B A F B L B est fils gauche de A car B.y < A.y Amphi 8 35
Exemple J G A C H E K D I C B A F B L C est fils gauche de A car C.x < B.x Amphi 8 36
Exemple J G A C H E K D I C B D A F B L D est fils droit de B car D.x > B.x Amphi 8 37
Exemple J G A C H E K D I C B D A E F B L E est fils droit de A car E.y > A.y D est fils droit de B car D.x > B.x Amphi 8 38
Insérer un point : au début A la racine, le niveau est impair static Arbre ajouter(point p, Arbre a) { return ajouter(p, a, false); } static Arbre ajouter(point p, Arbre a, boolean vertical) {... } Amphi 8 39
Insérer un point : une étape static Arbre ajouter(point p, Arbre a, boolean vertical) { if (a == null) return new Arbre(null, p, null); boolean estagauche = (vertical)? (p.x < a.p.x) : (p.y < a.p.y); if (estagauche) // insérer à gauche return new Arbre(ajouter(p, a.filsg,!vertical), a.p, a.filsd); else // insérer à droite return new Arbre(a.filsG, a.p, ajouter(p, a.filsd,!vertical)); } Amphi 8 40
La classe Rectangle class Rectangle { int g, d, b, h; } g h b d g : abcisse du côté gauche d : abcisse du côté droit b : ordonnée du côté bas h : ordonnée du côté haut Amphi 8 41
Le décompte (1) static int compter(rectangle r, Arbre a, boolean vertical) { if (a == null) return 0; int total = 0; boolean agauche = r.g <= a.p.x; boolean adroite = a.p.x < r.d; boolean enbas = r.b <= a.p.y; boolean enhaut = a.p.y < r.h; boolean min, max; min = (vertical)? agauche : enbas; max = (vertical)? adroite : enhaut;... // à suivre } Amphi 8 42
Le décompte (2) static int compter(rectangle r, Arbre a, boolean vertical) {... // suite if (min) total += compter(r, a.filsg,!vertical); if (agauche && adroite && enbas && enhaut) total++; if (max) total += compter(r, a.filsd,!vertical); return total; } Amphi 8 43
Application des arbres binaires. Plan Compter les arbres binaires Tétrarbres (quad trees) Problème des n corps Recherche dans un intervalle Recherche dans un nuage de points Recherche dans un arbre d intervalles Amphi 8 44
Recherche d'un intervalle coupant Problème : Chercher, dans un ensemble d intervalles, un élément qui rencontre un intervalle donné. Exemple : Dans une base d événements, chercher un événement qui a eu lieu durant une période donnée. Amphi 8 45
Type abstrait de données Données : Un ensemble d'intervalles fermés [g, d]. Opérations : ajouter un intervalle supprimer un intervalle chercher si l'ensemble contient un intervalle qui rencontre un intervalle donné v. Amphi 8 46
Structure de données Les intervalles sont stockés dans un arbre binaire de recherche. La clé utilisée pour comparer les nœuds est l'extrémité gauche des intervalles. Chaque noeud n contient une information supplémentaire, dmax, qui est le maximum des extrémités droites des intervalles du sous-arbre issu de n. Amphi 8 47
dmax = max des extrémités droites du sous-arbre. 8:9 23 16:21 30 Exemple [22,25] rencontre [11,14] non 25:30 30 5:8 10 15:23 23 17:19 20 26:26 26 0:3 6:10 3 10 19:20 20 Amphi 8 48
Utilisation de dmax (1) dmax = max des extrémités droites du sous-arbre. 8:9 23 16:21 30 Détermine dans quel sous-arbre chercher. 25:30 30 5:8 10 15:23 23 17:19 20 26:26 26 0:3 6:10 3 10 19:20 20 Amphi 8 49
Intervalle [g, d]. Règle 1 Si filsg.dmax < g, inutile de chercher dans le sous-arbre gauche. 8:9 23 16:21 30 Intervalle [22, 25] 25:30 30 5:8 10 15:23 23 17:19 20 26:26 26 0:3 6:10 3 10 dmax = 10 < 22 19:20 20 Amphi 8 50
Règle 2 (justifiée plus loin) Si filsg.dmax g, inutile de chercher dans le sous-arbre droit. 8:9 23 16:21 30 Intervalle [g, d]=[22, 25] 25:30 30 5:8 10 15:23 23 17:19 20 26:26 26 0:3 6:10 3 10 dmax = 23 > 22 dmax = 10 < 22 Intersection! 19:20 20 Amphi 8 51
Utilisation de dmax dmax = 23 > 11 dmax = 10 < 11 pas d'intersection! 8:9 23 16:21 30 Intervalle [11, 14] 25:30 30 5:8 10 15:23 23 17:19 20 26:26 26 0:3 6:10 3 10 19:20 20 Amphi 8 52
Justification Soit v = [g, d]. Soit [g', d'] un intervalle du sous-arbre gauche d'extrémité droite maximale. Par hypothèse, on a d' g. Supposons qu aucun intervalle du sous-arbre gauche ne rencontre [g, d]. Alors [g, d] [g', d'] =, d'où d < g'. Soit [g", d"] un intervalle du sous-arbre droit. On a g < d < g' < g" < d", donc [g, d] et [g", d"] sont disjoints. Donc aucun intervalle ne rencontre v! Amphi 8 53
Les classes Une classe d'intervalles Une classe d'arbres binaires de recherche avec un champ intervalle un champ dmax Il faut revoir le constructeur d'arbres pour le calcul de dmax! Amphi 8 54
Classe Intervalle class Intervalle { int min, max; Intervalle(int a, int b) { min = a; } } max = b; static boolean rencontre( Intervalle u, Intervalle v) { return u.min <= v.max && v.min <= u.max; } Amphi 8 55
Classe Arbre class Arbre { Intervalle u; int dmax; Arbre filsg, filsd; } Arbre(Intervalle v, Arbre g, Arbre d) { u = v; filsg = g; filsd = d; dmax = calculdmax(v, g, d); }... Amphi 8 56
Classe Arbre class Arbre {... static int calculdmax(intervalle v, Arbre g, Arbre d) { int m = v.max; if (g!= null && g.dmax > m) m = g.dmax; if (d!= null && d.dmax > m) m = d.dmax; return m; } } Amphi 8 57
Recherche static Arbre chercher(intervalle v, Arbre a) { if (a == null rencontre(v, a.u)) return a; if (a.filsg!= null) && a.filsg.dmax >= v.min) return chercher(v, a.filsg);//règle 2 else return chercher(v, a.filsd);//règle 1 } Amphi 8 58