Вы находитесь на странице: 1из 43

IN 101 - Cours 05

7 octobre 2011

prsent par e e

Matthieu Finiasz

Un probl`me concret e
Recherche de collisions

Le paradoxe des anniversaires dit que 365 l`ves sont susants ee (en moyenne) pour avoir une collision danniversaire, deux l`ves ayant leur anniversaire le mme jour. ee e Comment fait-on pour ecacement trouver ces paires dl`ves ? ee

Un probl`me concret e
Recherche de collisions

Le paradoxe des anniversaires dit que 365 l`ves sont susants ee (en moyenne) pour avoir une collision danniversaire, deux l`ves ayant leur anniversaire le mme jour. ee e Comment fait-on pour ecacement trouver ces paires dl`ves ? ee Mthode simple : e on remplit un tableau avec les n dates danniversaire, on compare chaque lment ` tous les autres du tableau ee a complexit en (n2). e Peut-on faire mieux ?

Un probl`me concret e
Recherche de collisions

Le paradoxe des anniversaires dit que 365 l`ves sont susants ee (en moyenne) pour avoir une collision danniversaire, deux l`ves ayant leur anniversaire le mme jour. ee e Comment fait-on pour ecacement trouver ces paires dl`ves ? ee Mthode simple : e on remplit un tableau avec les n dates danniversaire, on compare chaque lment ` tous les autres du tableau, ee a complexit en (n2). e Peut-on faire mieux ? OUI on trie le tableau, on le parcourt en regarant si 2 voisins sont gaux, e complexit en (n log n). e

Comment trier un tableau

Le tri
Description du probl`me e

On se donne un tableau de n lments (des entiers par exemple) et ee une relation dordre totale . on eectue un tri par comparaison, utilisant uniquement la complexit est le nombre de comparaisons. e ( 2) Les algorithmes lmentaires ont une complexit en n . ee e Les meilleurs algorithmes ont une complexit en (n log(n)). e

En autorisant plus que des comparaisons, on peut parfois faire (n).

Complexit variable e
Quelques dnitions e

Complexit dans le pire cas e Temps de calcul dans le pire cas pour les entres de taille n xe : e e T (n) = max T (x).
{x,|x |=n}

Complexit moyenne e Temps de calcul moyen sur toutes les entres de taille n xe : e e Tm (n) = pn (x)T (x).
x,|x |=n

(pn ) est une distribution de probabilit sur les entres de taille n. e e

Tri par insertion


Si a marche pour n, a marche pour n + 1 c c

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

void insertion_sort(int* tab, int n) { int i,j,tmp; for (i=1; i<n; i++) { tmp = tab[i]; j = i-1; while ((j >= 0) && (tab[j] > tmp)) { tab[j+1] = tab[j]; j--; } tab[j+1] = tmp; } }

Llment i est rang parmi les i 1 premiers lments (dj` tris) : ee e ee ea e i insrer un lment cote au pire i en moyenne 2 , e e e ( )u complexit en n2 dans(le pire cas (tableau inversement tri), e e ) complexit moyenne en n2 aussi. e

Tri ` bulles a Lide est de faire remonter les grands lments ` la n du tableau e ee a on parcourt le tableau en comparant llment i au i + 1 et on ee les inverse si ncessaire, e ` la n du parcours, le dernier lment est le plus grand, a ee apr`s i parcours les i plus grands lments sont ` la n. e ee a on fait n 1 parcours et la tableau est tri. e Complexit : on eectue (n) parcours comportant (n) compae raisons ` chaque fois, a ( 2) le tri ` bulles a une complexit de n dans le pire cas et en a e moyenne. Pour amliorer un peu les performances, on arrte le tri d`s que e e e lun des parcours ninverse aucun lments. ee Ce tri ne fait que (n) comparaisons sur un tableau dj` tri. ea e

Tri fusion
Si a marche pour n , a marche pour n c c 2

Insrer un lments dans un tableau tri cote (n), e ee e u fusionner deux tableaux de taille n cote aussi (n). u 2
p (p+r)/2 r-1 1 5 4 9 7 3 6 2 1 5 4 9 1 5 1 5 4 9 4 9 7 3 6 2 7 3 7 3 6 2 6 2

On cherche ` rduire le probl`me : a e e on coupe le tableau en deux, on trie chaque moiti, e on fusionne. Le cot total est celui des fusions : u chaque fusion cote (r p), u le cot total est (n log(n)), u dans le pire cas et en moyenne.

1 5

4 9

3 7

2 6

1 4 5 9

2 3 6 7

1 2 3 4 5 6 7 9

Tri fusion
Fusion des sous-tableaux

On commence par recopier dos ` dos les 2 tableaux (cot (n)), a u

1 4 5 9

2 3 6 7

1 4 5 9 7 6 3 2

puis on parcourt par les deux bouts en avanant du plus petit ct c oe ` chaque fois (cot (n) aussi). a u

4 5 9 7 6 i j 5 9 7 6 i j

1 2 3

1 2 3 4

Tri rapide
Quicksort

Tri rcursif bas sur un partitionnement : e e on choisit un pivot, on permute les lments du tableau ee les petits au dbut, puis le pivot, puis les grands, e on trie les petits entre eux et les grands entre eux.
1 2 3 4 5 6 7

void quick_sort(int* tab, int p, int r) { if (r-p > 1) { int q = partition(tab,p,r); quick_sort(tab,p,q); quick_sort(tab,q+1,r); } }

Tr`s rapide, peut tre fait en place :) e e ( 2 complexit dans le pire cas n , e complexit en moyenne (n log(n)). e

La fonction partition eectue r p 1 comparaisons.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

int partition(int* tab, int p, int r) { int x = tab[p]; int q = p; int i,tmp; for (i=p+1; i<r; i++) { if (tab[i] <= x) { q++; tmp = tab[q]; tab[q] = tab[i]; tab[i] = tmp; } } tmp = tab[q]; tab[q] = tab[p]; tab[p] = tmp; return q; }

Complexits compares e e
Asymptotiquement

Algorithme Tri par insertion Tri ` bulles a Tri rapide Tri fusion

Cas le pire En moyenne ( 2) ( 2) n n ( 2) n (n log(n)) (n log(n)) (n log(n))

Complexits compares e e
En pratique

En moyenne

Tableau inversement tri

temps

n Tableau tri

temps

Tri rapide Tri par insertion Tri fusion

temps

Application
Lalgorithme quickselect

Pour trouver la mdiane (ou le k-i`me lment) dun tableau : e e ee on peut trier le tableau et prendre llment n , ee 2 cote (n log n). u mais cela nest pas ncessaire... e

On sinspire du tri rapide : on conserve la ligne : int q = partition(tab,p,r); au lieu de 2 appels rcursifs, on nen fait quun e selon que q < n ou q > n , 2 2 on ne fait quune partie du tri, le minimum ncessaire, e la complexit moyenne est n + n + n + n + ... = 2n = (n). e 2 4 8

Complexit minimale dun e algorithme de tri

Complexit minimal dun algorithme de tri e


Tris par comparaison

Un tri par comparaison prend en entre n lments e ee ne fait que des comparaisons {1,4,3} est identique ` {2,4,3} a n! entres possibles, selon lordre des lments. e ee Un algorithme de tri par comparaison fait une suite de comparaison, puis donne une permutation qui remet les lments en ordre ee se comporte diremment pour chacune des n! entres possibles. e e Un tel tri peut se reprsenter par un arbre binaire : e chaque nud est une comparaison en fonction du rsultat on descend dans le ls gauche ou droit e chaque feuille correspond ` une permutation a chaque entre aboutit ` une feuille dirente. e a e

Complexit minimal dun algorithme de tri e


Exemple pour n = 3

a1:a2 < a2:a3 < 1,2,3 < 1,3,2 > a1:a3 > 2,3,1 2,1,3 < 3,1,2 < > a1:a3 > a2:a3 > 3,2,1

Complexit minimal dun algorithme de tri e


Exemple pour n = 3

a1:a2 < a2:a3 < 1,2,3 < 1,3,2 > a1:a3 > 2,3,1 2,1,3 < 3,1,2 < > a1:a3 > a2:a3 > 3,2,1

Nombre de comparaison = longueur de la branche cet arbre reprsente un algorithme qui trie en 3 comparaisons. e

Complexit minimale dun algorithme de tri e


(n log n), pas mieux

Un arbre de hauteur moyenne h contient au plus 2h feuilles 2h nombre de feuilles = n! ( nn ) en

h log(n!) > log

= n log n n log e

h est aussi le nombre moyen de comparaisons pour des entres quidistribues e e e la complexit moyenne dun tri est (n log n). e pour nimporte quelles entres e la complexit dans le pire cas est (n log n). e

Rcursivit e e

Algorithme rcursif e
Un concept utile

Un algorithme rcursif est un algorithme dni en rfrence ` e e ee a lui mme, et qui comprend une condition de terminaison. e Exemples : suite de Fibonacci, tri fusion, tri rapide... souvent faciles ` crire et ` comprendre ae a cest le compilateur qui fait le travail tr`s dirent dune fonction normale ! e e Permettent dutiliser une approche diviser pour rgner : e on divise le probl`me en sous-probl`mes e e on traite les sous-probl`mes (rcursivement ou directement) e e on recombine les rsultats. e

Les tours de Hano On cherche ` dplacer n disques de la tour 1 ` la tour 3 a e a il est interdit de poser un disque sur un plus petit que lui on dplace un seul disque ` la fois. e a

Les tours de Hano On dplace rcursivement n 1 disques vers la tour 2. e e

Les tours de Hano Puis on dplace le grand disque ` sa place. e a Cette tape est ncessaire dans tout solution. e e

Les tours de Hano On redplace rcursivement les n 1 petits disques vers la tour 3. e e

Les tours de Hano Et voila ! La magie de la rcursion a encore une fois opre... e ee on dcrit en quelques tapes un algorithme exponentiel en n. e e

Les tours de Hano


Le code C de lalgorithme

Cet algorithme ache les oprations ` eectuer : e a

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

void Hanoi(int n, int i, int j) { int intermediate = 6-(i+j); if (n > 0) { Hanoi(n-1,i,intermediate); printf("Mouvement de %d vers %d\n",i,j); Hanoi(n-1,intermediate,j); } } int main(int argc, char* argv[]) { Hanoi(atoi(argv[1]),1,3); }

Les tours de Hanoi


Complexit e

T (n) le nombre de mouvements ncessaire pour dplacer n disques : e e T (0) = 0 et T (1) = 1, T (n) = 1 + 2 T (n 1). On obtient : T (n) = 2n 1 = (2n ). Ltape de mouvement du grand disque est ncessaire e e cette complexit est intrins`que au probl`me. e e e La complexit spatiale est (n) e on ne stocke rien, mais on a n appels rcursifs imbriqus. e e

Pour dplacer 50 disques, ` 1 disque par seconde, il faut environ 35 e a millions dannes. e

Complexit dalgorithmes e rcursifs e

Tri fusion Calculer la complexit T (n) en nombre de comparaisons : e T (n) = D(n) + R(n) + C (n).

D(n) : cot pour diviser le probl`me en sous-probl`mes. D(n) = 0 u e e R(n) : cot pour rsoudre les sous-probl`mes. Ici, deux sousu e e probl`mes de taille n , donc R(n) = 2 T ( n ). e 2 2 C (n) : cot pour combiner les rsultats. Ici, une fusion : C (n) = n. u e n 2, T (n) = 2 T (n ) 2 +n

Une telle quation admet comme solution T (n) = (n log n). e

Tri rapide

1 2 3 4 5 6 7 8

void quick_sort(int* tab, int p, int r) { int q; if (r-p > 1) { q = partition(tab,p,r); quick_sort(tab,p,q); quick_sort(tab,q+1,r); } }

partition(tab, p, r) ncessite r p 1 comparaisons, e on calcule la complexit de quick sort comme prcdemment. e e e

Tri rapide Pour une entre de taille n : e Division en deux sous-probl`mes de taille q 1 et n q, cot de e u partition : D(n) = n 1. Rsolution des sous-probl`mes : cot R(n) variable selon la valeur e e u de q. Combinaison des rsultats : cot C (n) = 0. e u 2 T (n) meilleur cas 2 n 1 cas moyen T (n) = n 1 + q=1 T (q 1) + T (n q) n T (n 1) pire cas On trouve les solutions : T (n) = (n log n) (meilleur cas et cas moyen), ( 2) T (n) = n (pire cas).

Fibonacci rcursif e
Complexit exacte e

1 2 3 4 5 6

unsigned int fibo1(unsigned int n) { if (n < 2) { return n; } return fibo1(n-1) + fibo1(n-2); }

Si T (n) est la complexit du calcul du n-i`me nombre : e e T (n) = T (n 1) + T (n 2) + 1


R(n) C (n)

on fait un changement de variable S(n) = T (n) + 1 qui donne S(n) = S(n 1) + S(n 2) et donc S(n) = (n ). Comme annonc prcdemment T (n) = (n ). e e e

Les dessous de la rcursivit e e

Compilation dune fonction rcursive e Le code produit par un compilateur est une suite dinstruction avec des sauts, cest tout. Un if est un saut conditionnel : soit on excute linstruction suivante, soit on fait un saut un peu e plus loin.
execution

if

code du then si faux

code du else

suite du code

Compilation dune fonction rcursive e Le code produit par un compilateur est une suite dinstruction avec des sauts, cest tout. Un appel ` une fonction peut-tre trait de deux faons : a e e c soit on copie le code de la fonction (cest de linline),
execution appel de f inline du code de f suite du code

soit on fait un saut vers le code de la fonction comment savoir o` revenir ? u

execution appel de f suite du code

?
code de f

Compilation dune fonction rcursive e Le code produit par un compilateur est une suite dinstruction avec des sauts, cest tout. Un appel ` une fonction peut-tre trait de deux faons : a e e c soit on copie le code de la fonction (cest de linline),
execution appel de f inline du code de f suite du code

soit on fait un saut vers le code de la fonction on utilise une pile dadresses de retour.
pile des appels

0x88856234 execution appel de f stockage dans la pile suite du code

code de f

Compilation dune fonction rcursive e Le code produit par un compilateur est une suite dinstruction avec des sauts, cest tout. Une fonction rcursive ajoute successivement les adresses de retour e dans la pile : n appels imbriqus ont une complexit mmoire en (n). e e e

Autres remarques : un appel ` une fonction cote cher a u compromis entre inline/taille du code et temps dexcution, e certains vieux langages ne g`rent pas les fonctions rcursives : e e si on fait toujours de linline, les fonctions non rcursives sont e beaucoup plus simples ` compiler que les rcursives. a e

La rcursion terminale e
En anglais : tail recursion

La recursion terminale est un cas particulier de rcursion : e lappel rcursif est la derni`re commande excute, e e e e la valeur de retour de la fonction est la mme que celle retourne e e par lappel rcursif, e marche aussi sil ny a pas de valeur de retour. Il est alors possible de convertir la fonction rcursive en boucle : e un appel de fonction est toujours lourd (criture dans la pile...) e la rcursion terminale permet dtre plus ecace. e e Avec gcc, la rcursion terminale est prise en compte quand on e utilise loption doptimisation -O2 (ou -O3).

Rcursion terminale e
Exemple de lalgorithme dEuclide

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

int euclide(int x, int y) { if (y == 0) { return x; } else { return euclide(y,x % y); } } int euclide_iter(int x, int y) { int tmp1,tmp2; while (!(y == 0)) { tmp1 = y; tmp2 = x % y; x = tmp1; y = tmp2; } return x; }

Ce quil faut retenir de ce cours Il existe beaucoup dalgorithmes dirents pour trier un tableau : e les plus basics cotent (n2), u tri par insertion, tri ` bulles, tri cocktail... a les meilleurs cotent (n log n), u tri fusion, tri rapide, tri par tas, tri par arbre...

La rcursivit permet de dcrire facilement certains algorithmes : e e e la complexit dun algorithme rcursif est plus dicile ` calculer, e e a formules pour les algorithmes diviser pour rgner (cf. poly) e le compilation dune fonction rcursive est plus complique e e programme un peu plus lent dans certains cas.

Вам также может понравиться