Documentos de Académico
Documentos de Profesional
Documentos de Cultura
4-Programacion Dinamica PDF
4-Programacion Dinamica PDF
Introducción 2
El problema de la mochila 0-1 7
Camino de coste mínimo en
un grafo multietapa 17
Multiplicación de una secuencia
de matrices 30
Comparaciones de secuencias 40
Caminos mínimos entre todos
los pares de nodos de un grafo 47
Árboles binarios de búsqueda
óptimos 53
Un problema de fiabilidad
de sistemas 64
El problema del viajante
de comercio 69
Planificación de trabajos 79
Una competición internacional 92
Triangulación de polígonos 98
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 1
Programación dinámica:
Introducción
sujeto a ∑ pi xi ≤ C
1≤i ≤n
Ejemplo:
n=3 C=15
(b1,b2,b3)=(38,40,24)
(p1,p2,p3)=(9,6,5)
Más formalmente:
– Sea E0 el estado inicial del problema.
– Sea D1 = {v 11 ,K,v 1n 1 } el conjunto de valores de
decisión posibles para la decisión d1.
– Sea E1i el estado del problema tras la elección del
valor v1i, 1≤i≤n1.
– Sea S1i una secuencia óptima de decisiones
respecto al estado E1i.
con xi ∈{0,1}, k ≤ i ≤ l
Principio de optimalidad:
Sea y1,…,yn una secuencia óptima de valores 0-1
para x1,…,xn.
– Si y1=0, entonces y2,…,yn forman una secuencia
óptima para el problema mochila(2,n,C).
– Si y1=1, entonces y2,…,yn forman una secuencia
óptima para el problema mochila(2,n,C-p1).
Demostración: Si existe una solución mejor y˜ 2 ,K, y˜n
para el problema correspondiente,
entonces y1 , y˜ 2 ,K, y˜n es mejor
que y1 , y2 ,K, yn para el problema mochila(1,n,C),
en contra de la
hipótesis.
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 7
El problema de la mochila 0-1
⎛ j ⎞
mochila ⎜ j + 1,n ,C − ∑ pi xi ⎟
⎝ i=1 ⎠
v
– Si g j (c ) es el beneficio (o ganancia total) de una
solución óptima de mochila(j,n,c), entonces
v
{ v v
}
g j (c) = max g j + 1(c ), g j+ 1(c − p j ) + b j
– Además,
v
gn + 1 (c ) = 0, para cualquier capacidad c
v
Ambas ecuaciones permiten calcular g1 (C) ,
que es el valor de una solución óptima de
mochila(1,n,C).
w
– Si g j (c ) es el beneficio (o ganancia total) de una
solución óptima de mochila(1,j,c), entonces
w
{
w w
g j (c ) = max g j − 1(c), g j − 1(c − p j ) + b j }
dependiendo de que el objeto j-ésimo entre o no
en la solución (nótese que sólo puede entrar si
c-pj≥0).
– Además,
w
g0 (c ) = 0, para cualquier capacidad c
w
Ambas ecuaciones permiten calcular gn (C) ,
que es el valor de una solución óptima de
mochila(1,n,C).
función mochila1(p,b:vector[1..n]
función mochila1(p,b:vector[1..n] de de nat;
nat;
C:nat) devuelve nat
C:nat) devuelve nat
principio
principio
devuelve g(n,C)
devuelve g(n,C)
fin
fin
función g(j,c:nat)
función devuelve nat
g(j,c:nat) devuelve nat
principio
principio
si j=0
si j=0 entonces devuelve 00
entonces devuelve
sino
sino
si c<p[j]
si c<p[j]
entonces devuelve g(j-1,c)
entonces devuelve g(j-1,c)
sino
sino
si g(j-1,c)≥≥g(j-1,c-p[j])+b[j]
si g(j-1,c) g(j-1,c-p[j])+b[j]
entonces
entonces
devuelve g(j-1,c)
devuelve g(j-1,c)
sino
sino
devuelve g(j-1,c-p[j])+b[j]
devuelve g(j-1,c-p[j])+b[j]
fsi
fsi
fsi
fsi
fsi
fsi
fin
fin
Problema: ineficiencia
– Un problema de tamaño n se reduce a dos
subproblemas de tamaño (n-1).
– Cada uno de los dos subproblemas se reduce a
otros dos…
Por tanto, se obtiene un algoritmo exponencial.
el segundo, C valores.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
p1 = 9 0 0 0 0 0 0 0 0 0 38 38 38 38 38 38 38
p2 = 6 0 0 0 0 0 0 40 40 40 40 40 40 40 40 40 78
p3 = 5 0 0 0 0 0 24 40 40 40 40 40 64 64 64 64 78
w w
{ w
g j (c ) = max g j − 1(c) , g j − 1(c − p j ) + b j }
algoritmo mochila(ent
algoritmo mochila(ent p,b:vect[1..n]de
p,b:vect[1..n]de nat;
nat;
ent Cap:nat;
ent Cap:nat;
sal g:vect[0..n,0..Cap]de
sal g:vect[0..n,0..Cap]de nat)
nat)
variables c,j:nat
variables c,j:nat
principio
principio
para c:=0
para hasta Cap
c:=0 hasta hacer g[0,c]:=0
Cap hacer g[0,c]:=0 fpara;
fpara;
para j:=1
para hasta nn hacer
j:=1 hasta hacer g[j,0]:=0
g[j,0]:=0 fpara;
fpara;
para j:=1
para hasta nn hacer
j:=1 hasta hacer
para c:=1
para hasta Cap
c:=1 hasta Cap hacer
hacer
si c<p[j]
si c<p[j]
entonces
entonces
g[j,c]:=g[j-1,c]
g[j,c]:=g[j-1,c]
sino
sino
si g[j-1,c]≥≥g[j-1,c-p[j]]+b[j]
si g[j-1,c] g[j-1,c-p[j]]+b[j]
entonces
entonces
g[j,c]:=g[j-1,c]
g[j,c]:=g[j-1,c]
sino
sino
g[j,c]:=g[j-1,c-p[j]]+b[j]
g[j,c]:=g[j-1,c-p[j]]+b[j]
fsi
fsi
fsi
fsi
fpara
fpara
fpara
fpara
fin
fin
algoritmo objetos(ent
algoritmo objetos(ent p,b:vect[1..n]de
p,b:vect[1..n]de nat;
nat;
ent Cap:nat;
ent Cap:nat;
ent g:vect[0..n,0..Cap]de
ent g:vect[0..n,0..Cap]de nat)
nat)
principio
principio
test(n,Cap)
test(n,Cap)
fin
fin
algoritmo test(ent
algoritmo test(ent j,c:nat)
j,c:nat)
principio
principio
si j>0
si j>0 entonces
entonces
si c<p[j] entonces test(j-1,c)
si c<p[j] entonces test(j-1,c)
sino
sino
si g[j-1,c-p[j]]+b[j]>g[j-1,c]
si g[j-1,c-p[j]]+b[j]>g[j-1,c]
entonces
entonces
test(j-1,c-p[j]);
test(j-1,c-p[j]);
escribir('meter
escribir('meter ',j)
',j)
sino test(j-1,c)
sino test(j-1,c)
fsi
fsi
fsi
fsi
fsi
fsi
fin
fin
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 15
El problema de la mochila 0-1
Consideraciones finales
Grafo multietapa:
– Un grafo multietapa G=(V,A) es un grafo
dirigido en el que se puede hacer una partición
del conjunto V de vértices en k (k≥2) conjuntos
distintos Vi, 1≤i≤k, tal que todo arco del grafo
(u,v) es tal que u∈Vi y v∈Vi+1 para algún i, 1≤i<k.
– Los conjuntos V1 y Vk tienen un solo vértice que
se llama vértice origen, o, y vértice destino, d,
respectivamente.
V1 V2 V3 V4 V5
2 3
8
7 5
5 1 5 11
7 9
o 1 3 4 6 8 10 d
2 5 6 4
12
4 9 9
V1 V2 V3 V4 V5
2 3
8
7 5
5 1 5 11
7 9
o 1 3 4 6 8 10 d
2 5 6 4
12
4 9 9
Ejemplo de aplicación:
– Se tienen n unidades de un recurso que deben
asignarse a r proyectos.
– Si se asignan j, 0≤j≤n, unidades al proyecto i se
obtiene un beneficio Ni,j.
– El problema es asignar el recurso a los r
proyectos maximizando el beneficio total.
N 2,0
v2,0 v3,0
N 1,0
max {N 3,i }
i= 0,1,2,3,4
N 2,1
v2,1 N 2,0
v3,1
N 1,1
N 2,2 max {N 3,i }
N 2,3 i= 0,1,2,3
N max {N 3,i }
N 2,1 N 2,2 2,3 i= 0,1
N 1,3 N 2,2
v2,3 v3,3
N 2,0
N 2,1 N 3,0
N 1,4 N 2,4
v2,4 v3,4
N 2,0
– Principio de optimalidad:
C∗ (i , j) = min
l∈V i+ 1
{c( j ,l) + C∗ (i + 1,l)}, para 1≤ i ≤ k − 2
( j ,l)∈A
V1 V2 V3 V4 V5
2 3
8
7 5
5 1 5 11
7 9
o 1 3 4 6 8 10 d
2 5 6 4
12
4 9 9
C∗ (i , j) = min
l∈V i+ 1
{c( j ,l) + C∗ (i + 1,l)}, para 1≤ i ≤ k − 2
( j ,l)∈A
V1 V2 V3 V4 V5
2 3
8
7 5
5 1 5 11
7 9
o 1 3 4 6 8 10 d
2 5 6 4
12
4 9 9
c( j ,l) + C∗ (i + 1,l).
Entonces el camino de coste mínimo es:
v1=1; v2=D(1,1); v3=D(2,D(1,1)); etc.
V1 V2 V3 V4 V5
2 3
8
7 5
5 1 5 11
7 9
o 1 3 4 6 8 10 d
2 5 6 4
12
4 9 9
D(3, 5) = 7 ; D(3,6) = 8
D(2, 2) = 6; D(2, 3) = 5; D(2, 4) = 5
D(1,1) = 2
v1 = 1
v 2 = D(1,1) = 2
v 3 = D(2,D(1,1)) = 6
v 4 = D(3,D(2,D(1,1))) = 8
algoritmo multietapa(ent
algoritmo multietapa(ent G=(V,A,c):grafo;
G=(V,A,c):grafo;
ent k,n:nat;
ent k,n:nat;
sal P:vect[1..k]de
sal P:vect[1..k]de 1..n)
1..n)
{Los
{Los vértices
vértices están
están numerados
numerados de de forma
forma que
que los
los
índices
índices de
de los
los vértices
vértices de de una
una etapa
etapa son
son mayores
mayores
que los índices de los de la etapa anterior.
que los índices de los de la etapa anterior.
El *
El primer
primer índice
índice de
de CC* yy D,
D, que
que sólo
sólo identificaba
identificaba
la etapa, se ha suprimido.}
la etapa, se ha suprimido.}
variables C:vect[1..n]de
variables C:vect[1..n]de real;
real;
D:vect[1..n]de
D:vect[1..n]de 1..n;
1..n;
j,r:1..n
j,r:1..n
principio
principio
C[n]:=0.0; *
C[n]:=0.0; {Cálculo
{Cálculo de
de CC* yy D}
D}
para j:=n-1
para j:=n-1 descendiendo
descendiendo hastahasta 11 hacer
hacer
r:=vértice
r:=vértice t.q. (j,r)∈∈AA ∧∧
t.q. (j,r)
c(j,r)+C[r]
c(j,r)+C[r] es es mínimo;
mínimo;
C[j]:=c(j,r)+C[r];
C[j]:=c(j,r)+C[r];
D[j]:=r
D[j]:=r
fpara;
fpara;
P[1]:=1;
P[1]:=1; P[k]:=n;
P[k]:=n; {Construcción
{Construcción del del camino}
camino}
para j:=2
para hasta k-1
j:=2 hasta k-1 hacer
hacer
P[j]:=D[P[j-1]]
P[j]:=D[P[j-1]]
fpara
fpara
fin
fin
Análogamente, se desarrolla la
recurrencia hacia atrás.
– Ecuación de recurrencia hacia atrás:
Sea s(i,j) un camino de coste mínimo C*(i,j)
desde el vértice origen o hasta el vértice j del
conjunto Vi.
Entonces:
⎧c(o, j) , si (o, j) ∈ A
C∗ (2, j) = ⎨
⎩∞ , en otro caso
C∗ (i , j) = min
l∈V i− 1
{c(l , j) + C∗ (i − 1,l)}, para 3≤ i ≤ k
(l , j)∈A
V1 V2 V3 V4 V5
2 3
8
7 5
5 1 5 11
7 9
o 1 3 4 6 8 10 d
2 5 6 4
12
4 9 9
n −1
T (n) = ∑ T (i)T (n − i) , para n > 1
i =1
T (1) = 1
Números de Catalan
Por ejemplo:
n 1 2 3 4 5 10 15
T (n) 1 1 2 5 14 4862 2674440
Método:
– Construir la matriz [mij], 1≤i≤j≤n, donde mij da el
óptimo (i.e., el número de multiplicaciones
escalares requeridas) para la parte Mi Mi +1LM j
del producto total.
– La solución final vendrá dada por m1n.
s = 0: mi ,i = 0, para i = 1, 2,K,n
para i = 1, 2,K,n − s
⎧0, si i = j
mij = ⎨ min {m + m
ik k + 1, j + di − 1dkd j }, si i < j
⎩ i ≤ k< j
j =1 2 3 4
– La matriz es: i = 1 0 5785 1530 2856
s=3
2 0 1335 1845
s=2
3 0 9078
s =1
4 0
s =0
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 35
Multiplicación de una
secuencia de matrices
algoritmo parentOpt(ent
algoritmo parentOpt(ent d:vect[0..n]de
d:vect[0..n]de nat;
nat;
sal m:vect[1..n,1..n]de
sal m:vect[1..n,1..n]de nat;
nat;
sal km:vect[1..n,1..n]de
sal km:vect[1..n,1..n]de 1..n)
1..n)
{m
{m es
es la
la matriz
matriz [m
[mijij]] definida
definida antes;
antes;
km[i,j]
km[i,j] guarda
guarda el
el índice
índice kk para
para el
el que
que se
se alcanza
alcanza
el
el mínimo
mínimo alal calcular
calcular m[i,j].}
m[i,j].}
variables i,r,j,k,q:nat;
variables i,r,j,k,q:nat;
principio
principio
para i:=1
para hasta nn hacer
i:=1 hasta hacer
m[i,i]:=0
m[i,i]:=0
fpara;
fpara;
para r:=2
para hasta nn hacer
r:=2 hasta hacer
para i:=1
para hasta n-r+1
i:=1 hasta n-r+1 hacer
hacer
j:=i+r-1;
j:=i+r-1;
m[i,j]:=∞∞;;
m[i,j]:=
para k:=i
para hasta j-1
k:=i hasta j-1 hacer
hacer
q:=m[i,k]+m[k+1,j]+d[i-1]*d[k]*d[j];
q:=m[i,k]+m[k+1,j]+d[i-1]*d[k]*d[j];
si q<m[i,j]
si q<m[i,j]
entonces
entonces
m[i,j]:=q;
m[i,j]:=q;
km[i,j]:=k
km[i,j]:=k
fsi
fsi
fpara
fpara
fpara
fpara
fpara
fpara
fin
fin
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 37
Multiplicación de una
secuencia de matrices
Coste en tiempo:
– Θ(n3)
Coste en memoria:
– Θ(n2)
función multSec(M:vect[1..n]de
función multSec(M:vect[1..n]de matriz;
matriz;
km:vect[1..n,1..n]de
km:vect[1..n,1..n]de 1..n;
1..n;
i,j:1..n)
i,j:1..n)
devuelve matriz
devuelve matriz
variables X,Y:matriz
variables X,Y:matriz
principio
principio
si j>i
si j>i
entonces
entonces
X:=multSec(M,km,i,km[i,j]);
X:=multSec(M,km,i,km[i,j]);
Y:=multSec(M,km,km[i,j]+1,j];
Y:=multSec(M,km,km[i,j]+1,j];
devuelve mult(X,Y)
devuelve mult(X,Y)
sino
sino
devuelve M[i]
devuelve M[i]
fsi
fsi
fin
fin
Una solución:
abbc babb
bbc babc
2: insertar a
abbc babb
1: insertar b 2: borrar c
babbc
– Si denotamos:
⎧0, si ai = bj
c(i , j) = ⎨
⎩1, si ai ≠ bj
– Se tiene:
⎧⎪C (n − 1, m ) + 1 (borrando an )
C (n, m) = min ⎨C (n , m - 1) + 1 (insertando bm )
⎪⎩C (n − 1, m − 1) + c(n , m ) (otros casos)
C (i , 0) = i , for all i , 0 ≤ i ≤ n
C (0, j) = j , for all j, 0 ≤ j ≤ m
– Orden de cálculo: j
i ?
algoritmo compSec(ent
algoritmo compSec(ent A:cad[n];
A:cad[n];
ent B:cad[m];
ent B:cad[m];
sal C:vect[0..n,0..m]de
sal C:vect[0..n,0..m]de nat;
nat;
sal T:vect[1..n,1..m]de
sal T:vect[1..n,1..m]de Transf)
Transf)
{Transf=tipo
{Transf=tipo de
de las
las posibles
posibles transformaciones;
transformaciones;
Transf=(borrar,insert,sustit,nada)}
Transf=(borrar,insert,sustit,nada)}
variables i,j,x,y,z:nat
variables i,j,x,y,z:nat
principio
principio
para i:=0
para hasta nn hacer
i:=0 hasta hacer C[i,0]:=i
C[i,0]:=i fpara;
fpara;
para j:=0
para hasta mm hacer
j:=0 hasta hacer C[0,j]:=j
C[0,j]:=j fpara;
fpara;
para i:=1
para hasta nn hacer
i:=1 hasta hacer
para j:=1
para hasta mm hacer
j:=1 hasta hacer
x:=C[i-1,j]+1;
x:=C[i-1,j]+1; y:=C[i,j-1]+1;
y:=C[i,j-1]+1;
si A[i]=B[j]
si A[i]=B[j]
entonces
entonces
z:=C[i-1,j-1]
z:=C[i-1,j-1]
sino
sino
z:=C[i-1,j-1]+1
z:=C[i-1,j-1]+1
fsi;
fsi;
C[i,j]:=min(x,y,z);
C[i,j]:=min(x,y,z);
T[i,j]:=Transf(x,y,z)
T[i,j]:=Transf(x,y,z)
{T[i,j]
{T[i,j] es
es el
el último
último cambio
cambio que
que da
da el
el
mínimo
mínimo valor
valor aa C[i,j]}
C[i,j]}
fpara
fpara
fpara
fpara
fin
fin
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 44
Comparaciones de secuencias
algoritmo res(ent
algoritmo res(ent i,j:nat)
i,j:nat)
{Para
{Para resolver
resolver el
el problema,
problema, ejecutar
ejecutar res(n,m).}
res(n,m).}
variable k:nat
variable k:nat
principio
principio
selección
selección
i=0: para k:=1
i=0: para hasta jj hacer
k:=1 hasta hacer
escribir('Añadir',B[k],'en
escribir('Añadir',B[k],'en el el
lugar',k)
lugar',k)
fpara
fpara
j=0: para k:=1
j=0: para hasta ii hacer
k:=1 hasta hacer
escribir('Borrar
escribir('Borrar car.nº',k)
car.nº',k)
fpara
fpara
otros:
otros:
selección
selección
T[i,j]=borrar:
T[i,j]=borrar: res(i-1,j);
res(i-1,j);
escribir('Borrar
escribir('Borrar car.nº',i)
car.nº',i)
T[i,j]=insert:
T[i,j]=insert: res(i,j-1);
res(i,j-1);
escribir('Insertar
escribir('Insertar car.nº',j,
car.nº',j,
'de
'de BB tras
tras la
la posición',i)
posición',i)
T[i,j]=sustit:
T[i,j]=sustit: res(i-1,j-1);
res(i-1,j-1);
escribir('Sustit.
escribir('Sustit. car.nº',i,
car.nº',i,
'de
'de AA por
por nº',j,'de
nº',j,'de B')
B')
T[i,j]=nada:
T[i,j]=nada: res(i-1,j-1)
res(i-1,j-1)
fselección
fselección
fselección
fselección
fin
fin
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 45
Comparaciones de secuencias
Coste:
– En tiempo: Θ(nm)
– En espacio: Θ(nm)
R.W. Floyd:
“Algorithm 97: Shortest path”,
Communications of the ACM, 5(6), p. 345, 1962.
Problema:
Cálculo de los caminos de coste mínimo entre
todos los pares de vértices de un grafo dirigido
sin ciclos de peso negativo.
Principio de optimalidad:
Si i1, i2, …, ik, ik+1, …, in es un camino de coste
mínimo de i1 a in, entonces:
i1, i2, …, ik es un camino de coste mínimo de
i1 a ik, y
ik, ik+1, …, in es un camino de coste mínimo
de ik a in.
Dk (i , j) = Dk − 1 (i ,k ) + Dk − 1 (k , j)
En resumen:
– Se tiene la siguiente ecuación recurrente que
define el método de programación dinámica.
{ }
Dk (i , j) = min Dk − 1 (i , j) , Dk − 1 (i ,k ) + Dk − 1 (k , j) ,
k ≥1
D0 (i , j) = C (i , j) , 1 ≤ i ≤ n , 1 ≤ j ≤ n
{Pre:
{Pre: gg es
es un
un grafo
grafo dirigido
dirigido etiquetado
etiquetado sin
sin
ciclos negativos}
ciclos negativos}
función Floyd(g:grafo)
función Floyd(g:grafo)
devuelve
devuelve vector[vért,vért] de etiq
vector[vért,vért] de etiq
variables D:vector[vért,vért]
variables de etiq;
D:vector[vért,vért] de etiq;
u,v,w:vért;
u,v,w:vért; et,val:etiq
et,val:etiq
principio
principio
{inicialmente
{inicialmente la
la distancia
distancia entre
entre dos
dos vértices
vértices
tiene el valor de la arista que los
tiene el valor de la arista que los une; une;
las
las diagonales
diagonales se
se ponen
ponen aa cero}
cero}
para todo vv en
para todo en vért
vért hacer
hacer
para todo ww en
para todo en vért
vért hacer
hacer
D[v,w]:=etiqueta(g,v,w)
D[v,w]:=etiqueta(g,v,w)
{∞
{∞ si
si no
no hay
hay arco}
arco}
fpara;
fpara;
D[v,v]:=0
D[v,v]:=0
fpara;
fpara;
...
...
...
...
para todo uu en
para todo en vért
vért hacer
hacer
para todo vv en
para todo en vért
vért hacer
hacer
para todo ww en
para todo en vért
vért hacer
hacer
si D[v,u]+D[u,w]<D[v,w]
si D[v,u]+D[u,w]<D[v,w]
entonces D[v,w]:=D[v,u]+D[u,w]
entonces D[v,w]:=D[v,u]+D[u,w]
fsi
fsi
fpara
fpara
fpara
fpara
fpara;
fpara;
devuelve DD
devuelve
fin
fin
{Post:
{Post: D=caminosMínimos(g)}
D=caminosMínimos(g)}
C=2,43
al eso
eso • Solución 2:
a ama si su C=2,70
ama
• Solución 3:
a si
Es óptima.
C=2,15 al eso su
sin
– Entonces:
Cijk = mij + Ci , k − 1 + Ckj
{ }
Cij = mij + min Ci , k − 1 + Ckj , si 0 ≤ i < j ≤ n
i < k≤ j
Cii = 0, si 0 ≤ i ≤ n
{ }
Cij = mij + min Ci , k − 1 + Ckj , si 0 ≤ i < j ≤ n
i < k≤ j
Cii = 0, si 0 ≤ i ≤ n
0 1 2 3 4 5 6 7
0 0 0,22 0,58 1,02 1,17 1,83 1,89 2,15
7º
1 0 0,18 0,56 0,66 1,21 1,27 1,53
6º
2 0 0,20 0,30 0,80 0,84 1,02
5º
3 0 0,05 0,35 0,39 0,57
C= 4º
4 0 0,25 0,29 0,47
3º
5 0 0,02 0,12
2º
6 0 0,08
1º
7 0
algoritmo abbÓpt(ent
algoritmo abbÓpt(ent p:probP; ent q:probQ;
p:probP; ent q:probQ;
sal C:matC;
sal sal r:matSol)
C:matC; sal r:matSol)
{C
{C es
es la
la matriz
matriz definida
definida previamente.
previamente.
En
En cada componente i,j de rr se
cada componente i,j de se guarda
guarda el
el kk
para
para elel que
que C[i,j]
C[i,j] resulta
resulta mínimo.}
mínimo.}
variables i,j,k,d:entero;
variables i,j,k,d:entero;
min,aux:real;
min,aux:real;
m:matC
m:matC
principio
principio
para i:=0
para hasta nn hacer
i:=0 hasta hacer
C[i,i]:=0;
C[i,i]:=0;
m[i,i]:=q[i];
m[i,i]:=q[i];
para j:=i+1
para hasta nn hacer
j:=i+1 hasta hacer
m[i,j]:=m[i,j-1]+p[j]+q[j]
m[i,j]:=m[i,j-1]+p[j]+q[j]
fpara
fpara
fpara;
fpara;
para j:=1
para hasta nn hacer
j:=1 hasta hacer
C[j-1,j]:=m[j-1,j];
C[j-1,j]:=m[j-1,j];
r[j-1,j]:=j
r[j-1,j]:=j
fpara;
fpara;
{Ya
{Ya están
están determinados
determinados los
los árboles
árboles de
de 11 nodo.}
nodo.}
...
...
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 59
Árboles binarios de búsqueda
óptimos
...
...
para d:=2
para hasta nn hacer
d:=2 hasta hacer
para j:=d
para hasta nn hacer
j:=d hasta hacer
i:=j-d;
i:=j-d;
min:=maxEntero;
min:=maxEntero;
para k:=i+1
para hasta jj hacer
k:=i+1 hasta hacer
aux:=C[i,k-1]+C[k,j];
aux:=C[i,k-1]+C[k,j];
si aux<min
si aux<min entonces
entonces
min:=aux;
min:=aux;
r[i,j]:=k
r[i,j]:=k
fsi
fsi
fpara;
fpara;
C[i,j]:=m[i,j]+min
C[i,j]:=m[i,j]+min
fpara
fpara
fpara
fpara
fin
fin
algoritmo creaABB(ent
algoritmo creaABB(ent w:vectClaves;
w:vectClaves;
ent r:matSol;
ent r:matSol;
sal a:árbol)
sal a:árbol)
algoritmo creaRec(sal
algoritmo creaRec(sal a:árbol;
a:árbol;
ent i,j:entero)
ent i,j:entero)
principio
principio
si i=j
si entonces a:=nil
i=j entonces a:=nil
sino
sino
nuevoDato(a);
nuevoDato(a);
a↑.dato:=w[r[i,j]];
a↑.dato:=w[r[i,j]];
creaRec(a↑.iz,i,r[i,j]-1);
creaRec(a↑.iz,i,r[i,j]-1);
creaRec(a↑.de,r[i,j],j)
creaRec(a↑.de,r[i,j],j)
fsi
fsi
fin
fin
principio
principio
creaRec(a,0,n)
creaRec(a,0,n)
fin
fin
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 61
Árboles binarios de búsqueda
óptimos
Complejidad:
∑ (r[i + 1, j ] − r[i , j − 1] + 1)
d ≤ j ≤n
i = j− d
= r[n − d + 1,n ] −r[0,d − 1] + n − d + 1 < 2n
El problema:
– Diseñar un sistema compuesto de varios
dispositivos conectados en serie.
D1 D2 D3 ••• Dn
∏ 1≤i ≤n φi (mi )
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 65
Un problema de fiabilidad de
sistemas
maximizar ∏ φi (m i )
1≤i ≤n
sujeto a ∑ ci mi ≤ c
1≤i ≤m
m i ≥ 1 y entero , 1 ≤ i ≤ n
⎢⎛ n ⎞ ⎥
ui = ⎢ ⎜ c + ci − ∑ cj ⎟ ci ⎥
⎣⎝ j =1 ⎠ ⎦
– Denotemos:
fi (x) = máximo ∏ φ j (m j )
1≤ j ≤i
sujeto a ∑ cj m j ≤ x
1≤ j ≤i
1 ≤ mj ≤ u j, 1≤ j ≤ i
f n (c) = max
1 ≤m ≤ u
n
{
n
φn (mn ) f n − 1 (c − cnmn ) }
{
f i (x) = max φi (mi ) f i − 1 (x − ci mi )
1 ≤mi ≤ ui
}
Recordar:
¡Más vueltas!
{
= min L1 j + g ( j ,V \ {1, j})
2≤ j ≤n
}
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 70
El problema del viajante de
comercio
{
g (i ,S) = min Lij + g ( j ,S \ {j})
j∈S
} (*)
Además:
g (i ,∅) = Li 1 , i = 2, 3,…,n
– Método de resolución:
Usar (*) y calcular g para todos los conjunto
S con un solo vértice (distinto del 1).
Volver a usar (*) y calcular g para todos los
conjuntos S de dos vértices (distintos del 1) y
así sucesivamente.
Cuando se conoce el valor de g para todos
los conjuntos S a los que sólo les falta un
vértice (distinto del 1) basta calcular
g(1,V\{1}).
– Inicialización:
{
g (2,{ 3, 4}) = min L23 + g (3,{4}) , L24 + g (4 ,{3}) = }
= min {29, 25} = 25;
{
g (3,{ 2, 4}) = min L32 + g (2,{4}) , L24 + g (4 ,{2}) = }
= min {31, 25} = 25;
{
g (4 ,{ 2, 3}) = min L42 + g (2,{3}) , L43 + g (3,{2}) =}
= min {23, 27} = 23.
– Finalmente:
g (1,{ 2, 3, 4}) = min { L12 + g (2,{3, 4}) ,
L13 + g (3,{2, 4}) ,
L14 + g (4 ,{2, 3}) } =
= min { 35, 40, 43 } = 35.
En el ejemplo:
J(2,{3,4}) = 4; J(3,{2,4}) = 4;
J(4,{2,3}) = 2; J(1,{2,3,4}) = 2.
1 →J(1,{2,3,4}) = 2
→J(2,{3,4}) = 4
→J(4,{3}) = 3
→1
Tiempo de cálculo:
⎛ n −2 ⎛ n − 2⎞ ⎞
Θ ⎜ 2(n − 1) + ∑ (n − 1)k
⎝ k =1
⎝ k ⎠⎠
⎟ = Θ n 2 2n ( )
r
⎛r ⎞
Puesto que ∑ k ⎝ k ⎠ = r 2r − 1
k= 1
función g(i,S)
función devuelve nat
g(i,S) devuelve nat
variables másCorto,distancia,j:nat
variables másCorto,distancia,j:nat
principio
principio
si S=Ø
si S=Ø entonces devuelve L[i,1]
entonces devuelve L[i,1]
sino
sino
gtab[i,S]≥≥00
si gtab[i,S]
si
entonces devuelve gtab[i,S]
entonces devuelve gtab[i,S]
sino
sino
másCorto:=∞∞;;
másCorto:=
para todo jj en
para todo en SS hacer
hacer
distancia:=L[i,j]+g(j,S\{j});
distancia:=L[i,j]+g(j,S\{j});
si distancia<másCorto
si distancia<másCorto
entonces másCorto:=distancia
entonces másCorto:=distancia
fsi
fsi
fpara;
fpara;
gtab[i,S]:=másCorto;
gtab[i,S]:=másCorto;
devuelve másCorto
devuelve másCorto
fsi
fsi
fsi
fsi
fin
fin
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 78
Planificación de trabajos
El problema:
Sea un sistema en el que la realización de un con-
junto de trabajos requiere la ejecución por parte
de un conjunto de agentes (o procesadores) de
una serie de tareas diferentes para cada trabajo.
Ejemplo:
Se tiene que planificar la ejecución de dos
trabajos en tres procesadores, de forma que los
tiempos de cada tarea vienen dados por:
⎡2 0⎤
T = ⎢3 3⎥
⎣5 2⎦
Dos planificaciones posibles:
tiempo 0 1 2 3 4 5 6 7 8 9 10 11 12
P1 T11
(a) P2 T22 T21 T22
P3 T31 T32
tiempo 0 1 2 3 4 5 6 7 8 9 10 11 12
P1 T11
(b) P2 T22 T21
P3 T32 T31
Caso m=2:
– Denotemos T1i como ai y T2i como bi.
P1 a5 a1 a3 a2 a4
P2 b5 b1 b3 b2 b4
planificación (5,1,3,2,4)
– Principio de optimalidad:
0 t+bi-ai
ai aj, j∈S\{i}
bi bj, j∈S\{i}
0 bi
= bj + bi − aj + max {t − ai ,a j − bi ,0} =
– Entonces:
g (S,t) ≤ g ′ (S ,t ) ⇔
Es decir:
O sea:
min{bi ,a j } ≥ min {bj ,ai } (*)
– Ahora, si
min{a1 ,a2 ,K,an ,b1 ,b2 ,Kbn } = ai
Ejemplo:
– Sean n=4, (a1,a2,a3,a4) = (3,4,8,10) y
(b1,b2,b3,b4) = (6,2,9,15).
– La secuencia ordenada de los ai y los bi es:
(b2,a1,a2,b1,a3,b3,a4,b4) = (2,3,4,6,8,9,10,15).
El problema:
Dos equipos A y B se enfrentan un máximo de
2n-1 veces, ganando el primer equipo que
acumule n victorias.
Supongamos que no es posible un partido nulo,
que los resultados de cada partido son
independientes y que hay una probabilidad
constante p de que A gane un partido y q = 1-p de
que lo gane B.
El planteamiento:
– Sea P(i,j) la probabilidad de que A gane la
competición sabiendo que le faltan todavía i
victorias y a B le faltan j.
– Entonces, antes del primer partido, la probabili-
dad de que A gane la competición es P(n,n).
– Si A ya ha acumulado todas las victorias
necesarias entonces es el ganador de la
competición, es decir: P(0,j) = 1, 1≤j≤n.
– Igualmente, P(i,0) = 0, para 1≤i≤n.
– La ecuación recurrente es:
P(i,j) = pP(i-1,j) + qP(i,j-1), para i,j≥1.
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 92
Una competición internacional
La solución directa:
función P(i,j)
función devuelve real
P(i,j) devuelve real
{pp
{pp (pq)
(pq) es
es la
la probabilidad
probabilidad de
de que
que gane
gane AA (B)}
(B)}
principio
principio
si i=0
si i=0
entonces
entonces
devuelve 11
devuelve
sino
sino
si j=0
si j=0
entonces
entonces
devuelve 00
devuelve
sino
sino
devuelve pp*P(i-1,j)+pq*P(i,j-1)
devuelve pp*P(i-1,j)+pq*P(i,j-1)
fsi
fsi
fsi
fsi
fin
fin
T (k ) ≤ 2T (k − 1) + d , k > 1
⎛ i + j⎞
– Exactamente el nº de llamadas recursivas es 2⎜ ⎟−2
⎝ j ⎠
⎛ ⎞
– Por tanto, el tiempo para calcular P(n,n) es Ω( 2n )
⎝ n⎠
y puede demostrarse que
⎛ 2n⎞
≥ 22n (2n + 1)
⎝ n⎠
1 2 21 32 13 16 15 16 1 4
11 32 1 2 11 16 7 8 1 3
3 16 5 16 1 2 34 1 2
j
1 16 1 8 14 12 1 1
0 0 0 0 0
4 3 2 1 0
i
P(i,j) = pP(i-1,j) + qP(i,j-1)
la matriz se completa
por diagonales desde
la esquina inferior derecha
La solución:
función apuestas(n:natural;
función apuestas(n:natural; p:real)
p:real)
devuelve real
devuelve real
variables tabP:vector[0..n,0..n]de
variables tabP:vector[0..n,0..n]de real;
real;
q:real;
q:real; s,k:natural
s,k:natural
principio
principio
q:=1-p;
q:=1-p;
para s:=1
para hasta nn hacer
s:=1 hasta hacer
tabP[0,s]:=1;
tabP[0,s]:=1; tabP[s,0]:=0;
tabP[s,0]:=0;
para k:=1
para hasta s-1
k:=1 hasta s-1 hacer
hacer
tabP[k,s-k]:=p*tabP[k-1,s-k]+
tabP[k,s-k]:=p*tabP[k-1,s-k]+
q*tabP[k,s-k-1]
q*tabP[k,s-k-1]
fpara
fpara
fpara;
fpara;
devuelve tabP[n,n]
devuelve tabP[n,n]
fin
fin
Coste:
– En tiempo: Θ(n2)
– En espacio: Θ(n2)
Problema:
Dados los vértices de un polígono se trata de
seleccionar un conjunto de cuerdas (líneas entre
vértices no adyacentes) de modo que ningún par
de cuerdas se cruce entre sí y que todo el
polígono quede dividido en triángulos.
(8,26) (15,26)
v2 v3
(0,20) v1 v4 (27,21)
v5 (22,12)
(0,10) v0
v6 (10,0)
v2 v3
v1 v4
S65
v5
v0
v6
S65
1) Tomar el vértice vi+1 para
v0
formar un triángulo con
las cuerdas (vi,vi+s-1) y
(vi+1,vi+s-1) y con el tercer v6
lado (vi,vi+1), y después
resolver el subproblema Si+1,s-1. v2 v3
v6
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 100
Triangulación de polígonos
Cis = min
1≤ k ≤ s − 2
{Ci , k + 1 + Ci + k , s − k + D(vi ,vi + k ) +
+ D(vi + k ,vi + s − 1 ) }
para 0≤i≤n-1, 4≤s≤n;
donde:
D(vp,vq) es la longitud de la cuerda entre los
vértices vp y vqsi vp y vq no son vértices
adyacentes en el polígono; y
D(vp,vq) es 0 si vp y vq son adyacentes.
Solución eficiente:
(8,26) (15,26)
v2 v3
D(v2 ,v3 ) = D (v 6 ,v 0 ) = 0
v4 (27,21)
(0,20) v1 (son aristas y no cuerdas)
D (v 6 ,v 2 ) = 26,08;
v5 (22,12) D (v 1 ,v 3 ) = 16,16;
(0,10) v0
D (v 6 ,v 1 ) = 22, 36;
v6 (10,0) D (v 0 ,v 3 ) = 21,93
C07 =
7
75, 43
C06 = C16 = C26 = C36 = C46 = C56 = C66 =
6
53, 54 55, 22 57 , 58 64 ,69 59,78 59,78 63,62
C05 = C15 = C25 = C35 = C45 = C55 = C65 =
5
37 , 54 31, 81 35, 49 37 ,74 45, 50 39,98 38,09
(1) C04 = C14 = C24 = C34 = C44 = C54 = C64 = (3)
4
16,16 16,16 15,65 15,65 22,69 22,69 17 , 89
C03 = C13 = C23 = C33 = C43 = C53 = C63 =
3
0 0 (2) 0 0 0 0 0 (2)
C02 = C12 = C22 = C32 = C42 = C52 = C62 =
2
0 0 0 (3) 0 0 0 0 (1)
s i=0 1 2 3 4 5 6
J. Campos - C.P.S. Esquemas algorítmicos - Programación dinámicaPág. 103
Triangulación de polígonos
En el ejemplo:
– El valor de C07 procede de k=5. Es decir, el
problema S07 se divide en S06 y S52.
S52 es un problema trivial, de coste 0.
Así, se introduce la cuerda (v0,v5), de coste 22’09,
y se debe resolver S06.
v2 v3
v1 v4
2 3
2
v5
v0
1
v6