Dans quelle mesure un algorithme peut-il prédire la complexité temporelle d'un programme d'entrée arbitraire?

23

Le problème d'arrêt indique qu'il est impossible d'écrire un programme qui peut déterminer si un autre programme s'arrête, pour tous les programmes d'entrée possibles .

Je peux, cependant, certainement écrire un programme qui peut calculer le temps d'exécution d'un programme comme:

for(i=0; i<N; i++)
    { x = 1; }

et retourner une complexité temporelle de , sans jamais l'exécuter.N

Pour tous les autres programmes d'entrée, il retournerait un indicateur indiquant qu'il n'a pas pu déterminer la complexité temporelle.

Ma question est la suivante:

Quelles conditions doivent être remplies pour que nous puissions déterminer algorithmiquement la complexité temporelle d'un programme donné?

* S'il existe une référence canonique ou un article de synthèse à ce sujet, j'apprécierais un lien vers celui-ci dans les commentaires.

Accroché
la source
1
(1) «La notation O» ne signifie pas «complexité temporelle». (2) On ne sait pas ce que vous entendez par «O (infini)». Veuillez éviter d'inventer une nouvelle notation si possible. (3) Décider si un programme donné s'arrête ou non et donner une limite supérieure explicite sur la complexité temporelle du programme est différente.
Tsuyoshi Ito
1
Je ne suis pas familier avec la déduction de la complexité temporelle des programmes dans les classes restreintes, mais une classe de programmes qui mérite d'être vérifiée est appelée «programmes en boucle bornée», pour laquelle il est facile de limiter la complexité temporelle. Je me souviens que les programmes en boucle bornée sont discutés dans le chapitre 3 de Gems of Theoretical Computer Science par Uwe Schöning et Randall J.Pruim dans le contexte de la décision d'équivalence de deux programmes, mais je ne sais pas dans quelle mesure le chapitre est pertinent pour votre question.
Tsuyoshi Ito
4
Je suis un peu confus. En quoi est-ce hors de portée? Une réponse raisonnable à la question de l'OP serait des fragments de langage (ou même des classes de fragments) pour lesquels le temps d'exécution peut être déterminé de manière algorithmique.
Suresh Venkat
4
Question connexe: les limites d'exécution dans P sont-elles décidables?
Artem Kaznatcheev
7
Je suis terriblement en retard sur ce fil de commentaires. Nous semblons bondir au moment où un post sent le newbie-ish. Je ne pointe pas du doigt. Je ressens moi-même cet instinct. Nous devrions peut-être être plus doux. Le PO a reconnu ne pas être familier avec le domaine ou les termes. À quoi sert un site de questions-réponses si nous ne tolérons que des gens qui savent exactement ce qu'ils veulent et que nous le demandons dans notre langue.
Vijay D

Réponses:

23

En général, vous ne pouvez pas déterminer la complexité, même pour l'arrêt de programmes: soit une machine de Turing arbitraire et soit le programme (qui renvoie toujours 0):p TTpT

input: n
run T for n steps
if T is in halting state, output: 0
otherwise, loop for n^2 steps and output: 0

Il est clair qu'il est indécidable en général que soit linéaire ou temps quadratique.pT

Cependant, beaucoup de travail a été effectué sur le calcul efficace de la complexité du programme. J'ai un penchant particulier pour la théorie de la complexité implicite qui vise à créer des langages qui, en utilisant des constructions spéciales ou des disciplines de type, permettent d'écrire uniquement des programmes qui habitent une certaine classe de complexité bien définie. Par ce que je considère comme un miracle, ces langues sont souvent complètes pour cette classe!

Un exemple particulièrement agréable est décrit dans cet article par J.-Y. Marion, qui décrit un petit langage impératif, avec une discipline de type inspiré des techniques de flux d' information et d' analyse de sécurité, ce qui permet une caractérisation des algorithmes P .

cody
la source
En remarque, voir également Epigram, qui est un langage qui peut garantir la résiliation.
Realz Slaw
C'est un bon début, mais y a-t-il autre chose à dire? (Par exemple, il me semble que le temps d'exécution d'une fonction récursive élémentaire donnée doit être simple à calculer, mais de telles fonctions peuvent résoudre n'importe quel problème dans la hiérarchie exponentielle ...)
usul
Dans la mesure où il est possible de déterminer que le programme d'entrée est écrit dans un langage restreint, vous pouvez supposer que la complexité temporelle est limitée par la limite supérieure imposée par ce langage. Cependant, de nombreuses fonctions récursives primitives ont des équivalents récursifs généraux qui sont plus efficaces
Chris Pressey
1
(a accidentellement enregistré ce commentaire plus tôt, puis a dépassé la limite de 5 minutes. La deuxième phrase devrait se lire comme suit :) Cependant, les programmes dans ces langues restreintes peuvent avoir des équivalents dans des langues moins restreintes qui sont plus efficaces (en particulier, de nombreuses fonctions récursives primitives ont équivalents récursifs généraux plus efficaces) qui, dans la pratique, encouragent l’utilisation de langues illimitées et plus difficiles à analyser.
Chris Pressey
C'est très intéressant Chris! Avez-vous une référence? En fait, cela semble contre-inutile: j'aurais pensé que les fonctions récursives primitives pouvaient simuler des fonctions récursives générales pour un nombre donné d'étapes, ce qui limiterait alors l'accélération à un facteur constant.
cody
11

La question que vous posez et l'astuce de comptage spécifique que vous décrivez sont classiques dans l'analyse de programme. Il y a le problème théorique de l'analyse de la complexité, et c'est une manifestation pratique en termes d'estimation automatique des performances d'un morceau de code. Une telle analyse automatisée a plusieurs applications, de la détection de bogues de performance à l'estimation du coût de certains calculs dans le cloud.

Cody a souligné que le problème est indécidable en général. Ce problème est plus difficile que de prouver la terminaison, car l'obtention d'une limite de complexité implique que le programme se termine également. Il existe deux approches à un tel problème. L'une provient de l'analyse des programmes. L'idée d'ajouter un compteur et d'estimer sa valeur existe depuis les années 70. Ce codage réduit le problème de la détermination du temps d'exécution à celui du calcul d'un invariant.

Une deuxième approche consiste à concevoir un langage de programmation qui n'admet que des programmes d'une certaine complexité bornée. C'est le domaine de la complexité de calcul implicite.

Quelques références pour les deux domaines suivent.

  1. Le projet SPEED est une ligne spécifique de travail d'analyse de programme qui se concentre sur la façon de trouver des limites sur les compteurs une fois introduits dans le programme. Les compteurs peuvent mesurer la consommation de temps ou d'espace.
  2. Analyse des ressources amorties multivariées , Jan Hoffman, Klaus Aehlig, Martin Hoffman, ACM TOPLAS 2012
  3. Amir Ben Amram, Developments in Implicit Computational complExity, 2010, sur les propriétés décidables du taux de croissance des programmes impératifs.
Vijay D
la source