Medida do tempo de execução de um
programa
Algoritmos e Estruturas de Dados I
Natália Batista
https://sites.google.com/site/nataliacefetmg/
1º semestre/ 2019
CENTRO FEDERAL DE EDUCAÇÃO TECNOLÓGICA DE MINAS GERAIS
2
1. Custo de algoritmos
(1/5)
Custo de utilização de um algoritmo:
tempo de execução
quantidade de operações executadas
quantidade de memória
3
1. Custo de algoritmos
Tempo de execução
vantagens
desvantagens
4
1. Custo de algoritmos
Objeções:
resultados são dependentes do compilador que pode favorecer algumas construções em detrimento de outras;
diferenças de hardware;
quando grande quantidade de memória é utilizada, as medidas de tempo podem depender deste aspecto.
E quando existem vários algoritmos para resolver o mesmo problema, todos com custo de execução na mesma ordem de grandeza?
5
2. Modelo computacional
Uma forma mais adequada de medir o custo de utilização de um algoritmo é usando um modelo matemático baseado em um
computador idealizado.
Modelo computacional.
6
2. Modelo computacional
Modelo:
Esquema que possibilita a representação de uma entidade (Houaiss).
No modelo, só se deve incluir o que for relevante para a modelagem do objeto em questão.
Computacional:
Relativo ao processamento (Houaiss).
Definição (nosso contexto):
Esquema que descreve como é o modelo abstrato do processamento de algoritmos.
7
2. Modelo computacional
Importância:
Um algoritmo não existe, ou seja, não é possível escrevê-lo, se antes não for definido o modelo computacional associado (como será executado).
Conceito básico no projeto de qualquer algoritmo.
O mais popular (usado) de todos:
RAM – Random Access Machine.
Modela o computador tradicional e outros elementos computacionais.
8
2. Modelo computacional
Elementos do modelo:
um único processador;
memória.
Observações:
Podemos ignorar os dispositivos de entrada e saída (teclado, monitor, etc) assumindo que a codificação do algoritmo e os dados já estão armazenados na memória.
Computação nesse modelo:
Processador busca instrução/dado da memória.
Uma única instrução é executada de cada vez.
Cada instrução é executada seqüencialmente.
Modelo RAM
9
3. Função de complexidade
Para medir o custo de execução de um
algoritmo define-se uma função de custo ou função de complexidade f.
f(n) é a medida do tempo necessário para
executar um algoritmo para um problema de
tamanho n.
10
3. Função de complexidade
Se f é a medida da quantidade de tempo,
então f é função de complexidade de tempo.
Se f é a medida da quantidade de memória, então f é função de complexidade de espaço.
No livro e na disciplina: complexidade de
tempo.
11
3. Função de complexidade
A complexidade de tempo não representa tempo diretamente, mas o número de vezes que determinada operação considerada
relevante é executada.
A complexidade de espaço representa a
quantidade de memória que é necessária
para armazenar as estruturas de dados
associadas ao algoritmo.
12
4. Exemplo
Exemplo: algoritmo para encontrar o maior elemento de um vetor de inteiros A[1..n], n1.
int Max (int A[], int n){
int i, Temp;
Temp = A[0];
for (i = 1; i < n; i = i + 1) if (Temp < A[i]) Temp = A[i];
return Temp;
}
13
4. Exemplo
Seja f uma função de complexidade tal que f(n) é o número de comparações entre os elementos de A, se A contiver n elementos.
Logo,
f(n) = n – 1, para n>0.
14
4. Exemplo
O algoritmo anterior é ótimo?
Quando o custo de um algoritmo é igual ao menor custo possível, então o algoritmo é ótimo para a medida de custo considerada. (Ziviani)
15
4. Exemplo
Teorema: qualquer algoritmo para encontrar o maior elemento de um conjunto com n
elementos, n1, faz pelo menos n-1
comparações.
16
5. Melhor caso, pior caso e caso médio
Medida do custo de execução de um algoritmo depende:
do tamanho da entrada dos dados
ou de uma entrada particular dos dados
17
5. Melhor caso, pior caso e caso médio
Três cenários:
melhor caso
pior caso
caso médio
18
5. Melhor caso, pior caso e caso médio
Melhor caso
Menor tempo de execução sobre todas as entradas de tamanho n.
19
5. Melhor caso, pior caso e caso médio
Pior caso
Maior tempo de execução sobre todas as entradas de tamanho n.
Se f é uma função de complexidade baseada na análise de pior caso, o custo de aplicar o
algoritmo nunca é maior do que f(n).
20
5. Melhor caso, pior caso e caso médio
Caso médio (ou caso esperado)
Média dos tempos de execução de todas as entradas de tamanho n.
Uma distribuição de probabilidades sobre o
conjunto de entradas de tamanho n é suposta, por exemplo uniforme.
21
6. Exemplo
Considere o problema de acessar os registros de um arquivo.
Cada registro contém uma chave única que é utilizada para recuperar registros do
arquivo.
22
6. Exemplo
O problema: dada uma chave qualquer,
localize o registro que contenha esta chave.
O algoritmo de pesquisa mais simples é o
que faz a pesquisa seqüencial.
23
6. Exemplo
Seja f uma função de complexidade tal que f(n) é o número de registros consultados no arquivo (número de vezes que a chave de consulta é comparada com a chave de cada registro).
Melhor caso, pior caso, caso médio?
24
6. Exemplo
Melhor caso:
f(n) = 1
Pior caso:
f(n) = n
Caso médio:
f(n) = (n+1)/2
25
6. Exemplo
No estudo do caso médio, vamos considerar que toda pesquisa recupera um registro.
Se pi for a probabilidade de que o i-ésimo registro seja procurado e, considerando que para recuperar o i-ésimo registro são necessárias i comparações, então:
f(n) = 1 x p1 +2 x p2 +3 x p3 + ... +n x pn.
Para calcular f(n) basta conhecer a distribuição de probabilidades pi.
26
6. Exemplo
Se cada registro tiver a mesma probabilidade de ser acessado que todos os outros, então pi = 1/n,1i
n.
Neste caso:
A análise do caso esperado revela que uma
pesquisa com sucesso examina aproximadamente metade dos registros.
27
7. Exemplo
Algoritmo para encontrar o maior e o menor
elementos de um vetor de inteiros A[1..n], n1.
void MaxMin1 (int A[], int *Max, int *Min, int n){
int i;
*Max = A[0]; *Min = A[0];
for (i = 1; i < n; i = i + 1){
if (A[i] > *Max) *Max = A[i];
if (A[i] < *Min) *Min = A[i];
} }
28
7. Exemplo
Seja f(n) o número de comparações entre os elementos de A, se A tiver n elementos.
Logo
f(n) = 2(n - 1), para n > 0,
para o melhor caso, pior caso e caso médio.
29
7. Exemplo
Pode-se melhorar MaxMin1?
Observe que a comparação A[i] < Min
somente é necessária quando o resultado da
comparação A[i] > Max é falso.
30
7. Exemplo
void MaxMin2 (int A[], int *Max, int *Min, int n){
int i;
*Max = A[0]; *Min = A[0];
for (i = 1; i < n; i = i + 1){
if (A[i] > *Max) *Max = A[i];
else if (A[i] < *Min) *Min = A[i];
} }
31
7. Exemplo
Melhor caso: f(n) = n-1
o vetor A está em ordem crescente
os comandos do else nunca serão executados
32
7. Exemplo
Pior caso: f(n) = 2(n-1)
o vetor A está ordem decrescente
em todas as comparações, A[i] perde para Max
33
7. Exemplo
Caso médio: A[i] é maior do que Max a metade das vezes.
Sempre faz a comparação do primeiro if: n-1
Metade das vezes executa o else: (n-1)/2
34
7. Exemplo
Considerando o número de comparações
realizadas, existe a possibilidade de obter um
algoritmo mais eficiente para este problema?
35
7. Exemplo
Sim! Particionando o vetor em dois subconjuntos.
(Ziviani)
36
8. Exemplo
1. Compare os elementos de A aos pares, separando-os em dois subconjuntos (maiores em um e menores em outro), a um custo de ⌈n/2⌉
comparações.
2. O máximo é obtido do subconjunto que contém os maiores elementos, a um custo de ⌈n/2⌉ - 1 comparações.
3. O mínimo é obtido do subconjunto que contém os menores elementos, a um custo de ⌈n/2⌉ - 1 comparações.
37
8. Exemplo
Implementação: quando n é ímpar, o
elemento que está na posição A[n-1] é
duplicado na posição A[n] para evitar
tratamento de exceção.
38
void MaxMin3 (int A[], int *Max, int *Min, int n){
int i, FimDoAnel;
if ((n % 2) > 0){ //se n é ímpar, duplica último elemento A[n] = A[n-1]; FimDoAnel = n;
}
else FimDoAnel = n - 1;
if (A[0] > A[1]){
*Max = A[0]; *Min = A[1];
}
else {
*Max = A[1]; *Min = A[0];
}
i = 3;
while (i <= FimDoAnel){
if (A[i-1] > A[i]){
if (A[i-1] > *Max) *Max = A[i-1];
if (A[i] < *Min) *Min = A[i];
}
else {
if (A[i-1] < *Min) *Min = A[i-1];
if (A[i] > *Max) *Max = A[i];
}
i = i + 2;
} }
39
8. Exemplo
Comparação dos elementos aos pares: n/2
Obtenção do máximo do subconjunto dos maiores elementos: n/2-1
Obtenção do mínimo do subconjunto dos menores elementos: n/2-1
Para o melhor caso, pior caso e caso médio:
40
8. Exemplo
Comparação dos algoritmos para obter o máximo e o mínimo:
Os algoritmos MaxMin2 e MaxMin3 são superiores ao algoritmo MaxMin1 de forma geral.
O algoritmo MaxMin3 é superior ao algoritmo MaxMin2 com relação ao pior caso e bastante próximo quanto ao caso
médio.
*
* *
41
9. Limite inferior
É possível obter um algoritmo MaxMin mais eficiente?
Para responder temos de conhecer o limite
inferior para essa classe de algoritmos.
42
9. Limite inferior
Técnica utilizada: uso de um oráculo.
43
10. Exemplo: Oráculo
De acordo com o dicionário Aurélio, um oráculo é:
1. Resposta de um deus a quem o consultava.
2. Divindade que responde consultas e orienta o crente: o oráculo de Delfos.
3. Palavra, sentença ou decisão inspirada, infalível ou que tem grande autoridade: os oráculos dos profetas, os oráculos da ciência.
44
10. Exemplo: Oráculo
Dado um modelo de computação que
expresse o comportamento do algoritmo, o oráculo informa o resultado de cada passo possível (no caso, o resultado de cada
comparação).
45
10. Exemplo: Oráculo
O teorema a seguir utiliza um oráculo para derivar o limite inferior no número de
comparações necessárias para o problema do máximo e do mínimo.
Teorema: Qualquer algoritmo para encontrar
o maior e o menor elementos de um conjunto
com n elementos não ordenados, n 1, faz
pelo menos 3
⌈n/2⌉ - 2comparações.
46
10. Exemplo: Oráculo
Prova: A técnica utilizada define um oráculo que descreve o comportamento do algoritmo por meio de
um conjunto de n–tuplas, e
um conjunto de regras associadas que mostram as tuplas possíveis (estados) que um algoritmo pode assumir a partir de uma dada tupla e uma única comparação.
47
10. Exemplo: Oráculo
Uma 4–tupla, representada por (a, b, c, d), onde os elementos de:
a nunca foram comparados;
b foram vencedores e nunca perderam em comparações realizadas;
c foram perdedores e nunca venceram em comparações realizadas;
d foram vencedores e perdedores em comparações realizadas.
48
10. Exemplo: Oráculo
O algoritmo inicia no estado (n, 0, 0, 0) e termina com (0, 1, 1, n - 2).
49
10. Exemplo: Oráculo
Após cada comparação a tupla (a, b, c, d)
consegue progredir apenas se ela assume
um dentre os seis estados possíveis abaixo:
50
10. Exemplo: Oráculo
Dadas as transições de estado, é possível derivar o limite inferior determinando-se que o estado final
não pode ser atingido usando um número menor de transições.
51
10. Exemplo: Oráculo
O primeiro passo requer necessariamente a manipulação do componente a.
O caminho mais rápido para levar a até zero
requer ⌈n/2⌉ mudanças de estado e termina com a tupla (0, n/2, n/2, 0) (comparação dos
elementos de a dois a dois).
52
10. Exemplo: Oráculo
A seguir, para reduzir o componente b até um são necessárias ⌈n/2⌉ - 1 mudanças de estado (mínimo de comparações para obter o maior elemento de b).
Idem para c, com ⌈n/2⌉ - 1 mudanças de estado.
53
10. Exemplo: Oráculo
Logo, para obter o estado (0, 1, 1, n - 2) a partir do estado (n, 0, 0, 0) as comparações necessárias são:
54
10. Exemplo: Oráculo
O teorema nos diz que se o número de
comparações entre os elementos de um
vetor for utilizado como medida de custo,
então o algoritmo MaxMin3 é ótimo.
55
Exercício
Calcule o número de trocas/comparações que o algoritmo de
ordenação por seleção realiza no pior caso.
void ordena (int v[],int n){
int i, j;
for (i=0; i<n-1; i++){
int min = i;
for (j = i+1; j < n; j++){
if (v[j] < v[min]){
min = j;
//troca v[min] e v[i]
int x = v[min];
v[min] = v[i];
v[i] = x;
} } } }
56
Exercício
Considerando somente as comparações entre elementos do vetor:
O for mais externo é executado de 0 a n-2, ou seja, n-1 vezes.
O for mais interno é executado de i+1 a n-1, ou seja, n-1 - (i+1) + 1 = n - i - 1 vezes.
Como se trata do pior caso, iremos assumir que a comparação do if será sempre executada.
Logo
57
Exercício
n f(n)
0 0
1 0
2 1
3 3
... ...
n (n2-n)/2
58
11. Referências
Nivio Ziviani. Projeto de algoritmos: com implementações em Pascal e C. 3 ed.
Editora Cengage Learning, 2011.