programmazione dinamica
Paolo Camurati
Dip. Automatica e Informatica
Politecnico di Torino
Limiti della ricorsione
Ipotesi di indipendenza dei sottoproblemi
Memoria occupata
FIB5 FIB5
Problema di ottimizzazione
Risolvibile con:
i modelli del Calcolo Combinatorio
(2n)
il paradigma divide et impera ricorsivo
la programmazione dinamica bottom-up (n)
Dall’esempio si indurrà la metodologia.
01assembly_line
int mCostR(int **a, int **t, int *e, int *x, int j, int i) {
int ris;
int assembly_line(int **a, int **t, int *e, int *x, int j){
return min(
mCostR(a,t, e, x, j, 0) + x[0],
mCostR(a,t, e, x, j, 1) + x[1]
);
}
}
l[0][j]=0; catena 0: vengo
else { da catena 1
f[0][j]=f[1][j-1]+t[1][j-1]+a[0][j];
l[0][j]=1;
}
if (f[1][j-1]+a[1][j]<=f[0][j-1]+t[0][j-1]+a[1][j]) {
f[1][j]=f[1][j-1]+a[1][j];
l[1][j]=1; catena 1: vengo
}
else { da catena 1
f[1][j]=f[0][j-1]+t[0][j-1]+a[1][j];
l[1][j]=0;
} catena 1: vengo
}
da catena 0
}
l[0][n] = 0; l[1][n] = 0; esco dalla catena 0
else {
res = f[1][n-1] + x[1];
l[1][n] = 1; l[0][n] = 1; esco dalla catena 1
}
return res;
}
(x, y)
(x, y)
00
[x, y, 1] · 0 0 = [x, y, 1]
0 01
A.A. 2019/20 09 La programmazione dinamica 36
Rotazione
(x’, y’)
r (x, y)
r
cos sin 0
[x, y, 1] · -sin cos 0 = [x’, y’, 1]
0 0 1
A.A. 2019/20 09 La programmazione dinamica 38
Traslazione
(x + x, y + y)
(x, y)
1 0 0
[x, y, 1] · 0 1 0 = [x+x, y+ y,1]
x y 1
A.A. 2019/20 09 La programmazione dinamica 39
Trasformazione:
[x, y, z, 1] · A1 · A2 ….. · An
(A1·(A2·(A3· A4)))
(A1·((A2·A3)· A4))
((A1·A2)·(A3· A4 ))
((A1·(A2·A3))· A4)
(((A1·A2)·A3)· A4)
1 n=1
P(n) =
1 k n-1 P(k) · P(n-k) n 2
k=1 k=3
A1..1 A2..2 A3..3 A4..4
identificazione di i e j
for (l = 2; l <= n; l++)
for (i = 1; i <= n-l+1; i++) {
j = i+l-1;
m[i][j] = INT_MAX; identificazione di k
for (k = i; k <= j-1; k++) {
q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
if (q < m[i][j]) {
m[i][j] = q; scelta calcolo costo
s[i][j] = k;
}
} visualizzazione della soluzione ottima
}
displaySol(s, 1, n);
return m[1][n];
}
4 1
j i
3 2
A1 4x4 2 3
A2 4x6 1 4
A3 6 x 15 m
A4 15 x 10
4 1
j i
p 4 4 6 15 10 3 2
2 3
s
A.A. 2019/20 09 La programmazione dinamica 60
4 1
j i
3 2
m[1,1] = 0
2 3
m[2,2] = 0
1 4
m[3,3] = 0 0 0 0 0
m
m[4,4] = 0
4 1
j i
3 2
2 3
Catene lunghe 1 s 1
A.A. 2019/20 09 La programmazione dinamica 61
m[1,2] = m[1,1] + m[2,2] + p0p1p2 = 96
4 1
k=1 j i
3 2
2 3
1 96 4
m
0 0 0 0
4 1
j i
3 2
2 3
Catene lunghe 2: A1..2 s 1
A.A. 2019/20 09 La programmazione dinamica 62
m[2,3] = m[2,2] + m[3,3] + p1p2p3 = 360
4 1
k=2 j i
3 2
2 3
1 96 360 4
m
0 0 0 0
4 1
j i
3 2
2 3
Catene lunghe 2: A2..3 s 1 2
A.A. 2019/20 09 La programmazione dinamica 63
m[3,4] = m[3,3] + m[4,4] + p2p3p4 = 900
4 1
k=3 j i
3 2
2 3
1 96 360 900 4
m
0 0 0 0
4 1
j i
3 2
2 3
Catene lunghe 2: A3..4 s 1 2 3
A.A. 2019/20 09 La programmazione dinamica 64
4 1
m[1,3] = m[1,1] + m[2,3] j i
3 2
+ p0p1p3 = 360+ 240 =600
2 456 3
k=1 1 96 360 900 4
m[1,3] = m[1,2] + m[3,3] m 0 0 0 0
+ p0p2p3 = 96 + 360 = 456
4 1
k=2 j i
3 2
2 2 3
Catene lunghe 3: A1..3 s 1 2 3
A.A. 2019/20 09 La programmazione dinamica 65
4 1
m[2,4] = m[2,2] + m[3,4] j i
3 2
+ p1p2p4 = 900 + 240 =1140
2 456 960 3
k=2 1 96 360 900 4
m[2,4] = m[2,3] + m[4,4] m 0 0 0 0
+ p1p3p4 = 360 + 600= 960
4 1
k=3 j i
3 2
2 2 3 3
Catene lunghe 3: A2..4 s 1 2 3
A.A. 2019/20 09 La programmazione dinamica 66
Catena lunga 4: A1..4
T(n) = (n3)
S(n) = (n2)
rispetto al costo esponenziale nel tempo della
soluzione ricorsiva
4 1
j i
3 3 2
2 2 3 3
s 1 2 3
A.A. 2019/20 09 La programmazione dinamica 69
4 1
j i
3 3 2 A1…4 = (A1…3) x A4
2 2 3 3
s 1 2 3
4 1 A1…4 = (A1…3) x A4
j i
3 3 2 = ((A1…2) x A3) x A4
2 2 3 3
s 1 2 3
4 1 A1…4 = (A1…3) x A4
j i
3 3 2 = ((A1…2) x A3) x A4
2 2 3 3 = ((A1)x(A2)) x A3) x A4
s 1 2 3
A.A. 2019/20 09 La programmazione dinamica 70
Applicabilità della
programmazione dinamica
Esistenza di una sottostruttura ottima
Esistenza di molti sottoproblemi in comune:
s v
ricorsione bottom-up
iterazione
val 6 3 5 2 7 8 1 i=1
L 1 1 LIS={3}
P -1 -1
val 6 3 5 2 7 8 1 i=2
L 1 1 2 LIS={3,5}
P -1 -1 1
val 6 3 5 2 7 8 1 i=5
L 1 1 2 1 3 4 LIS={3,5,7,8}
P -1 -1 1 -1 2 4
val 6 3 5 2 7 8 1 i=6
L 1 1 2 1 3 4 1 LIS={3,5,7,8}
P -1 -1 1 -1 2 4 -1
A.A. 2019/20 09 La programmazione dinamica 90
calcolo del costo minimo e di una soluzione ottima
#define N 7
Sottosequenza comune: C G A
Sottosequenze comuni di lunghezza massima
(LCS): C G C A C T A C
LCS:
GTCGTCGGAAGCCGGCCGAA
X= A B C B D A B Y=B D C A B
0 1 2 3 4 5 m-1 0 1 2 3 n-1
B
|W| + 1 = k
contraddice l’ipotesi
A.A. 2019/20 09 La programmazione dinamica 104
2. se xm-1yn-1 e zk-1xm-1, allora Z è:
I. ovviamente una sottosequenza comune del
prefisso Xm−2 e di Y
II. di lunghezza massima. Per assurdo, se non lo
fosse, allora esisterebbe una sottosequenza
W comune a Xm−2 e Y tale che |W| > |Z| = k.
Il fatto che zk-1xm-1 implica che W sia anche
una sottosequenza comune di X=Xm-1 e Y, ma
essendo |W| > k si contraddice l’ipotesi.
Z= C G C A
0 1 2 k-1
contraddice l’ipotesi
0 se i=0 e j=0
c[i, j]= c[i-1,j-1]+1 se xi = yj
max{c[i,j-1], c[i-1,j]) se xi yj
Strutture dati:
tabella c[0…m, 0…n] per memorizzare le
lunghezze c[i, j] dei prefissi Xi e Yj
tabella b[0…m, 0…n] per la costruzione
dalla LCS
c= 0 0 0 0 0 0 0 b= 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
c= 0 0 0 0 0 0 0 b= 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
c= 0 0 0 0 0 0 0 b= 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
c= 0 0 0 0 0 0 0 b= 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
c= 0 0 0 0 0 0 0 b= 0 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
c= 0 0 0 0 0 0 0 b= 0 0 0 0 0 0 0
0 0 0 0 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
etc.
A.A. 2019/20 09 La programmazione dinamica 122
X= A B C B D A B Y= B D C A B A
i j
c= 0 0 0 0 0 0 0 b= 0 0 0 0 0 0 0
0 0 0 0 1 1 1 0
0 1 1 1 1 2 2 0
0 1 1 2 2 2 2 0
0 1 1 2 2 3 3 0
0 1 2 2 2 3 3 0
0 1 2 2 3 3 4 0
0 1 2 2 3 4 4 0
configurazione finale
c= 0 0 0 0 0 0 0 b= 0 0 0 0 0 0 0
0 0 0 0 1 1 1 0
0 1 1 1 1 2 2 0
0 1 1 2 2 2 2 0
0 1 1 2 2 3 3 0
0 1 2 2 2 3 3 0
0 1 2 2 3 3 4 0
0 1 2 2 3 4 4 0
Z= B C B A
jS vj xj = MAX
xj {0,1}
Soluzione ottima:
insieme {B, C, D} con valore massimo 23
A.A. 2019/20 09 La programmazione dinamica 128
Struttura della soluzione ottima
Strutture dati:
tabella maxVal[0…N, 0…cap] per memorizzare i
valori e identificare il massimo
non serve un’ulteriore struttura dati per la
costruzione dalla soluzione
}
return maxval[N][cap]; visualizzazione di una
soluzione ottima
A.A. 2019/20 09 La programmazione dinamica 138
Soluzione ottima: costruzione
void displaySol(Item *items, int N, int cap, int **maxval){
int i, j, *sol;
sol = calloc(N, sizeof(int));
j = cap;
for (i=N; i>=1; i--)
if (maxval[i][j] == maxval[i-1][j])
sol[i-1] = 0;
else { oggetto non preso
sol[i-1] = 1;
j-= items[i-1].size;
}
for (i=0; i<N; i++) oggetto preso
if (sol[i])
ITEMstore(items[i]);
}
visualizzazione degli oggetti presi
configurazione finale
Soluzione:
insieme {B, C, D} con valore massimo 23
array knownF
unsigned long fib(int n, unsigned long *knownF) {
unsigned long t;
if (knownF[n] != -1)
return knownF[n];
if(n == 0 || n == 1) {
knownF[n] = n;
return(n);
}
t = fib(n-2, knownF) + fib(n-1, knownF);
knownF[n] = t;
return t;
}
jS vj xj = MAX
xj {0,1}
Programmazione dinamica:
Cormen 16
Montresor 13
Crescenzi 2.7
Problema del ladro e dello zaino:
Sedgewick 5.3
8. Programmazione dinamica
8.1 Prodotto in catena di matrici
8.2 Longest Common Subsequence