{"id":399,"date":"2021-09-09T11:15:58","date_gmt":"2021-09-09T11:15:58","guid":{"rendered":"https:\/\/www.louismarchand.me\/?page_id=399"},"modified":"2021-09-09T11:15:58","modified_gmt":"2021-09-09T11:15:58","slug":"objet-2-la-complexite-algorithmique","status":"publish","type":"page","link":"https:\/\/www.louismarchand.me\/index.php\/objet-2-la-complexite-algorithmique\/","title":{"rendered":"La complexit\u00e9 algorithmique"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>Avoir une bonne repr\u00e9sentation de la performance d&rsquo;un algorithme est un \u00e9l\u00e9ment important pour un programmeur et, malheureusement, \u00e9valuer cette performance est g\u00e9n\u00e9ralement tr\u00e8s difficile et peu intuitif. Il ne suffit pas de diminuer le nombre de lignes de code pour augmenter la performance. En fait, il arrive souvent que des algorithmes plus performants soient \u00e9galement plus gros et plus complexes \u00e0 comprendre.<\/p>\n<h2>Les bases<\/h2>\n<p>Par performance d&rsquo;un algorithme, on entend la balance entre la rapidit\u00e9 d&rsquo;ex\u00e9cution de l&rsquo;algorithme par rapport \u00e0 l&rsquo;espace m\u00e9moire utilis\u00e9.<\/p>\n<p>En effet, un algorithme bien con\u00e7u devra d\u00e9cider pourra stocker une grande quantit\u00e9 de valeurs en m\u00e9moire (ce que nous appelons une cache) afin d&rsquo;\u00e9viter de traiter ces valeurs, ce qui fait un algorithme plus rapide. Inversement, au lieu de stocker des valeurs en m\u00e9moire, il est souvent possible de les recalculer au besoin, ce qui augmente la performance m\u00e9moire, mais diminue la vitesse.<\/p>\n<p>Par contre, avant de balancer la performance m\u00e9moire et la vitesse d&rsquo;ex\u00e9cution d&rsquo;un algorithme, il faut s&rsquo;assurer que l&rsquo;algorithme est optimal. Le calcul permettant de mesurer la performance (particuli\u00e8rement la vitesse) d&rsquo;un algorithme est appel\u00e9 la complexit\u00e9 algorithmique.<\/p>\n<h2>La complexit\u00e9 algorithmique<\/h2>\n<p>La complexit\u00e9 algorithmique permet le calcul et la notation de la performance d&rsquo;un algorithme. En d&rsquo;autres mots, \u00e7a nous permet d&rsquo;avoir une mesure permettant de comparer la performance de diff\u00e9rents algorithmes.<\/p>\n<h3>La complexit\u00e9 d&rsquo;un probl\u00e8me<\/h3>\n<p>Un algorithme est une m\u00e9canique permettant de r\u00e9soudre un probl\u00e8me (peu importe le type de probl\u00e8me). Par exemple, il y a des algorithmes permettant de ressourdre les probl\u00e8mes: Trouver un \u00e9l\u00e9ment dans une structure (liste, arbre, etc.), calculer une moyenne, ressourdre un Rubiks cube, calculer le chemin le plus rapide pour partir de ma r\u00e9sidence jusqu&rsquo;\u00e0 mon travail, etc.<\/p>\n<p>On dit que tous les probl\u00e8mes ont une complexit\u00e9. C&rsquo;est-\u00e0-dire une performance optimale permettant de r\u00e9soudre le probl\u00e8me. Cette complexit\u00e9 est un id\u00e9al et n&rsquo;est pas toujours connue. L&rsquo;objectif d&rsquo;un programmeur est de trouver un algorithme qui a une complexit\u00e9 qui se rapproche le plus de la complexit\u00e9 du probl\u00e8me.<\/p>\n<h3>La complexit\u00e9 d&rsquo;un algorithme<\/h3>\n<p>Il est important de comprendre que, de base, ce qui augmente la complexit\u00e9 d&rsquo;un algorithme, c&rsquo;est les boucles de cet algorithme. Par exemple, l&rsquo;algorithme suivant (en Java):<\/p>\n<div class=\"highlight\">\n<pre><span class=\"kd\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">addition<\/span><span class=\"o\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">aValeur1<\/span><span class=\"o\">,<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">aValeur2<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"n\">aValeur1<\/span> <span class=\"o\">+<\/span> <span class=\"n\">aValeur2<\/span><span class=\"o\">;<\/span>\r\n<span class=\"o\">}<\/span>\r\n<\/pre>\n<\/div>\n<p>est plus performant que l&rsquo;algorithme suivant:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"kd\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">addition<\/span><span class=\"o\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">aValeur1<\/span><span class=\"o\">,<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">aValeur2<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\r\n    <span class=\"kt\">int<\/span> <span class=\"n\">lRetour<\/span> <span class=\"o\">=<\/span> <span class=\"n\">aValeur1<\/span><span class=\"o\">;<\/span>\r\n    <span class=\"k\">for<\/span> <span class=\"o\">(<\/span><span class=\"kt\">int<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"o\">;<\/span> <span class=\"n\">i<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">aValeur2<\/span><span class=\"o\">;<\/span> <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"n\">i<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span><span class=\"o\">){<\/span>\r\n        <span class=\"n\">lRetour<\/span> <span class=\"o\">=<\/span> <span class=\"n\">lRetour<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span><span class=\"o\">;<\/span>\r\n    <span class=\"o\">}<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"n\">lRetour<\/span><span class=\"o\">;<\/span>\r\n<span class=\"o\">}<\/span>\r\n<\/pre>\n<\/div>\n<h3>La notation O<\/h3>\n<p>On note la complexit\u00e9 d&rsquo;un algorithme avec la notation O(complexit\u00e9). Par exemple, un algorithme peut \u00eatre 0(1), O(n), O(log(n)), O(n^2), etc. Le \u00ab\u00a0n\u00a0\u00bb dans les notations repr\u00e9sente le nombre de valeurs \u00e0 traiter. Par exemple, dans les deux exemples pr\u00e9c\u00e9dents, le premier exemple (l\u2019addition avec une seule ligne de retour) est O(2) puisqu&rsquo;il doit faire une addition et une assignation, et le second exemple (l&rsquo;addition avec une boucle) est O(2*aValeur2 + 2), le \u00ab\u00a02*aValeur2\u00a0\u00bb correspondant \u00e0 l&rsquo;addition et l&rsquo;assignation dans la boucle et le \u00ab\u00a0+ 2\u00a0\u00bb correspondant aux 2 assignations \u00e0 l&rsquo;ext\u00e9rieur de la boucle.<\/p>\n<h3>Le principe d&rsquo;ordre de grandeur<\/h3>\n<p>Il est important de comprendre que ce qui nous int\u00e9resse dans la complexit\u00e9 algorithmique, c&rsquo;est l&rsquo;ordre de grandeur de cette complexit\u00e9. L&rsquo;ordre de grandeur se calcule toujours par rapport \u00e0 une variable. Ainsi, les multiplications de constante ne sont pas prises en compte. Par exemple, les ordres de complexit\u00e9 suivants sont tous \u00e9quivalents:<\/p>\n<pre>O(2) = O(1000000) = O(-345) = O(1)<\/pre>\n<pre>O(2*n) = O(1000000*n) = O(-543*n) = O(n)<\/pre>\n<pre>O(2*n\u00b2) = O(1000000*n\u00b2) = O(-923*n\u00b2) = O(n\u00b2)<\/pre>\n<pre>O(2*n\u00b3) = O(1000000*n\u00b3) = O(-923*n\u00b3) = O(n\u00b3)<\/pre>\n<pre>O(2*log(n)) = O(log(2*n)) = O(log(1000000*n)) = O(log(n))<\/pre>\n<p>Il est important de voir que les derniers \u00e9l\u00e9ments de chaque ligne d&rsquo;\u00e9galit\u00e9s est comment on note cet ordre de complexit\u00e9. Ainsi, dans les exemples pr\u00e9c\u00e9dents, le premier exemple (l\u2019addition avec une seule ligne de retour) doit \u00eatre not\u00e9 O(1) et non O(2) comme pr\u00e9cis\u00e9 plus haut.<\/p>\n<p>\u00c9galement, l&rsquo;ordre de grandeur de complexit\u00e9 algorithmique ignore les additions de polyn\u00f4me contenant des ind\u00e9termin\u00e9s identiques. Seul l&rsquo;ind\u00e9termin\u00e9 ayant le plus haut degr\u00e9 est gard\u00e9. Par exemple, voici des ordres de complexit\u00e9 qui sont \u00e9quivalents:<\/p>\n<pre>O(3n + 5) = O(n)<\/pre>\n<pre>O(3*n + 5*n\u00b2 + n + 1000) = O(n\u00b2 + log(n)) = O(n\u00b2)<\/pre>\n<pre>O(n*log(n) + log(n) + log(log(n))) = O(n*log(n))<\/pre>\n<p>Encore une fois, le dernier \u00e9l\u00e9ment des \u00e9galit\u00e9s repr\u00e9sente comment nous devrions noter les ordres algorithmiques.<\/p>\n<p>Ainsi, dans les exemples pr\u00e9c\u00e9dents, le second exemple (le addition avec une boucle pour calculer le r\u00e9sultat), doit \u00eatre not\u00e9 O(aValeur2) et non O(2* aValeur2 + 2) comme pr\u00e9cis\u00e9 plus haut.<\/p>\n<h3>Comment calculer l&rsquo;ordre de complexit\u00e9 d&rsquo;un algorithme<\/h3>\n<p>Les techniques de calcul d&rsquo;ordre de complexit\u00e9 algorithmique sont hors des notions \u00e0 voir dans ce cours. N\u00e9anmoins, je crois qu&rsquo;il est important d&rsquo;avoir une bonne compr\u00e9hension de ce qui cause les ordres de complexit\u00e9 classique.<\/p>\n<p>L&rsquo;ordre de complexit\u00e9 algorithmique correspond au nombre maximal de fois que seraient ex\u00e9cut\u00e9s des capteurs d&rsquo;ex\u00e9cution qui seraient plac\u00e9s entre chaque instruction de l&rsquo;algorithme. Par exemple, prenons l&rsquo;algorithme suivant:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"kd\">public<\/span> <span class=\"kt\">void<\/span> <span class=\"nf\">afficherInformations<\/span><span class=\"o\">()<\/span> <span class=\"o\">{<\/span>\r\n    <span class=\"n\">System<\/span><span class=\"o\">.<\/span><span class=\"na\">out<\/span><span class=\"o\">.<\/span><span class=\"na\">println<\/span><span class=\"o\">(<\/span><span class=\"s\">\"Prenom: Boba\"<\/span><span class=\"o\">);<\/span>\r\n    <span class=\"n\">System<\/span><span class=\"o\">.<\/span><span class=\"na\">out<\/span><span class=\"o\">.<\/span><span class=\"na\">println<\/span><span class=\"o\">(<\/span><span class=\"s\">\"Nom: Fett\"<\/span><span class=\"o\">);<\/span>\r\n    <span class=\"n\">System<\/span><span class=\"o\">.<\/span><span class=\"na\">out<\/span><span class=\"o\">.<\/span><span class=\"na\">println<\/span><span class=\"o\">(<\/span><span class=\"s\">\"Age: 12 ans\"<\/span><span class=\"o\">);<\/span>\r\n<span class=\"o\">}<\/span>\r\n<\/pre>\n<\/div>\n<p>En pla\u00e7ant les capteurs entre chaque instruction, on obtiendrait:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"kd\">public<\/span> <span class=\"kt\">void<\/span> <span class=\"nf\">afficherInformations<\/span><span class=\"o\">()<\/span> <span class=\"o\">{<\/span>\r\n            <span class=\"n\">Capteur1<\/span>\r\n    <span class=\"n\">System<\/span><span class=\"o\">.<\/span><span class=\"na\">out<\/span><span class=\"o\">.<\/span><span class=\"na\">println<\/span><span class=\"o\">(<\/span><span class=\"s\">\"Prenom: Boba\"<\/span><span class=\"o\">);<\/span>\r\n            <span class=\"n\">Capteur2<\/span>\r\n    <span class=\"n\">System<\/span><span class=\"o\">.<\/span><span class=\"na\">out<\/span><span class=\"o\">.<\/span><span class=\"na\">println<\/span><span class=\"o\">(<\/span><span class=\"s\">\"Nom: Fett\"<\/span><span class=\"o\">);<\/span>\r\n            <span class=\"n\">Capteur3<\/span>\r\n    <span class=\"n\">System<\/span><span class=\"o\">.<\/span><span class=\"na\">out<\/span><span class=\"o\">.<\/span><span class=\"na\">println<\/span><span class=\"o\">(<\/span><span class=\"s\">\"Age: 12 ans\"<\/span><span class=\"o\">);<\/span>\r\n            <span class=\"n\">Capteur4<\/span>\r\n<span class=\"o\">}<\/span>\r\n<\/pre>\n<\/div>\n<p>Si on ex\u00e9cutait cet algorithme, chaque capteur s&rsquo;ex\u00e9cuterait une seule fois. On obtient donc que cet algorithme est d&rsquo;ordre O(1).<\/p>\n<p>Voici un autre exemple:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"kd\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">calculerMoyenne<\/span><span class=\"o\">(<\/span><span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Integer<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">aValeurs<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\r\n    <span class=\"kt\">int<\/span> <span class=\"n\">lSomme<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"o\">;<\/span>\r\n    <span class=\"k\">for<\/span> <span class=\"o\">(<\/span><span class=\"n\">Integer<\/span> <span class=\"n\">laValeur<\/span> <span class=\"o\">:<\/span> <span class=\"n\">aValeurs<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\r\n        <span class=\"n\">lSomme<\/span> <span class=\"o\">=<\/span> <span class=\"n\">lSomme<\/span> <span class=\"o\">+<\/span> <span class=\"n\">laValeur<\/span><span class=\"o\">.<\/span><span class=\"na\">intValue<\/span><span class=\"o\">();<\/span>\r\n    <span class=\"o\">}<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"n\">lSomme<\/span> <span class=\"o\">\/<\/span> <span class=\"n\">aValeurs<\/span><span class=\"o\">.<\/span><span class=\"na\">size<\/span><span class=\"o\">();<\/span>\r\n<span class=\"o\">}<\/span>\r\n<\/pre>\n<\/div>\n<p>Si on ajoute les capteurs dans cet algorithme, on obtient:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"kd\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">calculerMoyenne<\/span><span class=\"o\">(<\/span><span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Integer<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">aValeurs<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\r\n            <span class=\"n\">Capteur1<\/span>\r\n    <span class=\"kt\">int<\/span> <span class=\"n\">lSomme<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"o\">;<\/span>\r\n            <span class=\"n\">Capteur2<\/span>\r\n    <span class=\"nf\">for<\/span> <span class=\"o\">(<\/span><span class=\"n\">Integer<\/span> <span class=\"n\">laValeur<\/span> <span class=\"o\">:<\/span> <span class=\"n\">aValeurs<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\r\n                <span class=\"n\">Capteur3<\/span>\r\n        <span class=\"n\">lSomme<\/span> <span class=\"o\">=<\/span> <span class=\"n\">lSomme<\/span> <span class=\"o\">+<\/span> <span class=\"n\">laValeur<\/span><span class=\"o\">.<\/span><span class=\"na\">intValue<\/span><span class=\"o\">();<\/span>\r\n                <span class=\"n\">Capteur4<\/span>\r\n    <span class=\"o\">}<\/span>\r\n            <span class=\"n\">Capteur5<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"n\">lSomme<\/span> <span class=\"o\">\/<\/span> <span class=\"n\">aValeurs<\/span><span class=\"o\">.<\/span><span class=\"na\">size<\/span><span class=\"o\">();<\/span>\r\n            <span class=\"n\">Capteur6<\/span>\r\n<span class=\"o\">}<\/span>\r\n<\/pre>\n<\/div>\n<p>Ici, si on ex\u00e9cute cet algorithme avec des listes diff\u00e9rentes, nous remarquons rapidement que les capteurs ayant les plus d&rsquo;ex\u00e9cution sont les capteurs 3 et 4 et que leurs nombres d&rsquo;ex\u00e9cutions correspondent \u00e0 la taille de la liste re\u00e7ue en entr\u00e9e. On obtient donc la complexit\u00e9 algorithmique O(n) ou n=aValeurs.size().<\/p>\n<p>Voici un autre exemple:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"kd\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">valeurMaximale<\/span><span class=\"o\">(<\/span><span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Integer<\/span><span class=\"o\">&gt;&gt;<\/span> <span class=\"n\">aMatrice<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\r\n    <span class=\"kt\">int<\/span> <span class=\"n\">lResultat<\/span> <span class=\"o\">=<\/span> <span class=\"n\">aMatrice<\/span><span class=\"o\">.<\/span><span class=\"na\">get<\/span><span class=\"o\">(<\/span><span class=\"mi\">0<\/span><span class=\"o\">).<\/span><span class=\"na\">get<\/span><span class=\"o\">(<\/span><span class=\"mi\">0<\/span><span class=\"o\">).<\/span><span class=\"na\">intValue<\/span><span class=\"o\">();<\/span>\r\n    <span class=\"k\">for<\/span> <span class=\"o\">(<\/span><span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Integer<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">laLigne<\/span> <span class=\"o\">:<\/span> <span class=\"n\">aMatrice<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\r\n        <span class=\"k\">for<\/span> <span class=\"o\">(<\/span><span class=\"n\">Integer<\/span> <span class=\"n\">laValeur<\/span> <span class=\"o\">:<\/span> <span class=\"n\">laLigne<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\r\n            <span class=\"k\">if<\/span> <span class=\"o\">(<\/span><span class=\"n\">lResultat<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">laValeur<\/span><span class=\"o\">.<\/span><span class=\"na\">intValue<\/span><span class=\"o\">())<\/span> <span class=\"o\">{<\/span>\r\n                <span class=\"n\">lResultat<\/span> <span class=\"o\">=<\/span> <span class=\"n\">laValeur<\/span><span class=\"o\">.<\/span><span class=\"na\">intValue<\/span><span class=\"o\">();<\/span>\r\n            <span class=\"o\">}<\/span>\r\n        <span class=\"o\">}<\/span>\r\n    <span class=\"o\">}<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"n\">lResultat<\/span><span class=\"o\">;<\/span>\r\n<span class=\"o\">}<\/span>\r\n<\/pre>\n<\/div>\n<p>Si on ajoute nos capteurs, on obtient:<\/p>\n<div class=\"highlight\">\n<pre><span class=\"kd\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">valeurMaximale<\/span><span class=\"o\">(<\/span><span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Integer<\/span><span class=\"o\">&gt;&gt;<\/span> <span class=\"n\">aMatrice<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\r\n            <span class=\"n\">Capteur1<\/span>\r\n    <span class=\"kt\">int<\/span> <span class=\"n\">lResultat<\/span> <span class=\"o\">=<\/span> <span class=\"n\">aMatrice<\/span><span class=\"o\">.<\/span><span class=\"na\">get<\/span><span class=\"o\">(<\/span><span class=\"mi\">0<\/span><span class=\"o\">).<\/span><span class=\"na\">get<\/span><span class=\"o\">(<\/span><span class=\"mi\">0<\/span><span class=\"o\">).<\/span><span class=\"na\">intValue<\/span><span class=\"o\">();<\/span>\r\n            <span class=\"n\">Capteur2<\/span>\r\n    <span class=\"nf\">for<\/span> <span class=\"o\">(<\/span><span class=\"n\">List<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">Integer<\/span><span class=\"o\">&gt;<\/span> <span class=\"n\">laLigne<\/span> <span class=\"o\">:<\/span> <span class=\"n\">aMatrice<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\r\n                <span class=\"n\">Capteur3<\/span>\r\n        <span class=\"nf\">for<\/span> <span class=\"o\">(<\/span><span class=\"n\">Integer<\/span> <span class=\"n\">laValeur<\/span> <span class=\"o\">:<\/span> <span class=\"n\">laLigne<\/span><span class=\"o\">)<\/span> <span class=\"o\">{<\/span>\r\n                    <span class=\"n\">Capteur4<\/span>\r\n            <span class=\"nf\">if<\/span> <span class=\"o\">(<\/span><span class=\"n\">lResultat<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">laValeur<\/span><span class=\"o\">.<\/span><span class=\"na\">intValue<\/span><span class=\"o\">())<\/span> <span class=\"o\">{<\/span>\r\n                        <span class=\"n\">Capteur5<\/span>\r\n                <span class=\"n\">lResultat<\/span> <span class=\"o\">=<\/span> <span class=\"n\">laValeur<\/span><span class=\"o\">.<\/span><span class=\"na\">intValue<\/span><span class=\"o\">();<\/span>\r\n                        <span class=\"n\">Capteur6<\/span>\r\n            <span class=\"o\">}<\/span>\r\n                    <span class=\"n\">Capteur7<\/span>\r\n        <span class=\"o\">}<\/span>\r\n                <span class=\"n\">Capteur8<\/span>\r\n    <span class=\"o\">}<\/span>\r\n            <span class=\"n\">Capteur9<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"n\">lResultat<\/span><span class=\"o\">;<\/span>\r\n            <span class=\"n\">Capteur10<\/span>\r\n<span class=\"o\">}<\/span>\r\n<\/pre>\n<\/div>\n<p>Si on ex\u00e9cute cet algorithme, on obtient que les capteurs les plus ex\u00e9cut\u00e9s soient les capteurs 4 \u00e0 7. Leurs nombres d&rsquo;ex\u00e9cutions est de O(m*n) ou m=nombre de ligne de la matrice et n=nombre de colonne de la matrice.<\/p>\n<p>Ce r\u00e9sultat est un peu emb\u00eatant parce qu&rsquo;il correspond \u00e0 un ordre de complexit\u00e9 quadratique(ou O(n\u00b2)), mais il est difficile de s&rsquo;en rendre compte seulement en regardant la notation O(n*m). Par contre, puisque c&rsquo;est simplement l&rsquo;ordre de complexit\u00e9 du pire cas qui nous importe et non la complexit\u00e9 r\u00e9elle, nous pouvons indiquer quelque chose comme O(n\u00b2) ou n=Max(Ligne et colonne de la matrice).<\/p>\n<h4>R\u00e9sumons<\/h4>\n<p>On voit qu&rsquo;on peut, instinctivement (sans placer de capteur), d\u00e9duire l&rsquo;ordre de complexit\u00e9 d&rsquo;un algorithme en regardant la profondeur des boucles. Bien entendu, il y a des subtilit\u00e9s, mais g\u00e9n\u00e9ralement, un algorithme sans boucle est O(1), un algorithme avec une boucle (ou plusieurs boucles s\u00e9cancielles) sont O(n), un algorithme avec une boucle imbriqu\u00e9e dans une autre est O(n\u00b2), un algorithme avec une boucle imbriqu\u00e9e dans une autre qui est \u00e0 son tour imbriqu\u00e9e dans une autre est O(n\u00b3), etc.<\/p>\n<p>Vous devez faire attention parce que parfois, les boucles peuvent \u00eatre cach\u00e9es dans des sous-routines. Elles doivent \u00e9galement \u00eatre prises en compte dans le calcul d&rsquo;ordre de complexit\u00e9 algorithmique.<\/p>\n<h3>Le pire cas<\/h3>\n<p>Lorsque nous cherchons la complexit\u00e9 d&rsquo;un algorithme, nous nous int\u00e9ressons au pire cas possible dans cet algorithme. Par exemple, si nous faisons un algorithme effectuant une recherche dans une liste, il est inutile de continuer l&rsquo;algorithme si l&rsquo;\u00e9l\u00e9ment a \u00e9t\u00e9 trouv\u00e9. Il serait donc possible de sortir de l&rsquo;algorithme bien avant d&rsquo;avoir termin\u00e9 la recherche et de cette mani\u00e8re, rendre l&rsquo;algorithme plus performant. Par contre, lorsqu&rsquo;on calcule l&rsquo;ordre de complexit\u00e9 algorithmique, on \u00e9value le pire cas. Dans l&rsquo;exemple de la recherche dans une liste, le pire cas correspond au fait que l&rsquo;\u00e9l\u00e9ment est trouv\u00e9 \u00e0 la derni\u00e8re cellule de la liste qui est v\u00e9rifi\u00e9e (ou encore pire, l&rsquo;\u00e9l\u00e9ment n&rsquo;est pas trouv\u00e9).<\/p>\n<h3>Pour aller plus loin<\/h3>\n<p>Il est \u00e0 noter qu&rsquo;il existe des algorithmes d&rsquo;ordre logarithmique (avec ou sans multiplicateur variable). Par exemple, il y a des algorithmes d&rsquo;ordre O(log(n)), d&rsquo;autres d&rsquo;ordre O(n*log(n)), d&rsquo;autre d&rsquo;ordre O(n\u00b2*log(n)), O(log(log(n))), etc. Il s&rsquo;agit g\u00e9n\u00e9ralement d&rsquo;algorithme r\u00e9cursif de type diviser pour r\u00e9gner si vous voulez voir \u00e0 quoi \u00e7a ressemble (voir par exemple le tri fusion qui est O(n*log(n))). Savoir ordonner ces ordres de grandeur est important. Donc, voici une liste comparative non exhaustive qui pourrait vous \u00eatre utile:<\/p>\n<div class=\"highlight\">\n<pre>O(p^n) &gt; O(n\u00b3*log(n)) &gt; O(n\u00b3*log(log(n))) &gt; O(n\u00b3) &gt; O(n\u00b2*log(n)) &gt; \r\nO(n\u00b2*log(log(n))) &gt; O(n\u00b2) &gt; O(n*log(n)) &gt; O(n*log(log(n))) &gt; O(n) &gt; \r\nO(log(n)) &gt; O(log(log(n))) &gt; O(1)<\/pre>\n<\/div>\n<p>Le \u00ab\u00a0p\u00a0\u00bb indiqu\u00e9 dans O(p^n) repr\u00e9sente une constante enti\u00e8re p &gt; 1.<\/p>\n<p><a href=\"https:\/\/www.louismarchand.me\/index.php\/les-cours\/programmation-orientee-objet-2\/\">Retour<\/a><\/p>\n<hr \/>\n<p>Auteur: Louis Marchand<br \/>\n<a href=\"https:\/\/creativecommons.org\/licenses\/by\/4.0\/deed.fr\" target=\"_blank\" rel=\"license noopener noreferrer\"><img decoding=\"async\" src=\"https:\/\/i.creativecommons.org\/l\/by\/4.0\/80x15.png\" alt=\"Creative Commons License\" \/><\/a><br \/>\nSauf pour les sections sp\u00e9cifi\u00e9es autrement, ce travail est sous licence <a href=\"https:\/\/creativecommons.org\/licenses\/by\/4.0\/deed.fr\" target=\"_blank\" rel=\"license noopener noreferrer\">Creative Commons Attribution 4.0 International<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Avoir une bonne repr\u00e9sentation de la performance d&rsquo;un algorithme est un \u00e9l\u00e9ment important pour un programmeur et, malheureusement, \u00e9valuer cette performance est g\u00e9n\u00e9ralement tr\u00e8s difficile et peu intuitif. Il ne suffit pas de diminuer le nombre de lignes de code pour augmenter la performance. En fait, il arrive souvent que des algorithmes plus performants&hellip; <a class=\"more-link\" href=\"https:\/\/www.louismarchand.me\/index.php\/objet-2-la-complexite-algorithmique\/\">Continue reading <span class=\"screen-reader-text\">La complexit\u00e9 algorithmique<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-399","page","type-page","status-publish","hentry","entry"],"_links":{"self":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages\/399","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/comments?post=399"}],"version-history":[{"count":3,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages\/399\/revisions"}],"predecessor-version":[{"id":403,"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/pages\/399\/revisions\/403"}],"wp:attachment":[{"href":"https:\/\/www.louismarchand.me\/index.php\/wp-json\/wp\/v2\/media?parent=399"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}