1.2 Mathematical Preliminaries
Nesta seção, vamos explorar as notações matemáticas presentes ao longo de The Art of Computer Programming e desenvolver algumas fórmulas básicas que serão utilizadas diversas vezes. Mesmo que o leitor não se interesse pelas derivações matemáticas mais avançadas, é recomendável que se familiarize, ao menos, com o significado das diferentes fórmulas, para que possa aproveitar os resultados dessas derivações.
A notação matemática tem dois objetivos principais neste livro: descrever partes de um algoritmo e avaliar as características de desempenho de um algoritmo. A notação empregada para descrever algoritmos é relativamente simples, conforme detalhado na seção anterior. Já para analisar o desempenho dos algoritmos, recorremos a notações mais específicas e especializadas.
A maioria dos algoritmos que abordaremos vem acompanhada de cálculos matemáticos que estimam a velocidade esperada de execução. Esses cálculos abrangem quase todas as áreas da matemática, e seria necessário um livro à parte para explorar todos os conceitos matemáticos utilizados em diferentes momentos. Ainda assim, a maior parte desses cálculos pode ser compreendida com conhecimentos de álgebra universitária, e quem domina cálculo elementar conseguirá acompanhar quase toda a matemática apresentada. Em alguns casos, recorremos a resultados mais avançados de áreas como teoria de variáveis complexas, teoria de grupos, teoria dos números, teoria da probabilidade, entre outras. Nessas situações, o tema será explicado de forma simples, sempre que possível, ou indicaremos referências a outras fontes de informação.
As técnicas matemáticas usadas na análise de algoritmos têm um caráter bem particular. Por exemplo, é comum lidarmos com somas finitas de números racionais ou com soluções de relações de recorrência. Esses assuntos costumam receber pouca atenção nos cursos tradicionais de matemática, por isso as próximas subseções foram planejadas para oferecer um treinamento detalhado no uso das notações que serão definidas, além de exemplificar em profundidade os tipos de cálculos e métodos mais úteis para nossos propósitos.
Nota importante: As subseções seguintes proporcionam um treinamento abrangente nas habilidades matemáticas relacionadas ao estudo de algoritmos de computador. No entanto, a maioria dos leitores pode não perceber, de início, uma ligação direta entre esse conteúdo e a programação de computadores (exceto na Seção 1.2.1). O leitor pode optar por estudar essas subseções com atenção, confiando na afirmação do autor de que os temas aqui tratados são, sim, muito relevantes. Porém, para manter a motivação, talvez seja melhor dar uma leitura superficial nesta seção inicialmente e, depois de encontrar várias aplicações dessas técnicas nos capítulos seguintes, volte para um estudo mais aprofundado. Passar tempo demais nesse material logo na primeira leitura pode atrasar o avanço para os tópicos de programação! De toda forma, é essencial que cada leitor conheça ao menos o conteúdo geral dessas subseções e tente resolver alguns exercícios, mesmo na leitura inicial. A Seção 1.2.10 merece destaque especial, pois serve como ponto de partida para grande parte do material teórico desenvolvido mais adiante. Já a Seção 1.3, que vem após a 1.2, marca uma transição abrupta da “matemática pura” para a “programação de computadores pura”.
Uma expansão e apresentação mais detalhada de grande parte do material a seguir podem ser encontradas no livro Concrete Mathematics de Graham, Knuth e Patashnik, segunda edição (Reading, Mass.: Addison–Wesley, 1994). Esse livro será chamado simplesmente de CMath quando precisarmos nos referir a ele posteriormente.
1.2.1 Indução Matemática
Seja alguma afirmação sobre o número inteiro ; por exemplo, pode ser
ou
Suponha que queiramos provar que é verdadeira para todos os inteiros positivos . Uma maneira importante de fazer isso é:
Fornecer uma prova de que é verdadeira.
Fornecer uma prova de que
Essa prova deve ser válida para qualquer inteiro positivo .
Como exemplo, considere a seguinte sequência de equações, que muitas pessoas descobriram independentemente desde os tempos antigos:
Podemos formular a propriedade geral da seguinte maneira:
Chamemos essa equação temporariamente de ; desejamos provar que é verdadeira para todo positivo. Seguindo o procedimento descrito acima, temos:
Passo Base:
Passo Indutivo: Se todas as afirmações forem verdadeiras, então, em particular, é verdadeira, de modo que a equação acima se mantém. Somando em ambos os lados, obtemos
o que prova que também é verdadeira.
Podemos considerar esse método como um procedimento de prova algorítmico. De fato, o seguinte algoritmo gera uma prova de para qualquer inteiro positivo , assumindo que os passos (1) e (2) acima tenham sido realizados:
Algoritmo (Construção de uma prova)
Dado um inteiro positivo , este algoritmo fornecerá uma prova de que é verdadeira.
[Provar ] Defina e, de acordo com o passo base, forneça uma prova de .
[Verificar ] Se , termine o algoritmo; a prova necessária foi gerada.
[Provar ] De acordo com o passo indutivo, forneça uma prova de que
Além disso, forneça a afirmação:
[Incrementar ] Aumente em 1 e retorne ao passo 2. ||
Atualizado