Article de reference

Complexité temporelle

Graphiques de fonctions couramment utilisées dans l' analyse des algorithmes , montrant le nombre d'opérations N en fonction de la taille n des données d'entrée pour chaque fonc...

Graphiques de fonctions couramment utilisées dans l' analyse des algorithmes , montrant le nombre d'opérations N en fonction de la taille n des données d'entrée pour chaque fonction.

En informatique théorique , la complexité temporelle désigne la complexité de calcul qui décrit le temps d'exécution d'un algorithme . Elle est généralement estimée en comptant le nombre d'opérations élémentaires effectuées par l'algorithme, en supposant que chaque opération élémentaire a une durée d'exécution fixe. Ainsi, la durée d'exécution et le nombre d'opérations élémentaires sont liés par un facteur constant .

Comme le temps d'exécution d'un algorithme peut varier pour des entrées de même taille, on considère généralement sa complexité temporelle dans le pire des cas , c'est-à-dire le temps maximal requis pour des entrées d'une taille donnée. Moins courante, et généralement spécifiée explicitement, est la complexité temporelle moyenne , qui correspond au temps moyen d'exécution pour des entrées de taille donnée (ce qui est logique puisqu'il n'existe qu'un nombre fini d'entrées possibles de cette taille). Dans les deux cas, la complexité temporelle est généralement exprimée en fonction de la taille de l'entrée. Cette fonction étant généralement difficile à calculer exactement, et le temps d'exécution pour les petites entrées étant généralement négligeable, on s'intéresse généralement au comportement de la complexité lorsque la taille de l'entrée augmente, c'est-à-dire à son comportement asymptotique . Par conséquent, la complexité temporelle est généralement exprimée à l'aide de la notation grand O , typiquement O(n) , O(n- n), O(n-n), O(n-n ), etc. , où n est la taille, en bits , de l'entrée.

La complexité des algorithmes est classée selon le type de fonction apparaissant dans la notation grand O. Par exemple, un algorithme de complexité temporelle O(n) est un algorithme linéaire , et un algorithme de complexité temporelle O(n) = n/2 pour une certaine constante est un algorithme polynomial . 0 α>0{\displaystyle \alpha >0}0

Tableau des complexités temporelles courantes

Le tableau suivant résume certaines classes de complexités temporelles couramment rencontrées. Dans le tableau, poly( x ) = x O (1) , c'est-à-dire polynôme en x .

NomClasse de complexitéComplexité temporelle ( O ( n ) )Exemples de durées d'exécutionExemples d'algorithmes
temps constant10Trouver la valeur médiane dans un tableau trié de nombres. Calculer (−1) n .
temps d'Ackermann inverseTemps amorti par opération en utilisant un ensemble disjoint
temps logarithmique itéréColoration distribuée des cycles
logarithmiqueTemps amorti par opération en utilisant une file d'attente à priorité limitée
temps logarithmiqueDLOGTIMERecherche binaire
temps polylogarithmique
puissance fractionnaireRecherche de plage dans un arbre k -d
temps linéairen ,Recherche du plus petit ou du plus grand élément dans un tableau non trié . Algorithme de Kadane . Recherche linéaire .
"n log-étoile n" tempsL'algorithme de triangulation polygonale de Seidel .
temps linéaire-ithmiqueTri par comparaison le plus rapide possible . Transformée de Fourier rapide .
temps quasi-linéaireÉvaluation polynomiale multipoint
temps quadratiqueTri à bulles . Tri par insertion . Convolution directe
temps cubiqueMultiplication naïve de deux matrices. Calcul de la corrélation partielle .
temps polynomialPAlgorithme de Karmarkar pour la programmation linéaire . Test de primalité AKS
temps quasi-polynomialQPMeilleur algorithme d'approximation en O ( log₂n ) connu pour le problème de l'arbre de Steiner orienté , meilleur solveur de jeu de parité connu , meilleur algorithme d'isomorphisme de graphes connu
temps sous-exponentiel (première définition)SUBEXP0 ϵ>0{\displaystyle \epsilon >0}0 Contient BPP sauf si EXPTIME (voir ci-dessous) est égal à MA .
temps sous-exponentiel (deuxième définition)Meilleur algorithme classique pour la factorisation des entiers

ancien meilleur algorithme pour l'isomorphisme de graphes

temps exponentiel (avec exposant linéaire)ERésolution du problème du voyageur de commerce par programmation dynamique
temps factorielRésolution du problème du voyageur de commerce par recherche exhaustive
temps exponentielEXPTIMERésolution de la multiplication de chaînes matricielles par recherche exhaustive . Recherche d'une stratégie gagnante aux échecs , aux dames ou au go avec la règle japonaise du ko sur un échiquier.
temps double exponentiel2-EXPTIMEDéterminer la vérité d'un énoncé donné en arithmétique de Presburger

Un algorithme est dit à temps constant (souvent représenté par `t`) lorsque sa fonction de complexité est bornée par une valeur qui ne varie pas avec la taille des données d'entrée. Cela signifie que le temps d'exécution reste constant quelle que soit la quantité de données traitées. Par exemple, accéder à un élément spécifique d'un tableau est une opération à temps constant, car elle ne nécessite qu'une seule opération pour localiser cet élément.

En revanche, la détermination de la valeur minimale dans un tableau non ordonné ne s'effectue pas en temps constant ; elle nécessite l'examen de chaque élément , ce qui donne une complexité temporelle linéaire, ou O( n). Cependant, si le nombre d'éléments est connu et fixe, certaines tâches peuvent encore être considérées comme s'effectuant en temps constant.

Il est important de noter que le terme « temps constant » ne signifie pas que le temps d'exécution doit être totalement indépendant de la taille du problème ; il doit plutôt présenter une limite supérieure constante, quelle que soit la taille des données d'entrée. Par exemple, une tâche consistant à échanger les valeurs de a et b pour garantir que la condition soit remplie est classée comme ayant un temps constant, même si le temps d'exécution peut varier selon que la condition est déjà remplie ou non. L'essentiel est qu'il existe une constante t telle que le temps d'exécution ne dépasse jamais t , quelles que soient les valeurs des données d'entrée.

Les algorithmes à temps d'exécution constant sont particulièrement importants dans des domaines comme la cryptographie, où les attaques temporelles peuvent exploiter les variations du temps d'exécution. En concevant des algorithmes à temps d'exécution constant, les développeurs peuvent renforcer la sécurité et garantir la prévisibilité des performances, ce qui en fait un critère fondamental en génie logiciel.

temps logarithmique

On dit qu'un algorithme s'exécute en temps logarithmique lorsque . Puisque et sont liés par un multiplicateur constant , et que ce multiplicateur est sans incidence sur la classification grand O, l'usage standard pour les algorithmes en temps logarithmique est indépendamment de la base du logarithme apparaissant dans l'expression de T .

Les algorithmes s'exécutant en temps logarithmique sont couramment rencontrés dans les opérations sur les arbres binaires ou lors de l'utilisation de la recherche binaire .

Un algorithme est considéré comme très efficace lorsque le rapport entre le nombre d'opérations et la taille de l'entrée diminue et tend vers zéro lorsque n augmente. Un algorithme qui doit accéder à tous les éléments de son entrée ne peut pas s'exécuter en temps logarithmique, car le temps nécessaire pour lire une entrée de taille n est de l'ordre de .

Un exemple de complexité logarithmique est donné par la recherche dans un dictionnaire. Considérons un dictionnaire D contenant n entrées, triées par ordre alphabétique . Supposons que, pour tout n ≥ 0 , on puisse accéder à la k -ième entrée du dictionnaire en un temps constant. Notons cette k -ième entrée. Sous ces hypothèses, le test permettant de vérifier si un mot w est présent dans le dictionnaire peut être effectué en temps logarithmique : considérons w = w<sub>k</sub> , où ∅ désigne la fonction partie entière . Si w ≥ w (c’est-à-dire si le mot w se trouve exactement au milieu du dictionnaire), la recherche est terminée. Sinon, si w est antérieur au mot central du dictionnaire dans l’ordre alphabétique, on poursuit la recherche de la même manière dans la moitié gauche (c’est-à-dire la moitié antérieure) du dictionnaire, et ce, de façon répétée jusqu’à trouver le mot. Enfin, si w est postérieur au mot central, on poursuit la recherche de la même manière dans la moitié droite du dictionnaire. Cet algorithme est similaire à la méthode souvent utilisée pour trouver une entrée dans un dictionnaire papier. Par conséquent, l'espace de recherche au sein du dictionnaire diminue à mesure que l'algorithme se rapproche du mot cible.

temps polylogarithmique

On dit qu'un algorithme s'exécute en temps polylogarithmique si son temps est de l'ordre de k pour une certaine constante k . Une autre façon d'écrire cela est :

Par exemple, l'ordonnancement de chaînes de matrices peut être résolu en temps polylogarithmique sur une machine à accès aléatoire parallèle , et un graphe peut être déterminé comme étant planaire de manière entièrement dynamique en temps par opération d'insertion/suppression.

Temps sous-linéaire

On dit qu'un algorithme s'exécute en temps sous-linéaire (souvent orthographié temps sublinéaire ) si . Cela inclut notamment les algorithmes dont la complexité temporelle est définie ci-dessus.

Le terme spécifique d'algorithme en temps sous-linéaire fait généralement référence à des algorithmes randomisés qui échantillonnent une petite fraction de leurs entrées et les traitent efficacement pour inférer approximativement les propriétés de l'instance entière. Ce type d'algorithme en temps sous-linéaire est étroitement lié aux tests de propriétés et aux statistiques .

Voici d'autres contextes dans lesquels les algorithmes peuvent s'exécuter en temps sous-linéaire :

  • Les algorithmes parallèles qui ont un travail total linéaire ou supérieur (leur permettant de lire l'intégralité de l'entrée), mais une profondeur sous-linéaire .
  • Les algorithmes qui reposent sur des hypothèses garanties concernant la structure des données d'entrée en sont un exemple important. Les opérations sur les structures de données , comme la recherche binaire dans un tableau trié, en sont un exemple significatif.
  • Les algorithmes qui recherchent une structure locale dans les données d'entrée, par exemple la recherche d'un minimum local dans un tableau unidimensionnel (peuvent être résolus en temps constant à l'aide d'une variante de la recherche binaire), sont étroitement liés à la notion d' algorithmes de calcul local (ACL). Dans ce cadre, l'algorithme reçoit une entrée volumineuse et interroge des informations locales concernant une sortie valide de grande taille.

Temps linéaire

On dit qu'un algorithme s'exécute en temps linéaire (ou temps O(n)) si sa complexité temporelle est O(n) . Autrement dit, le temps d'exécution augmente au plus linéairement avec la taille de l'entrée. Plus précisément, cela signifie qu'il existe une constante c telle que le temps d'exécution soit au plus O(n) pour toute entrée de taille n . Par exemple, une procédure qui additionne tous les éléments d'une liste s'exécute en un temps proportionnel à la longueur de la liste si le temps d'addition est constant, ou du moins borné par une constante.

Le temps linéaire représente la meilleure complexité temporelle possible lorsque l'algorithme doit lire séquentiellement l'intégralité de ses données d'entrée. De nombreuses recherches ont donc été menées pour découvrir des algorithmes présentant un temps d'exécution linéaire, ou du moins quasi linéaire. Ces recherches portent sur des méthodes logicielles et matérielles. Plusieurs technologies matérielles exploitent le parallélisme pour y parvenir. La mémoire adressable par contenu (CAM) en est un exemple . Ce concept de temps linéaire est utilisé dans les algorithmes de recherche de chaînes de caractères, tels que l' algorithme de Boyer-Moore et l'algorithme d'Ukkonen .

Temps quasi-linéaire

On dit qu'un algorithme s'exécute en temps quasi-linéaire (ou log-linéaire ) si, pour une certaine constante positive k ; le temps linéaire-ithmique est le cas . En utilisant la notation O souple, ces algorithmes sont . Les algorithmes en temps quasi-linéaire sont également pour toute constante et s'exécutent donc plus rapidement que tout algorithme en temps polynomial dont la borne temporelle inclut un terme pour tout . 0 ε>0{\displaystyle \varepsilon >0}0 1 c>1{\displaystyle c>1}1

Les algorithmes qui s'exécutent en temps quasi-linéaire comprennent :

Dans de nombreux cas, le temps d'exécution correspond simplement au nombre d' opérations effectuées n fois (pour la notation, voir la notation Big O § Famille des notations de Bachmann-Landau ). Par exemple, le tri par arbre binaire crée un arbre binaire en insérant successivement chaque élément d'un tableau de taille n . Puisque l'opération d'insertion dans un arbre binaire de recherche auto-équilibré a une durée O(n log n), l'algorithme complet a une durée O(n log n).

Les tris par comparaison nécessitent au moins comparaisons dans le pire des cas car , d'après l'approximation de Stirling , . Ils résultent également fréquemment de la relation de récurrence .

Temps sous-quadratique

On dit qu'un algorithme a un temps sous-quadratique si .

Par exemple, les algorithmes de tri simples, basés sur la comparaison, ont une complexité quadratique (comme le tri par insertion ), tandis que des algorithmes plus avancés ont une complexité sous-quadratique (comme le tri Shell ). Aucun algorithme de tri général ne s'exécute en temps linéaire, mais le passage d'une complexité quadratique à une complexité sous-quadratique revêt une grande importance pratique.

temps polynomial

An algorithm is said to be of polynomial time if its running time is upper bounded by a polynomial expression in the size of the input for the algorithm, that is, T(n) = O(nk) for some positive constant k.Problems for which a deterministic polynomial-time algorithm exists belong to the complexity classP, which is central in the field of computational complexity theory. Cobham's thesis states that polynomial time is a synonym for "tractable", "feasible", "efficient", or "fast".

Some examples of polynomial-time algorithms:

  • The selection sort sorting algorithm on n integers performs A. Thus it runs in time
  • All the basic arithmetic operations (addition, subtraction, multiplication, division, and comparison) can be done in polynomial time.
  • Maximum matchings in graphs can be found in polynomial time. In some contexts, especially in optimization, one differentiates between strongly polynomial time and weakly polynomial time algorithms.

These two concepts are only relevant if the inputs to the algorithms consist of integers.

Complexity classes

The concept of polynomial time leads to several complexity classes in computational complexity theory. Some important classes defined using polynomial time are the following.

P désigne la classe de complexité temporelle minimale sur une machine déterministe, robuste aux changements de modèle de machine. (Par exemple, le passage d'une machine de Turing à une seule bande à une machine à plusieurs bandes peut entraîner un gain de vitesse quadratique, mais tout algorithme s'exécutant en temps polynomial sur un modèle s'exécute également en temps polynomial sur l'autre.) Chaque machine abstraite possède une classe de complexité correspondant aux problèmes résolubles en temps polynomial sur cette machine.

temps superpolynomial

Un algorithme est défini comme prenant un temps superpolynomial si T ( n ) n'est pas borné supérieurement par un polynôme ; c'est-à-dire si ⁠ ⁠ pour tout entier positif c .

Par exemple, un algorithme qui s'exécute en 2 n étapes sur une entrée de taille n nécessite un temps superpolynomial (plus précisément, un temps exponentiel).

Un algorithme utilisant des ressources exponentielles est clairement superpolynomial, mais certains algorithmes ne le sont que très faiblement. Par exemple, le test de primalité d'Adleman-Pomerance-Rumely s'exécute en un temps O (log log n ) pour des entrées de n bits ; sa complexité croît plus rapidement que celle de n pour des valeurs de n suffisamment grandes , mais la taille des entrées doit devenir excessivement grande pour ne plus pouvoir être dominée par un polynôme de petit degré.

Un algorithme dont le temps d'exécution est superpolynomial n'appartient pas à la classe de complexité P. La thèse de Cobham postule que ces algorithmes sont impraticables, ce qui est souvent le cas. Le problème P versus NP n'étant pas résolu, on ignore si les problèmes NP-complets nécessitent un temps d'exécution superpolynomial.

temps quasi-polynomial

Les algorithmes quasi-polynomiaux sont des algorithmes dont le temps d'exécution présente une croissance quasi-polynomiale , un comportement qui peut être plus lent qu'un temps polynomial mais nettement plus rapide qu'un temps exponentiel . Le temps d'exécution dans le pire des cas d'un algorithme quasi-polynomial est O(n^2) pour une valeur de n fixée . Lorsque n = 0, le temps d'exécution est polynomial, et pour n = 0, il est sous-linéaire. 0 c>0{\displaystyle c>0}0

Il existe des problèmes pour lesquels on connaît des algorithmes quasi-polynomiaux, mais aucun algorithme polynomial. De tels problèmes apparaissent dans les algorithmes d'approximation ; un exemple célèbre est le problème de l'arbre de Steiner orienté , pour lequel il existe un algorithme d'approximation quasi-polynomial atteignant un facteur d'approximation de ( n étant le nombre de sommets), mais démontrer l'existence d'un tel algorithme polynomial reste un problème ouvert.

Parmi les autres problèmes de calcul admettant des solutions en temps quasi-polynomial mais aucune solution en temps polynomial connue, on peut citer le problème de la clique plantée, dont le but est de trouver une grande clique dans l'union d'une clique et d'un graphe aléatoire . Bien que résoluble en temps quasi-polynomial, il a été conjecturé que le problème de la clique plantée n'admet pas de solution en temps polynomial ; cette conjecture a été utilisée comme hypothèse de complexité pour démontrer la difficulté de plusieurs autres problèmes en théorie des jeux computationnelle , en vérification de propriétés et en apprentissage automatique .

La classe de complexité QP regroupe tous les problèmes qui admettent des algorithmes en temps quasi-polynomial. Elle peut être définie en termes de DTIME comme suit.

Lien avec les problèmes NP-complets

En théorie de la complexité, le problème non résolu P versus NP consiste à déterminer si tous les problèmes NP admettent des algorithmes en temps polynomial. Tous les algorithmes les plus connus pour les problèmes NP-complets, comme 3SAT, ont une complexité exponentielle. De fait, on conjecture que de nombreux problèmes NP-complets naturels n'admettent pas d'algorithmes en temps sous-exponentiel. Ici, « temps sous-exponentiel » est entendu au sens de la seconde définition présentée ci-dessous. (Par ailleurs, de nombreux problèmes de graphes, représentés naturellement par des matrices d'adjacence, sont résolubles en temps sous-exponentiel simplement parce que la taille de l'entrée est le carré du nombre de sommets.) Cette conjecture (pour le problème k-SAT) est connue sous le nom d' hypothèse du temps exponentiel . Puisqu'il est conjecturé que les problèmes NP-complets n'admettent pas d'algorithmes en temps quasi-polynomial, certains résultats d'inapproximabilité dans le domaine des algorithmes d'approximation reposent sur cette conjecture. Voir par exemple les résultats d'inapproximabilité connus pour le problème de la couverture d'ensembles .

Temps sous-exponentiel

Le terme « temps sous-exponentiel » est utilisé pour exprimer que le temps d'exécution d'un algorithme peut croître plus rapidement que n'importe quel polynôme, tout en restant nettement inférieur à celui d'une exponentielle. En ce sens, les problèmes admettant des algorithmes à temps sous-exponentiel sont plus faciles à résoudre que ceux ne disposant que d'algorithmes exponentiels. La définition précise de « sous-exponentiel » ne fait pas consensus , mais les deux définitions les plus couramment utilisées sont présentées ci-dessous.

Première définition

Un problème est dit sous-exponentiel s'il peut être résolu en un temps d'exécution dont le logarithme est inférieur à la somme des carrés de tout polynôme donné. Plus précisément, un problème est sous-exponentiel s'il existe, pour tout ε > 0, un algorithme qui le résout en un temps O ( 2nε ) . L'ensemble de tous ces problèmes constitue la classe de complexité SUBEXP , qui peut être définie en fonction de DTIME comme suit.

0}{ extsf {DTIME}}\left(2^{n^{\varepsilon }} ight) SUBEXP=ε>0DTIME(2nε){\displaystyle { extsf {SUBEXP}}=\bigcap _{\varepsilon >0}{ extsf {DTIME}}\left(2^{n^{\varepsilon }} ight)}0}{ extsf {DTIME}}\left(2^{n^{\varepsilon }} ight)

Cette notion de sous-exponentielle n'est pas uniforme en termes de ε dans le sens où ε ne fait pas partie de l'entrée et chaque ε peut avoir son propre algorithme pour le problème.

Deuxième définition

Certains auteurs définissent le temps sous-exponentiel comme un temps d'exécution en O(n^n) . Cette définition autorise des temps d'exécution plus longs que la première définition du temps sous-exponentiel. Un exemple d'algorithme sous-exponentiel est l'algorithme classique le plus connu pour la factorisation d'entiers, le crible généralisé , qui s'exécute en O(n^n) , où n est la longueur de l'entrée . Un autre exemple est le problème d'isomorphisme de graphes , résolu en O(n^n ) par le meilleur algorithme connu de 1982 à 2016. Cependant, lors de la conférence STOC 2016, un algorithme quasi-polynomial a été présenté.

Il est important que l'algorithme puisse avoir une complexité sous-exponentielle par rapport à la taille de l'instance, au nombre de sommets ou au nombre d'arêtes. En complexité paramétrée , cette différence est explicitée en considérant des paires de problèmes de décision et de paramètres k . SUBEPT est la classe de tous les problèmes paramétrés dont le temps d'exécution est sous-exponentiel en k et polynomial en la taille de l'entrée n :

Plus précisément, SUBEPT est la classe de tous les problèmes paramétrés pour lesquels il existe une fonction calculable avec et un algorithme qui décide L en temps .

Hypothèse du temps exponentiel

L' hypothèse du temps exponentiel ( ETH ) stipule que le problème de satisfaisabilité 3SAT , qui concerne les formules booléennes sous forme normale conjonctive avec au plus trois littéraux par clause et n variables, ne peut être résolu en un temps 2 <sup>o ( n ) </sup>. Plus précisément, l'hypothèse est qu'il existe une constante absolue c > 0 telle que 3SAT ne puisse être résolu en un temps 2 <sup>cn</sup> par aucune machine de Turing déterministe. Avec m désignant le nombre de clauses, l'ETH est équivalente à l'hypothèse que kSAT ne peut être résolu en un temps 2 <sup>o ( m ) </sup> pour tout entier k ≥ 3. [ hypothèse du temps exponentiel implique P ≠ NP .

Temps exponentiel

Un algorithme est dit à complexité exponentielle si T ( n ) est majoré par 2 <sup>n</sup> poly( n ) , où poly( n ) est un polynôme en n . Plus formellement, un algorithme est à complexité exponentielle si T ( n ) est majoré par O (2 <sup> nk</sup> ) pour une certaine constante k . Les problèmes admettant des algorithmes à complexité exponentielle sur une machine de Turing déterministe forment la classe de complexité connue sous le nom d' EXP .

Parfois, le temps exponentiel est utilisé pour désigner des algorithmes qui ont T ( n ) = 2 O ( n ) , où l'exposant est au plus une fonction linéaire de n . Cela donne lieu à la classe de complexité E .

Temps factoriel

Un algorithme est dit en temps factoriel si T(n) est majoré par la fonction factorielle n!. Le temps factoriel est un sous-ensemble du temps exponentiel (EXP) car pour tout n ≥ 0. Cependant, il n'est pas un sous-ensemble de E. 0 ϵ>0{\displaystyle \epsilon >0}0

Un exemple d'algorithme s'exécutant en temps factoriel est le tri bogosort , un algorithme de tri notoirement inefficace basé sur la méthode des essais et erreurs . Le tri bogosort trie une liste de n éléments en la mélangeant de manière itérative jusqu'à ce qu'elle soit triée. En moyenne, chaque itération de l'algorithme examine l'un des n ! ordres possibles des n éléments. Si les éléments sont distincts, un seul de ces ordres est retenu. Le tri bogosort est lié au théorème du singe savant .

Temps double exponentiel

Un algorithme est dit à temps double exponentiel si T ( n ) est majoré par 2 2 poly( n ) , où poly( n ) est un polynôme en n . De tels algorithmes appartiennent à la classe de complexité 2-EXPTIME .

Parmi les algorithmes à complexité double exponentielle bien connus, on peut citer :