A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Programação Dinâmica IF672 - Algoritmos e Estruturas de Dados CIn - UFPE Átila Valgueiro Malta Moreira Juliana Medeiros de Lucena Rafael Alberto Gomes.

Apresentações semelhantes


Apresentação em tema: "Programação Dinâmica IF672 - Algoritmos e Estruturas de Dados CIn - UFPE Átila Valgueiro Malta Moreira Juliana Medeiros de Lucena Rafael Alberto Gomes."— Transcrição da apresentação:

1 Programação Dinâmica IF672 - Algoritmos e Estruturas de Dados CIn - UFPE Átila Valgueiro Malta Moreira Juliana Medeiros de Lucena Rafael Alberto Gomes Pereira Lima Rafael Loureiro de Carvalho Sara Carvalho da Rocha Brito Tiago Carneiro Pessoa Canto Victor Barbosa de Oliveira Medeiros Vinícius Monteiro de Lira

2 Motivação Técnicas de projeto de algoritmos estudadas até agora:
Algoritmos gulosos (greedy algorithms) Kruskal , Dijkstra, ... Dividir para conquistar (divide and conquer) Mergesort, Quicksort, ...

3 Motivação Um mesmo problema resolvido através 2 técnicas diferentes
Diferentes performances As técnicas anteriores não resolvem todos os problemas da maneira mais eficiente!!!

4 Motivação Portanto... Nenhuma lista de técnicas é exaustiva Mas...
Em alguns problemas, não há técnica alguma que nos dê uma solução pelo menos aceitável Problemas intratáveis (NP-completos)

5 Estrutura de um problema de Programação Dinâmica
Geralmente possuem estruturas recursivas Subproblemas devem ser resolvidos para que a solução final possa ser alcançada Em geral aplicados a problemas de otimização Buscam uma solução ótima

6 Por que não recursão? Se a estrutura do problema é recursiva, por que um algoritmo recursivo não seria uma boa solução? Subproblemas não são independentes. Algoritmos puramente recursivos trabalharão mais que o necessário resolvendo os subsubproblemas comuns mais de uma vez.

7 Por que não recursão? Uma boa estratégia seria ter uma tabela onde:
Pudéssemos guardar os resultados de sub-instâncias do problema que já foram resolvidas. E onde consultas poderiam ser feitas sob demanda.

8 Um exemplo simples: Fibonacci
Os números de Fibonacci são definidos pela função: Definidos em termos de uma função recursiva Seria natural imaginar que a solução algorítmica correspondente fosse as mais apropriada F(0) = 1, n = 0 F(1) = 1, n = 1 F(n) = F(n-1) + F(n-2), n > 1

9 Um exemplo simples: Fibonacci
Código recursivo para os números de Fibonacci: int fibonacci(int n){ if(n <= 1){ return 1; } else{ return fibonacci(n - 1) + fibonacci(n - 2); }

10 Um exemplo simples: Fibonacci
No entanto... O algoritmo apresentado é ineficiente pois há trabalho redundante:

11 Um exemplo simples: Fibonacci
Os cálculos redundantes levam o algoritmo a ter desempenho exponencial Um algoritmo mais “experto” poderia ser feito com programação dinâmica Guardaria apenas os dois últimos resultados

12 Um exemplo simples: Fibonacci
int fibonacci(int n){ int resultado = 1; if(n > 1){ int ultimo = 1; int penultimo = 1; for(int i = 2; i <= n; i++){ resultado = ultimo + penultimo; penultimo = ultimo; ultimo = resultado; } return resultado;

13 Knapsack(Problema da Mochila)

14 Knapsack(Problema da Mochila)
Busca calcular a melhor maneira de se armazenar em um compartimento qualquer, muitos itens com valores agregados, de forma que o somatório dos valores de tais itens seja o máximo possível dentre as possibilidades de combinação de itens. Esse problema tem importantes aplicações, como por exemplo o carregamento ótimo de containers. Importante para supermercados e empresas de armazenagem e logística em geral.

15 Knapsack – Como Funciona?
Vamos criar uma matriz chamada maxTab, de ordem (N+1) x (C+1), onde: N = número de itens; C = Capacidade da mochila. As linhas representam cada item. As colunas a capacidade máxima da mochila.

16 Knapsack – Como Funciona?
A idéia do algoritmo é começar com uma mochila de capacidade 1 e descobrir o valor máximo possível para esta mochila. Depois se passa para uma mochila de capacidade 2, que aproveitando as informações da mochila de capacidade atual -1 (nesse caso, 1) descobre o valor máximo para uma mochila de capacidade 2. Isso será feito até capacidade atual ser igual à C. Além da capacidade ir crescendo, também vai se adicionando novos itens no processo.

17 Knapsack – Como Funciona?
A idéia é ir percorrendo por linha (ou seja, por item) tal tabela, e para a coluna j atual, que representa capacidade atual, analisar se o item atual i (linha atual) cabe na mochila de capacidade j. Se couber é preciso escolher o maior valor entre: valor na mochila de mesma capacidade j que não tinha esse item (essa informação estará em maxTab[i-1][j]). Soma do valor do item com o valor na mochila de capacidade (j – peso do item i) e que não tinha esse item(maxTab[i-1][j – peso do item i]).

18 Knapsack – Como Funciona?
Então, se couber (itens[i].peso <= j), teremos: maxTab[i][j] = Máximo(maxTab[i-1][j], valor do item + maxTab[i-1][j – peso do item i]); Se não couber, significa que o maior valor para essa mochila será o valor da mochila de mesma capacidade, mas que não tem esse item: maxTab[i][j] = maxTab[i-1][j];

19 Knapsack – Exemplo Capacidade da mochila = 5 kg Itens:
1. Peso = 4, Frete = 2 2. Peso = 2, Frete = 1 3. Peso = 1, Frete = 3 4. Peso = 2, Frete = 4

20 Knapsack – Exemplo ? 4 2 1 3 Itens Peso Frete
? Itens Peso Frete 4 2 1 3 maxTab[i][j] = maxTab[i-1][j];

21 Knapsack – Exemplo ? 4 2 1 3 Itens Peso Frete
? Itens Peso Frete 4 2 1 3 maxTab[i][j] = maxTab[i-1][j];

22 Knapsack – Exemplo ? 4 2 1 3 Itens Peso Frete
? Itens Peso Frete 4 2 1 3 maxTab[i][j] = maxTab[i-1][j];

23 Knapsack – Exemplo ? 4 2 1 3 Itens Peso Frete
? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

24 Knapsack – Exemplo 2 ? 4 2 1 3 Itens Peso Frete
2 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

25 Knapsack – Exemplo 2 ? 4 2 1 3 Itens Peso Frete
2 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = maxTab[i-1][j];

26 Knapsack – Exemplo 2 ? 4 2 1 3 Itens Peso Frete
2 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

27 Knapsack – Exemplo 2 1 ? 4 2 1 3 Itens Peso Frete
2 1 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

28 Knapsack – Exemplo 2 1 ? 4 2 1 3 Itens Peso Frete
2 1 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

29 Knapsack – Exemplo 2 1 ? 4 2 1 3 Itens Peso Frete
2 1 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

30 Knapsack – Exemplo 2 1 ? 4 2 1 3 Itens Peso Frete
2 1 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

31 Knapsack – Exemplo 2 1 3 ? 4 2 1 3 Itens Peso Frete
2 1 3 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

32 Knapsack – Exemplo 2 1 3 ? 4 2 1 3 Itens Peso Frete
2 1 3 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

33 Knapsack – Exemplo 2 1 3 4 ? 4 2 1 3 Itens Peso Frete
2 1 3 4 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

34 Knapsack – Exemplo 2 1 3 4 ? 4 2 1 3 Itens Peso Frete
2 1 3 4 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

35 Knapsack – Exemplo 2 1 3 4 5 ? 4 2 1 3 Itens Peso Frete
2 1 3 4 5 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = maxTab[i-1][j];

36 Knapsack – Exemplo 2 1 3 4 5 ? 4 2 1 3 Itens Peso Frete
2 1 3 4 5 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

37 Knapsack – Exemplo 2 1 3 4 5 ? 4 2 1 3 Itens Peso Frete
2 1 3 4 5 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

38 Knapsack – Exemplo 2 1 3 4 5 7 ? 4 2 1 3 Itens Peso Frete
2 1 3 4 5 7 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

39 Knapsack – Exemplo 2 1 3 4 5 7 ? 4 2 1 3 Itens Peso Frete
2 1 3 4 5 7 ? Itens Peso Frete 4 2 1 3 maxTab[i][j] = MAX (maxTab[i-1][j], itens[i].frete + maxTab[i-1][j - itens[i].peso])

40 Knapsack – Exemplo 2 1 3 4 5 7 8 O 8 representa o valor do maior frete possível que se pode carregar nesta mochila de capacidade 5.

41 Knapsack – Outra Implementação

42 Knapsack – Recuperando Informações.
Observe que neste algoritmo não obtemos o subconjunto de itens correspondentes que foram inseridos na mochila. Se desejássemos obter o subconjunto correspondente, então usaríamos uma flag em cada item para recuperar esta informação.

43 Knapsack – Complexidade
Existem (nC) entradas na tabela (onde, n é o número de itens e C a capacidade da mochila), cada uma é computada em tempo constante a partir de uma ou duas outras entradas. Logo, a complexidade é O(nC). Obs: Knaspack não é um algoritmo polinomial pois k (capacidade da mochila) pode ser um valor infinitamente grande.

44 String Matching Este algoritmo resume-se em uma busca de padrões dentro de um conjunto de informações. São muitas as variações deste problema, desde procurar determinadas palavras ou sentenças em um texto até procurar um determinado objeto dentro de uma seqüência de bits que representam uma imagem.

45 Algoritmo inocente ou força bruta
Pode se resolver o problema do String Matching através da força bruta. Não é inteligente o bastante para aproveitar os mismatchs, quando acha um caractere em P que não pode ser casado em T. É deslocada uma posição de cada vez, independente de ter match ou não. Complexidade: O(n2) .

46 Força Bruta - Exemplo

47 Algoritmo De Boyer-Moore
Consiste em um algoritmo mais eficiente na resolução do problema de string matching. A cada mismatch um novo incremento é calculado para saber qual será a próxima posição do texto que será comparada. Possui duas versões para este calculo As comparações entre os caracteres do texto e do padrão é sempre feito da direita para a esquerda

48 Boyer-Moore (1ª versão)
De inicio, deve-se criar uma tabela com a posição da última ocorrências de cada caractere do padrão. A cada mismatch um novo incremento deverá ser calculado da seguinte forma: Pega-se o caractere do texto que esta na posição: deslocamento + 1. Desloca-se o suficiente para alinhar a ultima ocorrência desse caractere do padrão com o caractere correspondente no texto.

49 Boyer-Moore (1ª versão)
Texto: addcccadcba Padrão: ddc Criando Tabela De Ocorrência do padrão:

50 Boyer-Moore (1ª versão)
addcccadcba ddc Mismatch (pega-se o caractere da posição 5 (‘c’) do texto e procura a sua ultima ocorrência no padrão)

51 Boyer-Moore (1ª versão)-Exemplo
addcccadcba ddc Match (Encontrou uma ocorrência na posição 1 do texto, continua a procura por novas ocorrências)

52 Boyer-Moore (1ª versão)-Exemplo
addcccadcba ddc Mismatch (pega-se o caractere da posição 5 (‘c’) do texto e procura a sua ultima ocorrência no padrão)

53 Boyer-Moore (1ª versão)-Exemplo
addcccadcba ddc Mismatch (pega-se o caractere da posição 7 (‘a’) do texto e procura a sua ultima ocorrência no padrão)

54 Boyer-Moore (1ª versão)-Exemplo
addcccadcba ddc Mismatch (pega-se o caractere da posição 10 (‘a’) do texto e procura a sua ultima ocorrência no padrão)

55 Boyer-Moore (1ª versão)-Exemplo
addcccadcba ddc O tamanho do deslocamento + o comprimento do padrão é maior que o tamanho do texto. (termina o algoritmo).

56 Boyer-Moore (2ª versão)
Tentar casar o padrão com o pedaço do texto anteriormente casado. Exemplo: Texto: aabcaccacbac Padrão: cacbac

57 Boyer-Moore (2ª versão)
c a c b a c a a b c a c c a c b a c No primeiro caso, o padrão deve ser deslocado para a direita até casar com o pedaço do texto anteriormente casado, no caso ac, deslocando o padrão 3 posições à direita. O processo é repetido mais uma vez e o casamento entre P e T ocorre.

58 Algoritmo De Boyer-Moore (versão 3)
Esta versão do algoritmo de Boyer-Moore consiste em utilizar as duas heurísticas de forma independente e paralela. Quando ocorre uma falha no casamento, cada uma das heurísiticas propõe um valor para o novo deslocamento válido. O algoritmo de Boyer e Moore escolhe o maior valor.

59 Bibliografia Weiss, Mark Allen. Data Structures & Algorithm Analysis in Java, Addison Wesley-Longman Cormen et al. Algoritmos: Teoria e Prática, Editora Campos Manber, Udi. Introduction to Algorithms: A Creative Approach, Addison-Wesley

60 Programação Dinâmica IF672 - Algoritmos e Estruturas de Dados CIn - UFPE Átila Valgueiro Malta Moreira Juliana Medeiros de Lucena Rafael Alberto Gomes Pereira Lima Rafael Loureiro de Carvalho Sara Carvalho da Rocha Brito Tiago Carneiro Pessoa Canto Victor Barbosa de Oliveira Medeiros Vinícius Monteiro de Lira


Carregar ppt "Programação Dinâmica IF672 - Algoritmos e Estruturas de Dados CIn - UFPE Átila Valgueiro Malta Moreira Juliana Medeiros de Lucena Rafael Alberto Gomes."

Apresentações semelhantes


Anúncios Google