Até que ponto um algoritmo pode prever a complexidade de tempo de um programa de entrada arbitrário?

23

O problema de parada indica que é impossível escrever um programa que possa determinar se outro programa é interrompido para todos os programas de entrada possíveis .

Eu posso, no entanto, certamente escrever um programa que pode calcular o tempo de execução de um programa como:

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

e retorne uma complexidade de tempo de , sem nunca executá-lo.N

Para todos os outros programas de entrada, ele retornaria um sinalizador indicando que não era possível determinar a complexidade do tempo.

Minha pergunta é esta:

Quais condições devem ser mantidas, para que possamos determinar algoritmicamente a complexidade de tempo de um determinado programa?

* Se houver uma referência canônica ou artigo de revisão, eu apreciaria um link para ele nos comentários.

Hooked
fonte
1
(1) “A notação O” não significa “complexidade do tempo”. (2) Não está claro o que você quer dizer com “O (infinito).” Evite inventar uma nova notação, se possível. (3) Decidir se um determinado programa é interrompido ou não e atribuir um limite superior explícito à complexidade do tempo do programa é diferente.
Tsuyoshi Ito
1
Não estou familiarizado com a dedução da complexidade do tempo de programas em classes restritas, mas uma classe de programas que pode valer a pena verificar é chamada de "programas de loop limitado", para os quais é fácil limitar a complexidade do tempo. Lembro-me de que os programas de loop limitado são discutidos no Capítulo 3 de Gems of Theoretical Computer Science por Uwe Schöning e Randall J. Pruim no contexto da decisão de equivalência de dois programas, mas não tenho certeza da relevância do capítulo para sua pergunta.
Tsuyoshi Ito
4
Estou um pouco confuso. De que maneira isso está fora de escopo? Uma resposta razoável à pergunta do OP seria fragmentos de linguagem (ou mesmo classes de fragmentos) para os quais o tempo de execução pode ser determinado algoritmicamente.
Suresh Venkat
4
Pergunta relacionada: Os limites de tempo de execução em P são decidíveis?
Artem Kaznatcheev
7
Estou muito atrasado para este tópico de comentários. Parece que estamos no momento em que um post cheira a novato. Não estou apontando dedos. Eu mesmo sinto esse instinto. Talvez devêssemos ser mais gentis. O OP admitiu não estar familiarizado com a área ou termos. Qual é o sentido de um site de perguntas e respostas, se tolerarmos apenas as pessoas que sabem exatamente o que querem e perguntarmos em nosso idioma.
Vijay D

Respostas:

23

Em geral, você não pode determinar a complexidade, mesmo para programas vacilantes: vamos haver alguma máquina de Turing arbitrária e deixe p T ser o programa (que sempre retorna 0):TpT

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

É claro que é indecidível, em geral, se é tempo linear ou a tempo quadrática.pT

No entanto, muito trabalho foi realizado no cálculo efetivo da complexidade do programa. Tenho particular interesse pela Teoria da Complexidade Implícita, que visa criar linguagens que, usando construções especiais ou disciplinas de tipo, permitem escrever apenas programas que habitam uma certa classe de complexidade bem definida. Pelo que considero um milagre, essas línguas costumam ser completas para essa classe!

Um exemplo particularmente interessante é descrito neste artigo por J.-Y. Marion, que descreve uma pequena linguagem imperativa, com uma disciplina tipo inspirado em técnicas de informação de fluxo e análise de segurança, que permite uma caracterização de algoritmos em P .

cody
fonte
Como nota lateral, veja também Epigram, que é um idioma que pode garantir a rescisão.
Realz Slaw
Este é um bom começo, mas há mais a dizer? (Por exemplo, parece-me que uma determinada função recursiva elementar de tempo de execução deve ser simples de computação, mas essas funções podem resolver qualquer problema na hierarquia exponencial ....)
usul
Na medida em que é possível determinar que o programa de entrada seja gravado em um idioma restrito, você pode assumir que a complexidade do tempo é limitada por qualquer limite superior que o idioma imponha. No entanto, muitas funções recursivas primitivas têm equivalentes recursivas gerais que são mais eficientes
Chris Pressey
1
(salvou acidentalmente esse comentário com antecedência e excedeu o limite de 5 minutos. A segunda frase deve ser a seguinte :) No entanto, os programas nesses idiomas restritos podem ter equivalentes em idiomas menos restritos e mais eficientes (especificamente, muitas funções recursivas primitivas têm equivalentes recursivos gerais mais eficientes) que, na prática, incentivam o uso de linguagens irrestritas e mais difíceis de analisar.
precisa
Isso é muito interessante, Chris! Você possui uma referência? De fato, parece contra-inutivo: eu suspeitaria que funções recursivas primitivas possam simular funções recursivas gerais para um determinado número de etapas, o que limitaria a aceleração a algum fator constante.
Cody
11

A pergunta que você faz e o truque de contagem específico que você descreve são clássicos na análise de programas. Existe o problema teórico da análise de complexidade e sua manifestação prática em termos de estimativa automática do desempenho de um pedaço de código. Essa análise automatizada possui vários aplicativos, desde a detecção de bugs de desempenho até a estimativa do custo de alguns cálculos na nuvem.

Cody apontou que o problema é indecidível em geral. Esse problema é mais difícil do que provar a finalização, porque a obtenção de um limite de complexidade implica que o programa também seja finalizado. Existem duas abordagens para esse problema. Um é da análise do programa. A ideia de adicionar um contador e estimar seu valor existe desde os anos 70. Essa codificação reduz o problema de determinar o tempo de execução ao da computação de um invariante.

Uma segunda abordagem é projetar uma linguagem de programação que admita apenas programas de certa complexidade limitada. Essa é a área de complexidade computacional implícita.

Seguem algumas referências para as duas áreas.

  1. O Projeto SPEED é uma linha específica de trabalho de análise de programas que se concentra em como encontrar limites nos contadores, uma vez introduzidos no programa. Os contadores podem medir o consumo de tempo ou espaço.
  2. Análise multivariada de recursos amortizados , Jan Hoffman, Klaus Aehlig, Martin Hoffman, ACM TOPLAS 2012
  3. Sobre propriedades decidíveis de taxa de crescimento de programas imperativos , Amir Ben Amram, Desenvolvimentos em conformidade computacional implícita 2010. Esta é uma bela linha de trabalho para limitar a complexidade de programas imperativos por restrições sintáticas.
Vijay D
fonte