Prog Din08

1,052 views

Published on

Apresentação de Prog. Dinâmica para Clube de Programação

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,052
On SlideShare
0
From Embeds
0
Number of Embeds
11
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Prog Din08

  1. 1. Wikipedia.org Programação dinâmica é um método para a construção de algoritmos para a resolução de problemas computacionais, em especial os de optimização combinatória. Ela é aplicável a problemas no qual a solução óptima pode ser computada a partir da solução óptima previamente calculada e memorizada - de forma a evitar recalculo - de outros sub problemas que, sobrepostos, compõem o problema original. Exemplo (Fibonacci): var m := map(0 → 1 1 → 1) : 1, function fib(n) if map m does not contain key n m[n] := fib(n − 1) + fib(n − 2) return m[n] Programação Dinâmica
  2. 2. Solução Sem Programação Dinâmica: function fib(n) if n = 0 or n = 1 return 1 else return fib(n − 1) + fib(n − 2) fib(5) fib(4) + fib(3) (fib(3) + fib(2)) + (fib(2) + fib(1)) ((fib(2) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) + fib(1)) (((fib(1) + fib(0)) + fib(1)) + (fib(1) + fib(0))) + ((fib(1) + fib(0)) + fib(1)) Ou seja, existem inúmeras repetições nos cálculos necessários para determinar o resultado final pretendido. Programação Dinâmica
  3. 3. No entanto se usarmos o algoritmo anteriormente referido verificamos que não necessitamos de calcular diversas vezes as mesmas parcelas, basta construir a matriz e preenchê-la correctamente. var m := map(0 → 1, 1 → 1) function fib(n) if map m does not contain key n m[n] := fib(n − 1) + fib(n − 2) return m[n] [] Fib(0) b( ) Fib(1) b( ) Fib(2) b( ) Fib(3) b( ) Fib(4) b( ) Fib(5) b( ) 1 1 1+1=2 1+2=3 2+3=5 3+5=8 Programação Dinâmica
  4. 4. Cálculo de combinações sem repetição (coeficiente binomial): n −1 n −1 C =C + Cr n r r −1 r 1 - - - - n 1 1 - - - 1 1+1 = 2 1 - - 1 1+2 = 3 2+1 = 3 1 - 1 1+3 = 4 3+3 = 6 3+1 = 4 1 Programação Dinâmica
  5. 5. // binomial.c by: Steven Skiena long binomial_coefficient(n,m) int n,m; { int i,j; long bc[MAXN][MAXN]; for (i=0; i<=n; i++) bc[i][0] = 1; f (j=0; j for (j 0 j<=n; jj++) b [j][j] = 1 ) bc[j][j] 1; for (i=1; i<=n; i++) for (j 1; j<i; j++) (j=1; bc[i][j] = bc[i-1][j-1] + bc[i-1][j]; return( bc[n][m] ); } Programação Dinâmica
  6. 6. A programação dinâmica não serve apenas para satisfazer a necessidade de termos diversas formas de resolver um problema. Trata- se também de um método “muito” eficiente, ao nível da complexidade, no entanto é preciso ter em atenção que ele acarreta um custo maior a nível do uso de memória. Este método é assim muito útil para a resolução de problemas de optimização como o do caminho mais curto, Spanning trees mínimas, etc. N entanto nem sempre é evidente reconhecermos quando e como No id h d podemos usar programação dinâmica. Um dos truques é tentar verificar se existe um algoritmo recursivo para recursivo, a resolução do problema pretendido, que calcula diversas vezes os mesmos sub problemas. A partir do momento que conseguimos encontrar esse algoritmo temos a certeza de que o problema pode alternativamente ser resolvido recorrendo à programação dinâmica. Programação Dinâmica
  7. 7. A partir daqui só nos resta saber como implementar um algoritmo de programação dinâmica. Como em tudo esta etapa requer essencialmente treino e experiência no uso deste tipo de programação. Inicialmente existem algumas dificuldades e tudo parece que acontece por magia mas com o tempo rapidamente conseguimos chegar a solução quase que intuitivas. Enquanto isso não vai acontecendo aqui fica uma breve metodologia para encontrar tais algoritmos mais f il il i i facilmente: 1- Caracterizar a estrutura de uma solução óptima. 2- 2 Definir recursivamente o valor de uma solução óptima. óptima 3- Calcular o valor de uma solução óptima ascendentemente (Bottom-up). 4 Tentar construir a solução recorrendo à informação obtida 4- obtida. Programação Dinâmica
  8. 8. Exemplo: Assembly-Line-Scheduling (Linha de Montagem) Programação Dinâmica
  9. 9. Etapa 1: Estrutura do melhor caminho. Programação Dinâmica
  10. 10. Etapa 2: Solução Recursiva f* = min(f1[n]+x1; f2[n]+x2) Se j = 1 temos: f1[1] = e1 + a1,1 f2[1] = e2 + a2,1 E se j > 1 temos: f1[j] = min(f1[j-1]+a1,j; f2[j-1]+t2,j-1+a1,j) f2[j] = min(f2[j-1]+a2,j; f1[j-1]+t1,j-1+a2,j) Programação Dinâmica
  11. 11. Etapa 3: Cálculo do tempo optimal f1[j] = min (f1[j-1] + a1,j, f2[j-1] + t2,j-1 + a1,j) for j > 1; f2[j] = min (f2[j-1] + a2,j, f1[j-1] + t1,j-1 + a2,j) for j > 1; f1[1] = e1 + a1,1; f2[1] = e2 + a2,1. function schedule(a[], t[], e[], x[], n) 1. 1 f1[1] ← e1 + a1,1; 1 11 2. f2[1] ← e2 + a2,1; 3. for j ← 2 to n do 4. 4 f1[j] ← min (f1[j 1] + a1 j f2[j 1] + t2 j 1 + a1 j); (f1[j-1] a1,j, f2[j-1] t2,j-1 a1,j); 5. f2[j] ← min (f2[j-1] + a2,j, f1[j-1] + t1,j-1 + a2,j); 6. /* end for */ 7 return( min( f1[n] + x1, f2[n] + x2 )); x1 7. Programação Dinâmica
  12. 12. Etapa 4: Construção do Caminho Óptimo 1. i ← l*; 2. print « linha » i « , posto » n; 3. for j ← n to 2 do 4. i ← mli[j]; 5. print « linha » i « , posto » j-1; 6. /* end for */ Resultado: linha 1, posto 6 linha 2 posto 2, 5 linha 2, posto 4 linha 1, posto 3 linha 2 posto 2 2, linha 1, posto 1 Programação Dinâmica

×