Estrutura de Dados e Algoritmos

Discentes:

              

                                              - George Neres

                                      - Jean Lima

                                              - Vitor Emanuel

Greedy Method / Método Guloso

Um algoritmo guloso é usado em problemas de otimização. O algoritmo faz a escolha ideal em cada etapa, pois tenta encontrar a maneira geral ideal de resolver todo o problema. Algoritmos gulosos são bem-sucedidos em alguns problemas, mas podem falhar na procura do caso geral ótimo.

Problema: Pendrive

Tenho n arquivos digitais no meu computador. Cada arquivo i tem ti megabytes. Quero gravar o maior número possível de arquivos num pendrive que tem capacidade para c megabytes. O problema pode ser formulado assim: encontrar o maior subconjunto X do intervalo 1 .. n que satisfaça a restrição

  i ∈ X ti  ≤  c. (A)

(Note que queremos maximizar │X│ e não a soma i ∈ X ti.)

 

Supondo que os arquivos estejam ordenados em ordem crescente...

Solução: Guloso

Divide and Conquer / Divisão e Conquista

Esse método consiste no seguinte:

  1. A instância do problema é dividida em duas ou mais instâncias menores;
  2. Cada instância menor é resolvida usando o próprio algoritmo que está sendo definido;
  3. As soluções das instâncias menores são combinadas para produzir uma solução da instância original.

Problema: Buscar elemento numa lista

Se a lista não estiver ordenada, não há o que fazer senão percorrer a lista toda. Se a lista estiver ordenada, entretanto, é possível fazer algo bem melhor.

 

Problema da busca em vetor ordenado:  Dado um inteiro x e um vetor inteiro crescente A[1 .. n], encontrar j tal que  A[j−1] < x ≤ A[j]. Ou seja, x deve estar contido em A.

 

O problema faz sentido para todo n natural, até mesmo para n = 0. Toda instância do problema tem solução e toda solução j pertence ao intervalo 1 .. n+1. Se x > A[n], por exemplo, então n+1 é a resposta correta.

Solução: Busca Binária

Dynamic Programming / Programação Dinâmica

O método da programação dinâmica se aplica quando o problema tem estrutura recursiva: a solução de toda instância do problema deve conter soluções de subinstâncias da instância. O consumo de tempo do algoritmo é, em geral, proporcional ao tamanho da tabela.

Estratégias:

- Recursão: resolve subproblemas recursivamente

- Memoização: Armazena valores já calculados em uma tabela.

Propriedades da estratégia de programação dinâmica:

- Subestrutura ótima: uma solução ótima para um problema contém soluções ótimas para os subproblemas.

- Subproblemas sobrepostos: uma solução recursiva contém um pequeno número de subproblemas distintos repetidos várias vezes.

Problema: Troco com moedas

Dado um valor N, se quisermos trocar em miúdos para N centavos, e tivermos um suprimento infinito de cada uma das moedas com valor de S = {S1, S2, .., Sm}, de quantas maneiras podemos fazer o troco? A ordem das moedas não importa.


Por exemplo, para N = 4 e S = {1,2,3}, existem 4 soluções: {1,1,1,1}, {1,1,2}, {2,2}, {1, 3}. Portanto, a saída deve ser 4.

Para N = 10 e S = {2, 5, 3, 6}, existem cinco soluções: {2,2,2,2,2}, {2,2,3,3}, {2,2,6}, {2,3,5} e {5,5}. Portanto, a saída deve ser 5.

Problema de uma solução recursiva sem memoização

Problema de uma solução recursiva sem memoização

Solução com Programação Dinâmica

Referências

https://askgif.com/blog/46/introduction-to-dynamic-programming/

 

https://www.tutorialspoint.com/data_structures_algorithms/index.htm

 

https://www.ime.usp.br/~pf/analise_de_algoritmos/lectures.html

 

https://www.geeksforgeeks.org/dynamic-programming/

Estrutura de Dados e Algoritmos

By Vitor Emanuel

Estrutura de Dados e Algoritmos

Apresentação feita na matéria inf006 - ED & A

  • 273