notas arboles/grafos

Anuncio
Capı́tulo VII
Árboles y Grafos
VII.1.
Árboles Binarios
VII.1.1.
Definiciones
Definición. Un árbol binario T es una estructura tal que:
T es vacı́o, ó
T consiste de un nodo, llamado la raı́z de T , y dos árboles binarios llamados
el subárbol izquierdo y el subárbol derecho de T . cada uno de los cuales es
un arbol binario.
Decimos que un nodo v está en un árbol T si v es la raı́z ó v está (recursivamente)
en uno de los subárboles de T . Un nodo en un árbol se llama terminal u hoja,
si sus subárboles son vacı́os. Un nodo que no es terminal se llama interno.
Ejemplo. Un árbol se ilustra como se muestra en la figura. La raı́z es a y se
une con dos “arcos” a las raı́ces de sus subárboles. Procediendo recursivamente se
dibuja todo el árbol. Los nodos d, g, j, k, i son terminales, y los otros son internos.
a
c
b
e
d
f
g
h
j
i
k
1
2
CAPÍTULO VII. ÁRBOLES Y GRAFOS
Definición. En un árbol binario no vacı́o T , el nivel ó profundidad de un
nodo v en T se define como
0, si v es la raı́z de T ,
1 más el nivel de v en el subárbol de T que contiene v, si v no es la raı́z de T
El k-ésimo nivel de un árbol T es el conjunto de nodos con nivel k en T .
El nivel de un nodo es también el número de arcos en el “camino” desde el nodo
hasta la raı́z.
Definición. La altura de un árbol binario no vacı́o T es
0 si T tiene ambos subárboles vacı́os, y
es el máximo de las alturas de sus subárboles no vacı́os más 1, en caso
contrario.
La altura de un árbol binario T es también el máximo nivel de cualquier nodo en
el árbol.
Por ejemplo, en el árbol de la figura arriba, el nivel de a (en el árbol completo)
es 0, el nivel de e es 2, y el nivel de k es 4. La altura de ese árbol es 4.
Proposición. Para todo n ≥ 1, cualquier árbol binario de altura h tiene a lo mas
2h terminales.
La prueba es por inducción sobre la altura usando la definición recursiva de
árbol y de altura. Esto implica la siguiente proposición.
Proposición. Sea T un árbol binario con n terminales. Entonces la altura de T
es al menos dlog2 ne.
VII.1.2.
Ejemplo: Árbol de Ordenamiento
Definición. Un árbol de ordenamiento para una lista L[0 : n − 1] de ı́tems diferentes es un árbol binario tal que
cada nodo interno v tiene asociada una comparación “ L[i] : L[j]”; el subárbol
izquierdo de v corresponde al resultado L[i] < L[j], y el subárbol derecho de
v corresponde al resultado L[i] > L[j] de la comparación.
cada terminal w tiene asociado un ordenamiento
L[i0 ] < L[i1 ] < L[i2 ] < · · · < L[in−1 ]
el cual es el único consistente con los resultados de la comparaciones realizadas en los ancestros de w
VII.1. ÁRBOLES BINARIOS
3
a:b
b:c
a<b<c
a:c
a:c
a<c<b
b<a<c
c<a<b
b:c
b<c<a
c<b<a
Ejemplo. El siguiente árbol corresponde a ordenamiento por inserción con 3
elementos a, b, c:
Es posible que no exista un ordenamiento consistente con uno de los resultados
de una comparación y las anteriores comparaciones. En ese caso esa ramificación se
elimina. Por ejemplo, en la comparación a : c en la parte izquierda es redundante,
a:b
b:c
a:c
a<b<c
a:c
a:c
a<c<b
b<a<c
c<a<b
b:c
b<c<a
c<b<a
y no es posible que como resultado se tenga a > c (por lo tanto no se tiene el
subárbol correspondiente). Teniendo esto en cuenta, el número de terminales del
árbol de ordenamiento debe ser exactamente n!.
Proposición. Cualquier árbol de ordenamiento para n ı́tems diferentes tiene una
altura al menos dlog2 (n!)e.
Prueba. Por la proposición anterior puesto que el número de nodos terminales
es n!.
Proposición. Calquier algoritmo basado en comparaciones, para ordenar n ı́tems
diferentes requiere en el peor de los casos al menos (n/2) log2 (n/2) comparaciones.
Prueba. Correspondiente a un algoritmo A para ordenar podemos construir un
árbol T de ordenamiento. La primera comparación que realiza el algoritmo corresponde a la comparación en la raı́z. El subárbol izquierdo corresponde a la
continuación del algoritmo en el caso que L[i] < L[j], y el subárbol derecho corresponde a la continuación del algoritmo en el caso que L[i] > L[j]. Por la proposición
anterior, T tiene una altura de al menos dlog2 (n!)e. Esto significa que T tiene una
hoja con nivel al menos dlog2 (n!)e. Esto significa que el ordenamiento correspondiente a esa hoja requiere al menos dlog2 (n!)e comparaciones.
4
CAPÍTULO VII. ÁRBOLES Y GRAFOS
Finalmente, tenemos la cota:
log2 (n!) =
= log2 1 + log2 2 + log2 3 + · · · + log2 n
≥ log2 dn/2e + log2 (dn/2e + 1) + · · · + log2 n
ignorando términos
≥ log2 dn/2e + log2 dn/2e + · · · + log2 dn/2e
todos los términos son
mayores que el primero
= (n − dn/2e + 1) · log2 dn/2e
el # de términos es n − dn/2e + 1
= (bn/2c + 1) · log2 dn/2e
≥ (n/2) log2 (n/2).
VII.1.3.
Una mejor acotación de log2 (n!).
Esto sólo por información a quien quiera ver como integración puede ser útil (no
visto en clase).
Proposición.
n log2 (n/e) + log2 e ≤ log2 (n!) ≤ (n + 1) log2 ((n + 1)/e) + 2 log2 (e/2).
Prueba. Acotamos ln(n!). Se tiene que
ln(n!) =
n
X
ln k.
k=1
Usamos integrales para acotar esta suma como (ver la figura)
1
2
3
4
5
6
n−1 n n+1
Zn
ln xdx ≤
1
Usando que
1
n
X
k=1
2
3
4
5
6
n−1 n
Z n+1
ln k ≤
ln xdx.
2
Z
ln xdx = x ln x − x + C
se tiene entonces
n ln n − n + 1 ≤ ln(n!) ≤ (n + 1) ln(n + 1) − (n + 1) − 2 ln 2 + 2
y por lo tanto
n ln(n/e) + 1 ≤ ln(n!) ≤ (n + 1) ln((n + 1)/e) + 2 ln(e/2).
Recordando que log2 X = ln X · log2 e tenemos que
n log2 (n/e) + log2 e ≤ log2 (n!) ≤ (n + 1) log2 ((n + 1)/e) + 2 log2 (e/2).
VII.2. CÓDIGOS DE HUFFMAN
VII.2.
5
Códigos de Huffman
En computación y comunicaciones digitales se usan representaciones para los
diferetes sı́mbolos como secuencias de 0’s y 1’s. Por ejemplo el estándar ASCII
representa los carácteres alfanuméricos y otros especiales como secuencias ó cadenas de 8 bits. En comunicaciones es relevante tener representaciones ó códigos con
longitudes variables de tal manera que caracteres más frecuentes tengan códigos
más cortos que caracteres menos frecuentes. Por ejemplo, tenemos la siguiente
tabla de carácteres, frecuencias y códigos (en los ejemplos aquı́, la “frecuencia” va
a ser un entero que se entiende como un conteo; podrı́a ser también un real entre
0 y 1 obtenido dividiendo por el conteo total):
carácter frecuencia código
a
45
0
b
13
101
c
12
100
d
16
111
e
9
1101
f
5
1100
Por ejemplo, si el mensaje es accafeeb entonces su “codificación” correspondiente es
0 100 100 0 1100 1101 1101 101
El receptor del mensaje entonces debe “decodificarlo”. Un código con longitudes
fijas no presenta problema porque se toman grupos consecutivos de esa longitud
fija y se usa la tabla de códigos en forma inversa. Códigos de longitud variable
necesitarı́an una forma de indicar donde comienza y termina un código lo cual
requerirı́a el uso de más bits. Una solución son códigos libres de prefijos, en que
ningún código es prefijo de otro. La codificación del ejemplo arriba es libre de
prefijo. La decodicicación es entonces fácil: se escanea el mensaje hasta que se
encuentra el primer código, en lo que no hay ambigüedad, entonces el segundo,
y ası́ consecutivamente. Un árbol binario se puede usar para obtener códigos de
longitud variable y libres de prefijo. Por ejemplo, el código de la tabla arriba se
obtuvo del siguiente árbol binario: Los carácteres se asignan a los nodos terminales
1
1
1
0
0
a
0
1
d
1
b
e
0
0
c
f
y ramificaciones a la izquierda y derecha se hacen corresponder a 1 y 0 respectivamente. Entonces el código de un carácter c está dado por la cadena de 0’s y
6
CAPÍTULO VII. ÁRBOLES Y GRAFOS
1’s que corresponde a las ramificaciones que se siguen cuando se recorre el árbol
desde la raı́z hasta el nodo terminal correspondiente a c. Claramente los códigos
obtenidos de esta manera son libres de prefijo.
Para una código que asigna código(c) al carácter c, el valor del código que se
busca minimizar es
X
valor(código, C, f) =
longitud(código(c)) · f(c)
c∈C
Si el código proviene de un árbol binario como se ha descrito antes entonces (para
simplicar, identificamos un carácter con su terminal correspondiente):
X
valor(T, C, f) =
nivel(c, T ) · f(c)
c∈C
Se busca entonces minimizar este valor sobre todos los árboles binarios posibles.
A continuación discutimos un algoritmo para resolver este problema.
VII.2.1.
Algoritmo de Huffman
El algoritmo de Huffman encuentra un árbol óptimo para un conjunto de
caracteres C y frecuencias f de la siguiente manera:
1. Determina dos caracteres x y y con mı́nimas frecuencias (no son necesariamente únicos porque varios elementos pueden tener la mı́nima frecuencia,
ó la segunda mı́nima). Estos x y y van a ser hermanos en un árbol óptimo.
2. Se reemplazan x y y en C con un carácter nuevo z que tiene frecuencia
f(z) = f(x) + f(y), y se encuentra recursivamente un árbol óptimo T 0 para
C, f modificados.
3. Un árbol óptimo para C, f original se obtiene reemplazando el nodo terminal
de z con un nodo con dos hijos correspondientes a x y y.
Aunque descrito recursivamente es fácil de implementar más bien en forma
iterativa.
VII.2.2.
Ejemplo
Usamos el ejemplo C, f arriba para mostrar la ejecución del algoritmo: cada
columna de la siguiente tabla muestra caracteres y frecuencias (por ejemplo en la
primera iteración e y f se convierten en un caracter que escribimos como ef con
frecuencia 14, y ası́ sucesivamente):
car
frec
car
frec
car frec car frec car frec car frec
a
45
a
45
a
45
a
45
a
45 a((bc)(d(ef))) 110
b
13
b
13 bc 25
bc
25 (bc)(d(ef)) 55
c
12
c
12
d
16
d
16
d
16 d(ef) 30
e
9
ef 14 ef 14
f
5
VII.2. CÓDIGOS DE HUFFMAN
7
(Es más fácil en el tablero mostrar esto con una ilustración, pero más fácil aquı́ dar la
tabla.) El árbol correspondiente se muestra en la figura. No es el mismo que se dió antes,
pero los códigos tienen las mismas longitudes y al valor es óptimo.
0
1
0
1
a
1
1
b
0
0
d
1
0
c
e
VII.2.3.
f
Pseudocódigo
(No se escribió en clase.) Asumimos un tipo de estructura de datos nodo,
tal que si z es un nodo, entonces tiene información asociada z.izq y z.der que
“apuntan” a los hijos izquierdo y derechos. Con esto tenemos la siguiente versión
iterativa del algoritmo de Huffman:
Huffman (C, f)
1. n ← |C|
B (el tamaño de C)
2. Q ← conjunto de nodos, uno por cada c ∈ C
3. para i ← 1 a n − 1
4.
crear nuevo nodo z
5.
sean x y y de minimas frecuencias en Q
6.
Q ← Q − {x, y}
7.
z.izq ← x
8.
z.der ← y
9.
f(z) ← f(x) + f(y)
10.
Q ← Q ∪ {z}
11. devolver el unico elemento que queda en Q
Note que al final el único elemento que queda en Q es la raı́z del árbol construı́do.
VII.2.4.
Justificación
La justificación de que el algoritmo de Huffman construye un árbol óptimo se
basa en las siguientes observaciones. Se dan un conjunto de carácteres C y sus
frecuencias f.
Observación. Si x y y son dos caracteres de frecuencias mı́nimas, entonces existe
un árbol óptimo que los tiene como hermanos (en nodos terminales)
8
CAPÍTULO VII. ÁRBOLES Y GRAFOS
T
T’
x
y
a
a
b
y
x
b
Figura VII.1: En T se intercambian x y a. El árbol y las otras asignaciones de
caracteres a terminales no cambia. El valor de estos árboles es igual. Si igualmente
se intercambian y y b, se obtiene un árbol óptimo con x y y como hermanos (en
nodos terminales).
Sea T un árbol de óptimo valor para C, f. Sean a y b dos nodos terminales en
T de mayor nivel (profundidad). Si estos son x y y no hay nada que probar. Si no,
supongamos que x no es ni a ni b (ver figura). Entonces si se intercambian x y a
se obtiene otro árbol (y código) T 0 . Pero puesto que nivel(x, T ) ≤ nivel(a, T ) (por
la selección de a y b), y f(x) ≤ f(a) (por la selección de x y y), se tiene que
valor(T, C, f) − valor(T 0 , C, f) =
= (nivel(x, T )f(x) + nivel(a, T )f(a)) − (nivel(x, T 0 )f(x) + nivel(a, T 0 )f(a))
= (nivel(x, T )f(x) + nivel(a, T )f(a)) − (nivel(a, T )f(x) + nivel(x, T )f(a))
= nivel(a, T )(f(a) − f(x)) − nivel(x, T )(f(a) − f(x))
= (nivel(a, T ) − nivel(x, T )(f(a) − f(x))
≥ 0
porque ambos factores del producto son ≥ 0. Por otra parte valor(T, C, f) ≤
valor(T 0 , C, f) porque T es óptimo. Por lo tanto valor(T, C, f) = valor(T 0 , C, f),
y ası́ T 0 es también óptimo. Si b no es y entonces estos también se pueden intercambiar para obtener de la misma manera un árbol óptimo donde x y y son
hermanos.
Observación. Sean x y y son dos caracteres de frecuencias mı́nimas en C, f;
reemplazamos x y y con un caracter z que tiene frecuencia f(z) = f(x) + f(y) (los
otros caracteres y frecuencias no cambian); sean C 0 , f 0 el conjunto de caracteres y
frecuencias resultantes. Entonces, si T 0 es un árbol óptimo para C 0 , f 0 entonces T
es óptimo para C, f donde T es obtenido como se muestra en la figura: al nodo de
z se le agregan hijos que corresponden a los caracteres x y y.
Esto no es difı́cil de ver y se deja como ejercicio.
VII.3. GRAFOS: CAMINOS MÁS CORTOS
9
T
T’
z
z
x
y
Figura VII.2: Se encuentra un árbol T 0 óptimo para C 0 , f 0 . Si en T 0 se agregan al
nodo terminal de z dos hijos terminales y se asignan a x y y, entonces el árbol T
ası́ obtenido es óptimo para C, f.
VII.3.
Grafos: Caminos Más Cortos
VII.3.1.
Grafos
Definición. Un grafo G consiste de un conjunto de nodos ó vértices V(G) y
un conjunto de arcos ó aristas
E(G) ⊆ {{u, v} : u, v ∈ V(G), u 6= v}.
Si {u, v} ∈ E(G), entonces se dice que u y v son adyacentes en G. (Aquı́ no
permitimos múltiples arcos entre nodos, ni arcos entre un nodo y si mismo; además
los arcos no tienen dirección. En un contexto más general donde esos casos son
permitidos, los grafos que estamos considerando son llamados grafos simples y no
dirigidos.)
Definición. Un camino en un grafo G es una secuencia de nodos y arcos
v0 , e1 , v1 , e2 , v2 , . . . , vk−1 , ek , vk
tal que los ei = {vi , vi+1 } son arcos diferentes en E(G). Si los vértices son también
diferentes, el camino de dice simple.
Ver ejemplos adelante.
Para los grafos que consideramos, para un camino es suficiente especificar su
secuencia de vértices (la secuencia de arsitas está entonces implı́cita).
Los grafos se usan para modelar muy diferentes relaciones (tanto de la vida
diaria, como matemáticas). Algunos ejemplos: (1) los nodos son personas y los
arcos corresponden a la relación de dos personas conocerse mutuamente; (2) los
nodos son ciudades y los arcos corresponden a la existencia de una carretera
entre dos ciudades; (3) los nodos son conjuntos y los arcos corresponden a una
intersección no vacı́a entre un par de conjuntos; etc. En Johnsonbaugh se pueden
encontrar muchos ejemplos.
10
CAPÍTULO VII. ÁRBOLES Y GRAFOS
VII.3.2.
Problema: Los Caminos Más Cortos
Consideramos el siguiente problema motivado por ejemplo con el caso mencionado antes de un grafo donde los nodos son ciudades y los arcos corresponden a
conexiones con carretera. Cada una de estas tiene una longitud y uno está interesado en determinar una ruta para llegar de una ciudad a otra pasando posiblemente
por otras ciudades, de tal manera que la distancia total recorrida es minimizada.
Formalmente, se tiene un grafo G con nodos V(G) y arcos E(G), y una función
d : E(G) → R≥0 (reales no negativos) definida sobre los arcos (las longitudes de
los arcos), y se especifica un s ∈ V(G); se quiere determinar los caminos lo más
cortos (de mı́nima longitud), y sus distancias (longitudes) totales desde s a cada
uno de los otros nodos u. La longitud de un camino s = v0 , v1 , v2 , . . . , vk = u es
k−1
X
d({vi , vi+1 }).
i=0
Por supuesto que una forma de resolver este problema es listar los diferentes
caminos y sus longitudes y entre estos escoger los más cortos. Pero es posible
hacerlo en forma “más eficiente,” es decir, de tal manera que la ejecución en
un computador sea más rápida. (Estamos interesados en caminos simples, pero
no necesitamos preocuparnos de esto porque repetir vértices no puede acortar
distancias, y el algoritmo que vamos a ver elimina automáticamente la posibilidad
de repeticiones.)
VII.3.3.
Algoritmo de Dijkstra
La idea del algoritmo es comenzar en el nodo s, el cual es el nodo más cercano
a si mismo, e iterativamente determinar el siguiente nodo más cercano a s. Para
esto el algoritmo mantiene para cada nodo un valor D[u] el cual es la longitud del
mejor camino encontrado hasta el momento (inicialmente D[u] = ∞ para todo
u 6= s, ya que inicialmente no se conoce ningún camino). El algoritmo también
mantiene para cada nodo u un “apuntador” π[u] al nodo anterior en el camino
más corto de s a u encontrado hasta el momento (el camino cuya longitud es
D[u]). Correspondientemente, π[u] es “nulo” (ó indefinido) inicialmente.
Pseudocódigo
El pseudocódigo del algoritmo, llamado el algoritmo de Dijkstra, es el siguiente:
VII.3. GRAFOS: CAMINOS MÁS CORTOS
11
Dijkstra (G, d)
1. para v ∈ V(G)
2.
D[v] ← ∞
3.
π[v] ← nulo
4. D[s] ← 0
5. Q ← V(G)
6. mientras Q 6= ∅
7.
sea u ∈ Q tal que D[u] es minimo
8.
Q ← Q − {u}
9.
para v ∈ Ady[u] ∩ Q
10.
si D[u] + d({u, v}) < D(v)
11.
D[v] ← D[u] + d({u, v}) B el camino a traves de u es mejor
12.
π[v] ← u
13. devolver (D, π)
Aquı́ Ady[u] = {v ∈ V(G) : {u, v} ∈ E(G)}, el conjunto de nodos adyacentes a
u. Al final, D[u] es igual a la distancia más corta de s a u, y π[u] es igual al nodo
anterior a u en un camino más corto de s a u. El camino más corto hasta u se
puede reconstruir como u, π[u], π[π[u]], π[π[π[u]]], . . ..
Ejemplo
La siguiente figura muestra en la primera imagen un grafo con nodos a, b, c, . . . , j,
y arcos y sus longitudes como aparecen allı́. Las 11 imágenes siguientes muestran
los valores D[u], π[u] en los nodos (excepto los valores que son ∞ y nulo) antes
del mientras y al finalizar cada una de las iteraciones de este. Los nodos del grafo
oscurecidos (en azul) son los que han dejado de estar en Q (y entonces están en
S) y los arcos entre ellos son los definidos por los valores π[u].
VII.3.4.
Justificación
(No se hizo en clase.)
Para el análisis general, sea δ(u) la distancia más corta de s a u sobre todos los
caminos de s a u en G. Una observación importante en verificar que el algoritmo
funciona correctamente es la siguiente:
(∗) Si
s = v0 , v1 , v2 , . . . , v`−1 , v` , v`+1 , . . . , vk−1 , vk = u
es un camino lo más corto de s a u en G entonces la parte inicial de
ese camino hasta v` (donde v` puede ser cualquiera de los nodos en ese
camino)
s = v0 , v1 , v2 , . . . , v`−1 , v`
es un camino lo más corto hasta v` .
12
CAPÍTULO VII. ÁRBOLES Y GRAFOS
5
5
5,a
c
3
4,a
1
6,b
h
5
5,a
c
g
4
9 ,c
4a
1
2
d
4,a
4
8,h
1
g
1
3
5,a
c
5
4
j
g
3
1
6
4
9,e
1
i
5
j
5,a
c
3
1
e 2
5,d
3
4
5
7,d
9,e
12,f
6
1
j
h
i
5,a
c
5
j
4
2
d
4,a
4
8,h
1
g
5,a
c
4
9,c 1
g
h
5
5,a
c
3
1
e 2
5,d
3
4
5
7,d
9.e
10,i
6
1
j
h
i
j
b 3,a
3
3
1
e
5,d
4
7,d 6
6
9,b
f
2
5
1
i
3
j
b 3,a
6
3
7,e
f
1
e 2
5,d
3
4
7,d
9,e
6
1
h
i
5
5,a
c
5
1
4
3
0 a
7,e
f
f
2
d
4,a
4
8,h
1
g
6
2
i
4
b 3,a
3
6
0 a
6
e
4
h
2
d
4,a
b 3,a
1
e 2
5,d
3
4
5
7,d
9,e
12,f
6
1
j
h
i
5
7,e
f
2
3
3
1
5
9,b
f
1
i
1
3
g
6
3
d
4
6
7,e
f
0 a
4,a
0 a
2
d
4,a
b 3,a
j
2
b 3,a
1
e
5,d
4
4
4
9,c
1
g
6
1
3
7,d 6
5
7,e
f
3
h
f
3,a
b
3
4
5,a
c
5
i
4
0 a
2
e
3
2
d
4,a
2
5
4
6
h
5
9,b
f
b 3,a
5,d
4
2
3
3
7,d
6
h
5
e
i
1
d
0 a
5,a
c
6
4
2
1
g
e
3
0 a
4
3
0 a
j
6
3
1
d
4
6
3
3
4
1
2
c
0
a
b
4
b 3,a
1
d
f
5
i
4
2
2
3
a
5
4
6
h
0 a
g
e
3
1
6
3
1
d
4
g
b
4
2
c
0
3
a
b 3,a
4
2
d
4,a
4
8,h
1
g
6
3
1
3
7,d
6
h
5
12,f
j
5,d
e
2
7,e
f
4
5
10,i
9,e
1
j
i
Figura VII.3: Grafo G con longitudes de sus arcos, y antes de la primera y después
de cada una de las iteraciones del algoritmo de Dijkstra, con nodo a como s.
VII.3. GRAFOS: CAMINOS MÁS CORTOS
13
Esto es fácil de ver: si hubiera otro camino más corto a v` , ese nos darı́a también
un camino más corto a u, lo que es una contradicción.
Para el propósito de este análisis,
sea δ(u) igual la distancia del camino más corto de s a u
y
sea S = V(G) − Q, el conjunto de nodos ya removidos de Q.
Invariante: En cada iteración del mientras, el algoritmo mantiene que
(i) cuando un nuevo nodo u es removido de Q (y entonces pasa a S), se tiene
que
δ(u) = D[u],
es decir, el estimativo D[u] es igual a la distancia más corta
(ii) para los nodos v que están en Q se mantiene que
D[v] es la distancia más corta sobre caminos con nodos en S, excepto v
(el cual está en Q). De aquı́ que siempre
δ(v) ≤ D[v]
para todo v en Q (porque D[v] es la mejor distancia sobre un subconjunto
de los caminos, mientras que δ(v) es la distancia sobre todos los caminos).
Justificación lı́neas 1-5: Inicialmente sólo la distancia al nodo s ha sido identificada
y es 0 (D[s] = 0, las otras se inicializan a ∞ (un número más grande que cualquier
otro), y los apuntadores π son inicialmente nulos.
Justificación de lı́neas 7-8:
Veamos que para el nodo u ∈ Q con D[u] que es mı́nimo, su valor D[u] es la distancia más corta a s. Se sabe
ya porque lo garantiza el invariante en la iteración previa que D[u] es la mı́nima distancia sobre caminos C
en S (excepto u). Ası́ que consideremos un camino C 0
de s a u que no está completamente en S. Sea y el primer nodo no en S y x el anterior nodo el cual entonces
C
u
s
S
C’
x
y
14
CAPÍTULO VII. ÁRBOLES Y GRAFOS
está en S (ver figura). Por la observación (∗) arriba, el segmento de C 0 hasta y es
también de mı́nima distancia. Entonces
D[y] ≤
=
=
≤
D[x] + d({x, y}) por la parte (ii) del invariante arriba para y
δ(x) + d({x, y}) por la parte (i) del invariante arriba para x
δ(y) porque son longitudes medidas en C 0
δ(u) porque δ(u) es la longitud de todo el camino C 0 y
la longitud de C 0 hasta y es menor ó igual que eso
≤ D[u] porque δ(u) ≤ D[u] para todo nodo u
De aquı́ que D[y] ≤ D[u]. Pero D[u] ≤ D[y] por que D[u] se ha escogido en la
lı́nea 7 como mı́nimo sobre nodos en Q. Por lo tanto D[u] = D[y]. Y entonces
D[u] = δ(u)
(porque está entre y y u en la cadena de desigualdades arriba). Ası́ que D[u] si
es la distancia más corta sobre todos los caminos de s a u.
Justificación de lı́neas 9-12:
De la iteración anterior se conoce ya la distancia más corta
a v ∈ Q usando sólo vértices en S. Pero en esta iteración, se
está agregando u a S, por lo tanto se debe examinar si ir a
u primero y luego a v (usando el arco {u, v}) es más corto.
Esto se debe hacer para todo v ∈ Ady[u] ∩ Q.
v
x
u
s
S
Descargar