<?xml version="1.0" encoding="iso-8859-1" ?>
<rss version="0.92">
	<channel>
    <title>ordregrandeur</title>
    <link>http://ordregrandeur.blog2geek.com</link>
    <description>Blog specialise; geek et geek attitude.</description>
    <language>fr-FR</language><item>
        <title>Ordre de grandeurs et notation theta</title>
        <link>http://ordregrandeur.blog2geek.com/ordre-de-grandeurs-et-notation-theta-707.html</link>
        <description>
ATTENTION: La mise en page de ce billet pose problème, veuillez vous référer aux liens donnés dans le billet précédent pour consulter l&amp;#39;article sous une meilleure forme.

Complexité structurelle: ordre de grandeur et notation 

Julien BIBOLLET, Dimitri BISOO, Benjamin GANDON


 

Résumé:
Lorsque l&amp;#39;on doit choisir parmis plusieurs algorithmes celui qui est le plus performant, on a besoin d&amp;#39;exprimer une approximation de sa complexité ou de son temps d&amp;#39;exécution. Pour ce faire, on utilise la notation  d&amp;#39;une fonction de base. Cet article a pour but d&amp;#39;introduire quelques unes de ces fonctions de base, ainsi que de présenter la notation .

 


 


Table des matières

	Ordre de grandeurs
	
		Ordres de grandeurs courants
		
		Tableaux comparatifs
		
	
	
	
	Notation 
	
		Définitions mathématique
		
		Utilisation
		
	
	
	
	Exemple d&amp;#39;application: QuickSort
	
	Bibliographie
	


 


Ordre de grandeurs
En général, un algorithme possède un paramètre  qui affecte de manière significative son temps d&amp;#39;exécution. Ce paramètre est proportionnel à la taille de l&amp;#39;ensemble de données à traiter (taille de la chaîne de caractères, nombre de noeuds de l&amp;#39;arbre, nombre d&amp;#39;éléments dans la liste, ...). L&amp;#39;objectif est d&amp;#39;estimer le temps d&amp;#39;exécution de l&amp;#39;algorithme en fonction de ce paramètre, en le ramenant à l&amp;#39;une des fonctions de base qui sont définies dans la section suivante.

 


Ordres de grandeurs courants


La majorité des instructions n&amp;#39;est exécutée qu&amp;#39;une seule fois, ou un petit nombre de fois; le temps d&amp;#39;exécution du programme est donc considéré constant.


Un temps d&amp;#39;exécution logarithmique signifie que l&amp;#39;algorithme va aller très légèrement plus lentement à mesure que  augmente. Typiquement, les programmes qui résolvent de grands problèmes en les divisant en de plus petits de complexité moindre font parties de cette catégorie. La base du logarithme change simplement quelque peu la constante: par exemple, pour  1000$&quot; width=&quot;72&quot; height=&quot;14&quot; align=&quot;bottom&quot; /&gt;,  3$&quot; width=&quot;81&quot; height=&quot;32&quot; align=&quot;middle&quot; /&gt; si la base est  et  si la base est . A chaque fois que  double de valeur,  augmente d&amp;#39;une constante, mais il ne double pas tant que  n&amp;#39;augmente pas jusqu&amp;#39;à .


Le temps d&amp;#39;exécution est linéaire lorsque quelques opérations sont appliquées à chaque élément en entrée. Le temps d&amp;#39;exécution double chaque fois que  double. Un temps de  est optimal pour un algorithme ayant  entrées à traiter, ou  sorties à produire.


Cette classe est typique des programmes algorithmes qui résolvent un problème en le découpant en de plus petits, en les traitant indépendamment puis en combinant ensuite les solutions. Quand  double,  vaut légèrement plus du double, mais tout en restant largement acceptable.


Un temps d&amp;#39;exécution quadratique est surtout adapté à la résolution de petits problèmes et traite tous les couples d&amp;#39;éléments (d&amp;#39;où le 
 N \\times N$&quot; width=&quot;96&quot; height=&quot;34&quot; align=&quot;middle&quot; /&gt;). Dans un tel cas, quand  double, le temps d&amp;#39;exécution est multiplié par 4.


Similairement au précédent, un temps d&amp;#39;exécution polynomiale ou géométrique va traiter tous les -uplets d&amp;#39;éléments. Quand  double, le temps d&amp;#39;exécution se voit multiplier par , ce qui limite l&amp;#39;utilisation de tels algorithmes à de très petits problèmes.


Un algorithme en temps d&amp;#39;exécution exponentiel est quasiment inutilisable dans la pratique: quand  double, le temps d&amp;#39;exécution est élevé au carré.


Un algorithme en temps d&amp;#39;exécution factoriel n&amp;#39;est même pas envisageable, tant le temps d&amp;#39;exécution va grandir pour chaque unité de  supplémentaire.

 

.
Dans la pratique, le temps d&amp;#39;exécution d&amp;#39;un algorithme n&amp;#39;est pas rigoureusement exact à l&amp;#39;une des fonctions précédentes, mais plutôt à une constante multiplée par l&amp;#39;une de ces fonctions plus quelques petits termes. Les valeurs de cette constante et de ces termes supplémentaires dépendent des détails de l&amp;#39;implémentation et nécessitent une analyse plus précise de l&amp;#39;algorithme pour être déterminés. Pour faire simple, la constante est très liée au nombre d&amp;#39;instructions dans la boucle interne de l&amp;#39;algorithme. Toutefois, dans la plupart des cas, on dit simplement d&amp;#39;un algorithme que son temps d&amp;#39;exécution est logarithmique, linéaire, quadratique, ...via l&amp;#39;utilisation de la notation  comme nous le verrons dans la section suivante.

 


Tableaux comparatifs


 


Tableau:
Résultats de quelques fonctions utilisées dans l&amp;#39;analyse des algorithmes.






3
10
33
110
32
100
7
100
664
4 414
1 000
10 000
10
1 000
9 966
99 317
31 623
1 000 000
13
10 000
132 877
1 765 633
1 000 000
100 000 000
17
100 000
1 660 964
27 588 016
31 622 777
10 000 000 000
20
1 000 000
19 931 569
397 267 426
1 000 000 000
1 000 000 000 000

 


En étudiant le tableau 1, on peut, par exemple, se rendre compte de la grande différence qu&amp;#39;il existe entre  et . Par ailleurs, on remarque que pour de petites valeurs de ,  se comporte mieux que , mais la situation s&amp;#39;inverse dès lors que  est assez grand. De ce fait, l&amp;#39;analyse précise d&amp;#39;un algorithme nécessite également de savoir dans quelles conditions il sera utilisé.

 


 


Tableau:
Temps de résolution en fonction de la complexité.
Opérations
Taille du problème de 1 million
Taille du problème de 1 milliard
par seconde







Secondes
Secondes
Semaines
Heures
Heures
Jamais

Immédiat
Immédiat
Heures
Secondes
Secondes
Décennies

Immédiat
Immédiat
Secondes
Immédiat
Immédiat
Semaines

 


Le tableau 2 montre le temps moyen de résolution d&amp;#39;un problème avec 1 million et 1 milliard d&amp;#39;éléments, en fonction de sa complexité et de la capacité de calcul de la machine. Ce tableau permet de se rendre compte qu&amp;#39;un algorithme rapide sera à même de résoudre un gros problème, même sur une machine lente, mais que l&amp;#39;inverse n&amp;#39;est pas vrai: une machine, même très performante, ne sera pas en mesure de résoudre un problème avec un algorithme en  par exemple.

 


Notation 
En théorie de la complexité, on s&amp;#39;intéresse à l&amp;#39;équivalence asymptotique de fonctions positives à variables entières. Pour ce faire, on utilise la notation .

 


Définitions mathématique
Avant de définir la notation , nous avons besoin de définir la notation . Cette dernière, aussi appelée symbole de Landau (du nom du mathématicien allemand qui l&amp;#39;introduisit), est le symbole utilisé en mathématique pour décrire la dominance asymptotique de fonctions. On utilise la lettre  car on parle de l&amp;#39;ordre de la fonction. Mathématiquement, on la définie comme suit:

 


Notation 
 O(g(x))$&quot; width=&quot;111&quot; height=&quot;32&quot; align=&quot;middle&quot; /&gt; quand 
 \\forall x &gt; N_0 \\mid f(x) \\mid \\leq C_0 \\mid g(x) \\mid$&quot; width=&quot;340&quot; height=&quot;32&quot; align=&quot;middle&quot; /&gt; (autrement dit, on est simplement en train de définir le fait que  ne croît pas plus vite que ).

 


Notation 
En théorie de la complexité, on va surtout utiliser l&amp;#39;équivalence asymptotique, notée  et définie par:

 et 
 avec 
 \\mid f(x) \\mid \\geq M \\mid g(x) \\mid \\forall x &gt; x_0$&quot; width=&quot;428&quot; height=&quot;32&quot; align=&quot;middle&quot; /&gt;.


 


Utilisation
On peut voir la notation  comme un artifice mathématique permettant de s&amp;#39;affranchir des détails lorsque l&amp;#39;on analyse des algorithmes.

Cette notation permet d&amp;#39;écrire, en toute rigueur mathématique, le comportement d&amp;#39;une fonction, ou, dans notre cas, la complexité approximée d&amp;#39;un algorithme. En effet, si l&amp;#39;on prend l&amp;#39;exemple d&amp;#39;un algorithme de complexité 
 3 \\times N^2 + 2 \\times N - 3$&quot; width=&quot;202&quot; height=&quot;34&quot; align=&quot;middle&quot; /&gt;, on l&amp;#39;associe à la classe . La notation  permet donc de s&amp;#39;affranchir des constantes (ce qui est fondé puisque l&amp;#39;on peut dire qu&amp;#39;elles dépendent de l&amp;#39;implémentation de l&amp;#39;algorithme) et des termes plus faibles (puisqu&amp;#39;ils sont &amp;#39;dominés&amp;#39;). Les constantes  et  de la définition de la notation  servent à masquer les détails d&amp;#39;implémentation.


Ainsi, en écrivant 
 3 \\times N^2 + 2 \\times N - 3 = \\theta(N^2)$&quot; width=&quot;265&quot; height=&quot;34&quot; align=&quot;middle&quot; /&gt;, on reste rigoureux au niveau mathématique (la notation  se chargeant de contenir les termes négligeables afin d&amp;#39;obtenir une égalité), et cela donne une approximation de la complexité de l&amp;#39;algorithme permettant de rapidement comparer différents algorithmes entre eux pour déterminer le plus performant.


 

.
Pour résumer, on peut dire que la notation  est utilisée dans trois buts:

	borner les erreurs faites lorsque l&amp;#39;on ignore les petits termes dans les formules mathématiques
	
	borner les erreurs faites lorsque l&amp;#39;on ignore des morceaux de l&amp;#39;algorithme qui influencent très peu le temps total dans le cadre de l&amp;#39;analyse en cours
	
	classer les algorithmes selon les bornes supérieures de leur temps total d&amp;#39;exécution
	


 


Exemple d&amp;#39;application: QuickSort
Nous allons expliquer comment calculer la complexité d&amp;#39;un algorithme à travers un exemple: l&amp;#39;algorithme de QuickSort.

 


Principe de QuickSort:
Le principe consiste à séparer l&amp;#39;ensemble des éléments en deux parties. Pour effectuer la séparation, une valeur pivot est choisie. Ensuite les deux ensembles sont séparés par rapport à la valeur du pivot : ceux qui sont plus petits vont à gauche et ceux qui sont plus grand vont à droite, le pivot étant intercalé entre les deux.






 


Problème:
Le problème de cet algorithme est la recherche du pivot. En effet, l&amp;#39;idéal consiste à prendre un pivot permettant de séparer les deux ensembles en deux parties de taille sensiblement égales. Dans la pratique, le pivot est le premier élément ou le dernier élément de l&amp;#39;ensemble à fractionner. En moyenne, les deux ensembles seront de taille sensiblement égale.

 


Complexité:
La complexité du tri rapide pour trier une liste de  éléments est égale à la complexité pour le tri de  et de  éléments ou . Soit 
 (avec  une constante). Dans le meilleur des cas, , soit . Dans ce cas, la complexité de l&amp;#39;algorithme est en 
. Cependant, dans le pire cas, c&amp;#39;est-à-dire dans le cas où la liste est déjà triée, la complexité tombe alors dans .  Pour contrer cet effet là, on effectue un mélange de la liste avant d&amp;#39;effectuer QuickSort (en s&amp;#39;assurant que la temps passé à effectuer ce mélange n&amp;#39;est pas trop important).

 


Bibliographie

 

1
Robert Sedgewick.

Algorithmes en C++.

Pearson Education, troisième edition, 2004.

 

2
wikipedia.

http://fr.wikipedia.org/wiki/Notation_O.

 


À propos de ce document...
Complexité structurelle: ordre de grandeur et notation 

This document was generated using the
LaTeX2HTML translator Version 2002-2-1 (1.71)


Copyright © 1993, 1994, 1995, 1996,
Nikos Drakos, 
Computer Based Learning Unit, University of Leeds.

Copyright © 1997, 1998, 1999,
Ross Moore, 
Mathematics Department, Macquarie University, Sydney.


The command line arguments were: 
latex2html complexite_structurelle.tex -dir website -split 0


The translation was initiated by  on 2007-05-17
</description>
		<pubDate>Thu, 17 May 2007 18:25:00 GMT</pubDate>
      </item><item>
        <title>Ordre de grandeur et notation theta: Résumé</title>
        <link>http://ordregrandeur.blog2geek.com/ordre-de-grandeur-et-notation-theta-resume-704.html</link>
        <description>Lorsque l&amp;#39;on doit choisir parmis plusieurs algorithmes celui qui est le
plus performant, on a besoin d&amp;#39;exprimer une approximation de sa
complexité ou de son temps d&amp;#39;exécution. Pour ce faire, on utilise la
notation 
d&amp;#39;une fonction de base. Cet article a pour but d&amp;#39;introduire quelques
unes de ces fonctions de base, ainsi que de présenter la notation .

** ** ** ** **


Le rapport complet est consultable  http://scia.homelinux.org/complexite_structurelle  ou téléchargeable ici. 
</description>
		<pubDate>Thu, 17 May 2007 17:21:00 GMT</pubDate>
      </item>		</channel>
</rss> 
