Prog Din08
-
Upload
joel-carvalho -
Category
Documents
-
view
878 -
download
1
description
Transcript of Prog Din08
Wikipedia.org
Programação dinâmica é um método para a construção de algoritmospara a resolução de problemas computacionais, em especial os deoptimização combinatória. Ela é aplicável a problemas no qual a soluçãoóptima pode ser computada a partir da solução óptima previamentecalculada e memorizada - de forma a evitar recalculo - de outros subproblemas que, sobrepostos, compõem o problema original.
Exemplo (Fibonacci):
var m : map(0 1 1 1)var m := map(0 → 1, 1 → 1)function fib(n)
if map m does not contain key nm[n] := fib(n 1) + fib(n 2)m[n] := fib(n − 1) + fib(n − 2)
return m[n]
Programação Dinâmica
Solução Sem Programação Dinâmica:
function fib(n)if n = 0 or n = 1
return 1else
return fib(n − 1) + fib(n − 2)
fib(5)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(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
No entanto se usarmos o algoritmo anteriormente referido verificamosque 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 nm[n] := fib(n − 1) + fib(n − 2)[ ]return m[n]
b( ) b( ) b( ) b( ) b( ) b( )Fib(0) Fib(1) Fib(2) Fib(3) Fib(4) Fib(5)1 1 1+1=2 1+2=3 2+3=5 3+5=8
Programação Dinâmica
Cálculo de combinações sem repetição (coeficiente binomial):
CCC n
r
n
r
n
r
11
1
−−
−+=r
1 - - - -
1 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
// 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 j ) b [j][j] 1for (j=0; j<=n; j++) bc[j][j] = 1;
for (i=1; i<=n; i++)for (j 1; j<i; j++)for (j=1; j<i; j++)
bc[i][j] = bc[i-1][j-1] + bc[i-1][j];
return( bc[n][m] );return( bc[n][m] );}
Programação Dinâmica
A programação dinâmica não serve apenas para satisfazer anecessidade 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 anível do uso de memória.
Este método é assim muito útil para a resolução de problemas deoptimização como o do caminho mais curto, Spanning trees mínimas,
N é id h detc. No entanto nem sempre é evidente reconhecermos quando e comopodemos usar programação dinâmica.
Um dos truques é tentar verificar se existe um algoritmo recursivo paraUm dos truques é tentar verificar se existe um algoritmo recursivo, paraa resolução do problema pretendido, que calcula diversas vezes osmesmos sub problemas. A partir do momento que conseguimosencontrar esse algoritmo temos a certeza de que o problema podeencontrar esse algoritmo temos a certeza de que o problema podealternativamente ser resolvido recorrendo à programação dinâmica.
Programação Dinâmica
A partir daqui só nos resta saber como implementar um algoritmo deprogramação dinâmica. Como em tudo esta etapa requeressencialmente treino e experiência no uso deste tipo de programação.Inicialmente existem algumas dificuldades e tudo parece que acontecepor magia mas com o tempo rapidamente conseguimos chegar asolução quase que intuitivas.
Enquanto isso não vai acontecendo aqui fica uma breve metodologiai l i i f ilpara encontrar tais algoritmos mais facilmente:
1- Caracterizar a estrutura de uma solução óptima.2 Definir recursivamente o valor de uma solução óptima2- Definir recursivamente o valor de uma solução óptima.3- Calcular o valor de uma solução óptima ascendentemente
(Bottom-up).4 Tentar construir a solução recorrendo à informação obtida4- Tentar construir a solução recorrendo à informação obtida.
Programação Dinâmica
Exemplo: Assembly-Line-Scheduling (Linha de Montagem)
Programação Dinâmica
Etapa 1: Estrutura do melhor caminho.
Programação Dinâmica
Etapa 2: Solução Recursiva
f* = min(f1[n]+x1; f2[n]+x2)
Se j = 1 temos:f [1]f1[1] = e1 + a1,1f2[1] = e2 + a2,1
E se j > 1 temos: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
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 f1[1] 1 1 11. f1[1] ← e1 + a1,1;2. f2[1] ← e2 + a2,1;3. for j ← 2 to n do4 f1[j] min (f1[j 1] + a1 j f2[j 1] + t2 j 1 + a1 j);4. f1[j] ← min (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 ));7. return( min( f1[n] + x1, f2[n] + x2 ));
Programação Dinâmica
Etapa 4: Construção do Caminho Óptimo
1. i ← l*;2. print « linha » i « , posto » n;3. for j ← n to 2 do4. i ← mli[j];5. print « linha » i « , posto » j-1;6. /* end for */
Resultado:linha 1, posto 6linha 2 posto 5linha 2, posto 5linha 2, posto 4linha 1, posto 3linha 2 posto 2linha 2, posto 2linha 1, posto 1
Programação Dinâmica