You are on page 1of 56

Estruturas de Dados e Algoritmos

Introdução e Motivação

joao.arthur@computacao.ufcg.edu.br
Metadados

Professor: joaoarthurbm.github.io

Form: bit.ly/formeda

Ambiente: bit.ly/eda-20182

tst-eda: tst-eda.splab.ufcg.edu.br
Metadados

Avaliação

● EDA (75%) + LEDA (25%)


● 3 Unidades
○ Média das 3 Provas (85%)
○ Média dos MTs/Atividades Extras (15%)
As bíblias
As bíblias
Estrutura de dados e algoritmos

O que veremos na disciplina?

● Noções básicas de projeto e análise de algoritmos


● Estudo avançado sobre estrutura de dados
Antes de começar

● É fácil?
● É importante?
● O que tenho que fazer para ser aprovado?
● Mais perguntas?
O que é um algoritmo?

Qualquer procedimento computacional que produza um


conjunto de valores (saída) a partir de um conjunto de
valores (entrada).
O que é um algoritmo?

Sequência finita de instruções que transformam um


conjunto de valores em um dado estado inicial em um dado
estado final que satisfaça condições específicas.
O que é um algoritmo?
Ferramenta para resolver um problema computacional.

Entrada: Uma sequência de N números <a1,a2,a3...an>


Saída: Uma permutação da sequencia de entrada em ordem não decrescente
<a1',a2',a3'….an'>
O que é um algoritmo?
Mais exemplos?
Diferença entre algoritmos e programas
Diferença entre algoritmos e programas
● Escritos para humanos ● Escritos em linguagens de
entenderem programação para que
computadores os processem
Como podemos descrever algoritmos?

Linguagem natural?
"Pega um número e um array e retorna o menor número maior do que o
número que pegou"
● Informal
● Ambígua
● Prolixa
● Falta de estrutura
● Inadequado para a tradução em linguagem de
programação
Como podemos descrever algoritmos?

Precisamos de algo mais formal.

● Fluxo de controle
● Reduzir ambiguidade
● Ser conciso
Como podemos descrever algoritmos?

Linguagem de programação?

● Feita para leitores burros


● Sintaxe atrapalha
● Tratamento de erros
O Problema
Linguagem de Programação Linguagem Natural
Pseudocódigo

Estrutura e Concisão Flexibilidade e expressão


Exercício

Especifique, em Java, um programa que calcule as médias


acumuladas de um vetor V contendo n inteiros. As médias
devem ser armazenadas em um vetor M com n reais.
Em Linguagem de Programação
public double[] media(int[] v) {
double[] medias = new double[v.length];
double soma;
for (int i = 0; i < v.length ; i++) {
soma = 0;
for (int j = 0; j <= i; j++)
soma += v[j];
medias[i] = soma/(i+1);
}
return medias;
}
Em pseudocódigo

Como avaliar nosso algoritmo? No que estamos


interessados em avaliar?
Avaliação de algoritmos

● Corretude
○ Um algoritmo é correto se para toda entrada ele produz a saída
esperada
● Simplicidade
○ Um algoritmo é simples se for fácil: entender, implementar e manter
● Eficiência
○ Qual a relação entre o algoritmo e o consumo de recursos?
Em pseudocódigo

É correto? Simples? Eficiente?


Corretude

Como provar que um algoritmo é correto?


● Testes? "Servem apenas para provar que um algoritmo
contém erros, nunca que está correto." Dijkstra
Corretude

A ideia geral é garantir que cada bloco faz exatamente o


que se espera.

● O que deve ser feito


● O estado anterior
● efeito do bloco sobre o estado
● estado posterior

É uma atividade complexa!


Simplicidade

Menos formal.

● É simples traduzi-lo em código?


● É fácil de entender?
● É fácil de explicar?
● É fácil depurar?
● É simples modificá-lo?
Eficiência

Analisar um algoritmo é avaliar a sua eficiência, ou seja,


determinar a quantidade de recursos que requer para
operar.

De que recursos estamos falando?


Eficiência

É importante? BogoSort
Eficiência

É importante? Não basta comprar mais recurso?

10ˆ7 instruções / segundo 10ˆ9 instruções / segundo


Eficiência

Algoritmo de ordenação

50nlog(n) 2nˆ2

Quem ordenará mais rápido N = 10^6?

10ˆ7 instruções / segundo 10ˆ9 instruções / segundo


Eficiência
Quem ordenará mais rápido N = 10^6?
Eficiência

● Comparar diversas soluções para o mesmo problema


● Foco no que é essencial do ponto de vista do algoritmo
● Abstrair detalhes da linguagem de programação e do
ambiente usado para execução
Eficiência: Como?

● Uma solução: abordagem experimental.


Abordagem experimental

● Implementar os algoritmos
● Realizar um experimento controlado
○ Medir variáveis
○ Análise estatística dos resultados
● Fatores que influenciam
○ Tamanho da entrada
○ Hardware
○ Linguagem de programação
Abordagem experimental: Vantagens

● Preciso
● Comparação detalhada
Abordagem experimental: Limitações

● Número limitado de testes


● Controle do ambiente
● Precisamos implementar os algoritmos
● Dependente de plataforma e linguagem
de programação
O que precisamos?

Método analítico

● Simples
● Independente de plataforma
● Possa ser generalizado para um
espectro maior de entrada
● Análise de pseudocódigo, sem a
necessidade de execução
Análise de Algoritmos: Método Analítico

int maior(int x, int y) {


if(x>y)
return x;
else
return y;
}
Análise de Algoritmos: Primitivas

Hipótese 1: Custo de operações primitivas é constante.

● Operações primitivas
○ operações aritméticas (a + b)
○ atribuição (a = 14)
○ avaliação de expressões booleanas (a == b)
○ retorno de métodos / funções (return False)
○ acesso direto e elementos em um vetor (v[i])

Obs: Na prática, o tempo varia de acordo com o hardware e software


Análise de Algoritmos: Primitivas

c(primitiva) = 1 ou c(primitiva) = C

int maior(int x, int y) {


if(x>y)
return x;
else
return y;
}
Análise de Algoritmos: Primitivas

● Instruções consecutivas
x = 10 (c1)
y = x (c2)
==========
ct = c1 + c2

● Condicionais
if (x < 10) (c1)
// c-alt1
else
// c-alt2
====================
ct = c1 + max(c-alt1,c-alt2)
Análise de Algoritmos: Laços
Análise de Algoritmos: Laços
Análise de Algoritmos: Laços
Análise de Algoritmos: Laços

Multiplicar o número de iterações pelo custo das instruções


dentro do laço.

O que acontece com laços aninhados?

Recursão? Método iterativo e método mestre.


Tipos de análise

● Pior caso
○ Mais comum
○ Nos diz o tempo máximo de execução para uma determinada entrada
○ Fácil de calcular
● Caso médio
○ Estimativa de tempo esperado levando em consideração todas as
entradas
○ Tipicamente envolve estatística e probabilidade
● Melhor caso
○ Não agrega muita informação
○ Raramente ocorre na prática
Sujando as mãos

1. Busca linear - Em sala de aula.


1.1. Pseudocódigo
1.2. Implementação
1.3. Análise de eficiência (método analítico)
Exercício: Abordagem experimental
Execute várias vezes o algoritmo de busca implementado em sala de aula,
variando o tamanho da lista de entrada (de 10^2 a 10^9). Registre a média dos
tempos que o algoritmo executa para cada entrada. Construa um gráfico em
que seja possível visualizar o comportamento do algoritmo à medida em que a
entrada aumenta.

- abscissas (eixo x): tamanho da lista de entrada


- ordenadas (eixo y): média dos tempos de execução observados
Backup Slides
Corretude: Loops invariantes (invariantes
de laço)

Método para provar blocos de laços:

1. Declarar Invariante
2. Verificar caso base (inicialização)
a. invariante antes de executar o laço
b. e para o primeiro valor da variável de controle
3. Manutenção
4. Término
a. para o valor final da variável de controle
Corretude de MediaAcumulada

Para qualquer i, 2-4 calculam a soma de v[1..i]


Corretude de MediaAcumulada

soma é a soma de i valores;


M[i] após a linha 5 é a média desses valores
Corretude de MediaAcumulada

Invariante?
● I(i) = M[1..i-1] armazena as médias acumuladas de
V[1..i-1]
Corretude de MediaAcumulada

Caso base? i = 1.
● M[1..0] e V[1..0] são vazios
Corretude de MediaAcumulada

Manutenção (k-ésima execução do laço)


● Antes da execução do laço, I(k) é verdade
○ M[1..K-1] ok
○ Calcula M(k) corretamente
○ Ao atingir a invariante, M[1..k]
○ I(k+1) ok
Corretude de MediaAcumulada

Término? i = n + 1
● I (n+1) é verdade
● M[1..n] contém as médias acumuladas de V[1..n]

O algoritmo está correto!