Programmation avancée Chapitre 1 : Complexité et les ABR (arbres binaires de recherche) 1 1 IFSIC Université de Rennes-1 M2Crypto, octobre 2011
Plan du cours 1 2 3 4 5 6 7 8 9 10
Algorithmes Définition Algorithme : spécification bien définie d un schéma de calcul sous forme d une suite (finie) des opérations élémentaires obéissant à un enchaînement déterminé décrit par des spécifications traduit par un programme dans un langage informatique devant être exécuté sur une machine (éventuellement) sur un jeu de données
Objectifs : quantifier le temps d exécution la place mémoire nécessaire pour exécuter le programme. On s intéresse donc au temps d exécution et à la place mémoire de stockage des instructions et des données du programme et de manipulation des données. But : comparer des rithmes.
Résumé sur une machine donnée : On souhaite pouvoir dire l A, implémenté par le programme P, sur l ordinateur O, exécute sur les données D utilise k secondes de calcul et j bits de mémoire. Temps : nombre de cycles machine lors de l exécution du programme en comptant le nombre d opérations effectuées et le temps pour chaque opération. Place mémoire : nombre de mots mémoire.
Résultats plus généraux, indépendants de la machine, du langage de programmation, des compilateurs,..., liés à la machine donnée. la machine, le langage, A 1 est meilleur que A 2 pour des données de grande taille (à partir de telle taille). ou bien A 1 est optimal (en nombre de opérations) pour résoudre ce problème.
Choix des mesures : recherche des opérations fondamentales tq le temps d exécution soit toujours proportionnel au nombre de ces opérations. Donc donne une mesure simplifiée du temps d exécution. Exemples d opérations fondamentales : recherche d un élément dans une liste : nombre de comparaisons entre 2 éléments recherche d un élément sur un disque ; nombre d accès à la mémoire secondaire tri interne d une liste d éléments : nombre de comparaisons entre 2 élts + nombre de déplacement d élts multiplication de matrices : nombre de * et de +
Choix des mesures : recherche des opérations fondamentales tq le temps d exécution soit toujours proportionnel au nombre de ces opérations. Donc donne une mesure simplifiée du temps d exécution. Exemples d opérations fondamentales : recherche d un élément dans une liste : nombre de comparaisons entre 2 éléments recherche d un élément sur un disque ; nombre d accès à la mémoire secondaire tri interne d une liste d éléments : nombre de comparaisons entre 2 élts + nombre de déplacement d élts multiplication de matrices : nombre de * et de +
Soit un A pour résoudre un problème P. Peut-on trouver un B meilleur que A ou A est-il optimal pour ce problème P? Parfois on ne connaît qu un ordre de grandeur de la complexité optimale de la classe de problèmes résolvant P. Il est établi que la résolution de problème de multiplication de 2 matrices n n demande au moins n? multiplications. un de n lg 7 (Strassen) et en n 2,376. Mieux?
L approche Séparer le problème en plusieurs sous problèmes similaires au problème initial, mais de taille moindre, résoudre les sous problèmes de façon récursive, puis combiner ces solutions pour retrouver une solution au problème initial. Diviser le problème en un certain nombre de sous problèmes. Régner sur les sous problèmes en les résolvant récursivement. Par ailleurs, si la taille d un sous problème est assez réduite, on peut le résoudre directement. Combiner les solutions aux sous problèmes en une solution complète pour le problème initial.
Tri fusion Diviser : Diviser la séquence de n éléments à trier en 2 sous séquences de n/2 éléments. Régner : Trier les 2 sous séquences récursivement à l aide du tri fusion. Combiner : Fusionner les 2 sous séquences triées pour produire la réponse triée. void mergesort(item[] a, int l, int r) { if (l < r) { int m = (l+r)/2; mergesort(a,l,m); mergesort(a,m+1,r); merge(a,l,m,r); } }
du tri fusion Diviser : Se fait en temps constant. Régner : 2 pb de taille n/2, donc 2T(n/2). Combiner : merge prend un temps Θ(n). Donc { Θ(1), si n = 1 T(n) = 2T(n/2)+Θ(n), si n > 1 Mais comment trouver la solution sous forme close?
Compromis temps mémoire L rithme de chiffrement DES a des clés de 56 bits. La recheche exhaustive nécessite donc 2 k 1 opérations de chiffrement en moyenne. Considérons maintenant le chiffrement double : le texte chiffré est chiffré une nouvelle fois avec une autre clé, indépendante de la première. Naïvement, la recherche exhaustive nécessiterait 2 2k 1 opérations en moyenne.
Attaque par le milieu (meet in the middle) Une attaque dite par le milieu (meet-in-the-middle) réduit le temps à 2 k opérations, au prix d espace mémoire considérable 2 k. On effectue des chiffrements du texte clair par toutes les clés possibles et on les range dans une table. Puis on effectue un déchiffrement du texte chiffré par toutes les clés possibles. Enfin on compare ensuite les deux listes pour trouver des textes identiques. Une deuxième paire texte clair/texte chiffré permet d éliminer les paires de clés incorrectes. Donc, le chiffrement double n est jamais utilisé.
Attaque d anniversaires sur les fonctions de hachage Une fonction de hachage cryptographique envoie des mots binaires de taille arbitraire sur des mots binaires de taille fixe n. Cela sert par exemple dans la signature électronique. Mais il faut que le signataire ne puissent pas prétendre à avoir signé un autre message. Donc, il faut qu il soit infaisable de trouver 2 messages avec la même valeur de hachage. Combien de tests faut-il effectuer (en prenant 2 messages au hasard à chaque fois) pour trouver une collision?
Définition d un ABR Définition Un arbre binaire de recherche (ABR) est un arbre binaire t.q. les n nœuds de l arbre représentent les n éléments de l ensemble, et pour tout nœud n tous les nœuds du sous arbre gauche, s il en existe, ont une valeur inférieure ou égale à celle de n tous les nœuds du sous-arbre droit, s il en existe, ont une valeur(strictement)supérieure ou égale à celle de n Une lecture symétrique donne les éléments dans l ordre croissant. Les sous arbres gauche et droit sont aussi des ABR.
Définition d un ABR Définition Un arbre binaire de recherche (ABR) est un arbre binaire t.q. les n nœuds de l arbre représentent les n éléments de l ensemble, et pour tout nœud n tous les nœuds du sous arbre gauche, s il en existe, ont une valeur inférieure ou égale à celle de n tous les nœuds du sous-arbre droit, s il en existe, ont une valeur(strictement)supérieure ou égale à celle de n Une lecture symétrique donne les éléments dans l ordre croissant. Les sous arbres gauche et droit sont aussi des ABR.
Définition d un ABR On considère l ABR repéré par un pointeur sur sa. (Si le sous arbre dans lequel on cherche es vide, alors échec.) type abr = noeud*; struct noeud { item val; abr g,d; }
dans un ABR Principe de la recherche dans un ABR : comparer l élément cherché x à la valeur de la de l arbre. si x = val(a), alors succès si x > val(a), alors recherche dans le sous arbre droite d(a) si x < val(a), alors recherche dans le sous arbre gauche d(a)
Adjonction aux On compare l élément à la pour savoir si l ajout sera dans le sous arbre gauche ou droit et on rappelle la procédure récursivement. Le dernier appel récursif se fait sur un arbre vide et on a alors à cette place le nœud contenant l élément à ajouter.
Adjonction à la On peut ajouter un élément à n importe quel niveau, en particulier à la. L adjonction à la peut présenter un intérêt si on désire privilégier l accès au(x) dernier(s) élément(s). 2 étapes : on coupe l arbre A en A 1 et A 2 t.q. A 1 contienne les éléments inférieurs à x et A 2 les éléments supérieurs, et puis on construit l arbre. Remarque : on ne visite que les nœuds situés sur le chemin suivi lors de la recherche de X à partir de la.
Adjonction à la On peut ajouter un élément à n importe quel niveau, en particulier à la. L adjonction à la peut présenter un intérêt si on désire privilégier l accès au(x) dernier(s) élément(s). 2 étapes : on coupe l arbre A en A 1 et A 2 t.q. A 1 contienne les éléments inférieurs à x et A 2 les éléments supérieurs, et puis on construit l arbre. Remarque : on ne visite que les nœuds situés sur le chemin suivi lors de la recherche de X à partir de la.
Adjonction à la On peut ajouter un élément à n importe quel niveau, en particulier à la. L adjonction à la peut présenter un intérêt si on désire privilégier l accès au(x) dernier(s) élément(s). 2 étapes : on coupe l arbre A en A 1 et A 2 t.q. A 1 contienne les éléments inférieurs à x et A 2 les éléments supérieurs, et puis on construit l arbre. Remarque : on ne visite que les nœuds situés sur le chemin suivi lors de la recherche de X à partir de la.
Adjonction à la On peut ajouter un élément à n importe quel niveau, en particulier à la. L adjonction à la peut présenter un intérêt si on désire privilégier l accès au(x) dernier(s) élément(s). 2 étapes : on coupe l arbre A en A 1 et A 2 t.q. A 1 contienne les éléments inférieurs à x et A 2 les éléments supérieurs, et puis on construit l arbre. Remarque : on ne visite que les nœuds situés sur le chemin suivi lors de la recherche de X à partir de la.
Adjonction à la void coupure(item x, abr A, abr& G, abr& D) { abr X, Y; if (A == null) then { G = null; D = null; } else if x >= val(a) then { coupure(x, d(a), X, Y); d(a) = X; G = A; D = Y; } else { coupure(x, g(a), X, Y); g(a) = Y; G = X; D = A; } }
Adjonction à la void coupure(item x, abr A, abr& G, abr& D) { if (A == null) then { G = null; D = null; } else if (x >= val(a)) then { G = A; coupure(x, d(a), d(g), D); } else { D = A; coupure(x, g(a), G, g(d)); } }
Adjonction à la void ajout_(item x, abr A) { abr R = new abr(); val(r) = x; coupure(x, A, g(r), d(r)); A = R; }
dans un ABR suppression d une feuille : cas simple suppression d un nœud n ayant qu un fils : remettre le fils à la place suppression d un nœud ayant 2 fils : il faut chercher l élément immédiatement supérieur ou inférieur (SUPMIN ou SUPMAX), l échanger avec le nœud à supprimer, et supprimer le nœud SUPMIN ou SUPMAX.
recherche/adjonction/suppression Dans le cas d un succès = 2 * profondeur(x) + 1 Dans le cas d un échec = 2 * (profondeur(y) + 1) : profondeur(y) + 1 : profondeur(y) + 1 : même que la recherche de x dans l arbre + complexité de supmax
Profondeur d un nœud dans un ABR Profondeur des arbres : entre 0 et n-1 (arbres dégénérés). Donc θ(n), la même que pour les listes. Profondeur des arbres bien équilibrés : θ(log n).
Profondeur dans les ABR aléatoires On considère que toutes les permutations des valeurs sont équiprobables. Exemple : n = 3. On peut montrer que la profondeur moyenne dans un ABR est de l ordre de log 2 (n). Pour les nœuds internes PI(n) = 1(1+ 1 n )H n 4. Pour les nœuds externes PE(n) = 2H n+1 2, où H n = n i=1 1 n.
Complexité dans les ABR max rech+ (n) = max supp (n) = 2n 1 max rech (n) = 2n max ajout (n) = n moy rech+ (n) = moy supp (n) = θ(log n) = 2PI n + 1 moy rech (n) = 2PE n moy ajout (n) = PE n Conclusion : en moyenne θ(log n) en pire θ(n)
Complexité dans les ABR max rech+ (n) = max supp (n) = 2n 1 max rech (n) = 2n max ajout (n) = n moy rech+ (n) = moy supp (n) = θ(log n) = 2PI n + 1 moy rech (n) = 2PE n moy ajout (n) = PE n Conclusion : en moyenne θ(log n) en pire θ(n)
Complexité dans les ABR max rech+ (n) = max supp (n) = 2n 1 max rech (n) = 2n max ajout (n) = n moy rech+ (n) = moy supp (n) = θ(log n) = 2PI n + 1 moy rech (n) = 2PE n moy ajout (n) = PE n Conclusion : en moyenne θ(log n) en pire θ(n)