Professional Documents
Culture Documents
Recorrido en Profundidad
] Explora sistemáticamente las aristas del grafo de forma que primero ordenRecorrido=0; vV: R[v]=0;
se visitan los vértices adyacentes a los visitados más recientemente. vV: Si (R[v]==0) entonces DFS(v)
Así se va “profundizando” en el grafo. R mantiene el orden de recorrido
finRP
] Algoritmo de recorrido en profundidad:
\ Contador (ordenRecorrido) Método privado recursivo
\ Vector de naturales (R) para DFS(v)
[ “marcar” los vértices ya visitados (R[v]>0) y ordenRecorrido++; R[v]=ordenRecorrido;
[ almacenar el orden de recorrido. R[v]: orden en el que se visita el vértice v. wAdyacentes(v): Si (R[w]==0) entonces DFS(w)
int R[];
Nodos R int OrdenRecorrido;
v/w 1 2 3 4 5 6 7 8 9 public void RecorridoEnProfundidad () {
R=new int[numVertices];
7 0 0 0 0 0 0 0 0 0 OrdenRecorrido=1;
2 1/2,3,4,5 1 - - - - - - - - for (int i=0;i<numVertices;i++) R[i]=0;
OTP
] Aplicaciones: ordenRecorrido=0;
\ Representación de las fases de un proyecto en un GDA vV: R[v]=0;
\ Evaluación de atributos en la fase de análisis semántico de un compilador p= new pilaVec();
] Algoritmo para el recorrido según la OT vV: Si (R[v]==0) entonces DFST(v) ;
\ Utilizar el recorrido en profundidad para ordenar los vértices según un
orden (parcial) “½“ tal que u,vV, si (u,v)E, u ½ v. Método privado recursivo
\ Basta ir anotando en una pila global (P) los vértices completamente DFST(v)
explorados por DFS.
ordenRecorrido++; R[v]=ordenRecorrido;
wAdyacentes(v): Si (R[w]==0) entonces DFST(w);
p.apilar(v);
Nodos R P
v/w 1 2 3 4 5 6 7 8 9
0 0 0 0 0 0 0 0 0 <> Implementación del algoritmo de Ordenación topológica en Java
7 1/2,3,4,5 1 - - - - - - - - <>
2
2 - 2 - - - - - - - <2>
6 3/2,6,8 - - 3 - - - - - - <2>
3 6/7 - - - - - 4 - - - <2>
7/2 - - - - - - 5 - - <7,2>
1 --- - - - - - - - - - <6,7,2>
8 8/6 - - - - - - - 6 - <8,6,7,2>
4 --- - - - - - - - - - <3,8,6,7,2>
4/3,8 - - - 7 - - - - - <4,3,8,6,7,2>
5/- - - - - 8 - - - - <5,4,3,8,6,7,2>
5 9 --- - - - - - - - - - <1,5,4,3,8,6,7,2>
9/5,8 - - - - - - - - 9 <9,1,5,4,3,8,6,7,2>
Grafo ordenado
9 1 5 4 3 8 6 7 2 topológicamente
Grafos. EDA. Curso 2002/03 Grafos. EDA. Curso 2002/03
17 18
BÚSQUEDA DE CAMINOS MÍNIMOS EN Problema: dado el siguiente grafo, encontrar el camino más
GRAFOS corto (medido por el número de aristas) desde su Vértice v2 a
cualquier otro vértice
] Problema del camino mínimo sin pesos
v0 1 v1
\ La longitud del camino sin pesos mide el número de aristas
\ Encontrar el camino más corto (medido por el número de aristas)
desde un cierto vértice O a cualquier otro vértice v2 v3 v4
] Problema del camino mínimo con pesos positivos
(algoritmo de Dijkstra) v5 v6
\ La longitud del camino con pesos es la suma de los costes de las
aristas del camino Problema0: encontrar el Camino más corto desde v2a v2
\ Las aristas tienen costes no negativos Solución0: //la
no distancia
//lahay mínima
o longitud
distancia 0 de
mínima devv22aavv22es
es00
\ Se trata de encontrar el camino más corto (medido con su coste distanciaMin[vOrigen]
distanciaMin[vOrigen]=
=0;
0;;
total) desde el vértice origen al resto de vértices
\ El problema anterior es un particular de éste, en el que las aristas
tiene coste 1
distanciaM[vOrigen]
distanciaM[vOrigen]=
= 0;
0;;
v0 v1 v5 v6
v2 v3 v4
Problema2: encontrar el Camino más corto desde v2 a los
Vértices más cercanos a los Vértices adyacentes a v2
v5 v6
Solución : los Vértices
////distancia mínimamás cercanos son2sus
(v adyacentes
2distancia mínimade
devv00aavv1-v es no tiene)
1-v33 es 2 (v55 no tiene)
Problema1: encontrar el Camino más corto desde v2 a sus están “a 2 Aristas de v 2 ” o longitud (mínima) 2
distanciaMin[primerVAdyacente(primerVAdyacente(vOrigen)]
distanciaMin[primerVAdyacente(primerVAdyacente(vOrigen)] ==2;
2;;
Vértices más cercanos ¿ Cómo distanciaMin[segundoVAdyacente(primerVAdyacente(vOrigen)]
distanciaMin[segundoVAdyacente(primerVAdyacente(vOrigen)]==2; 2;;
////lala distancia mínima de ...
Solución1: los Vértices más
distancia mínima devv2son
cercanos a v sus es 1
/v adyacentes,
2 a v00/v55 es 1 Usar una
recordar
...
distanciaMin[últimoVAdyacente(primerVAdyacente(vOrigen)]
distanciaMin[últimoVAdyacente(primerVAdyacente(vOrigen)]==2;
2;;
están “a 1 Arista de v2” olongitud (mínima)
distanciaMin[primerVAdyacente(vOrigen)]
distanciaMin[primerVAdyacente(vOrigen)] = 1;1;
=1; ...
...
Cola
dónde distanciaMin[primerVAdyacente(últimoVAdyacente(vOrigen)]
distanciaMin[primerVAdyacente(últimoVAdyacente(vOrigen)]==2;
2;;
...
...
distanciaMin[segundoVAdyacente(últimoVAdyacente(vOrigen)]
distanciaMin[segundoVAdyacente(últimoVAdyacente(vOrigen)]==2; 2;;
distanciaMin[últimoVAdyacente(vOrigen)]
distanciaMin[últimoVAdyacente(vOrigen)]=
=1;
1;; seguir ? ...
...
Grafos. EDA. Curso 2002/03 distanciaMin[últimoVAdyacente(últimoVAdyacente(vOrigen)]
distanciaMin[últimoVAdyacente(últimoVAdyacente(vOrigen)]
Grafos. EDA. Curso 2002/03 ==2;
2;;
21 22
Problema: dado un grafo, encontrar el camino más corto Resolución del problema de caminos
(medido por el número de aristas) desde un Vértice dado, mínimos sin pesos
origen, a cualquier otro vértice
distanciaMin[origen]=0 ;
v0 v1 Vertice’s DistanciaMin q.insertar(new Integer(origen));
0 1 2 3 4 5 6
try { while ( !q.esVacia()) {
2 |q = 2| q = v v 0vvv v
v2 v3 v4 int v=((Integer)q.quitarprimero())..intValue() ;
2 |q =0 1 - - - - - -
2 |q = 0, 5 - - - - - 1 - Lista b=tabla[v].ady;
0 |q = 5, 1 - 2 - - - - - b.inicio();
v5 v6
0 |q = 5, 1, 3 - - - 2 - - - while ( !b.esFin()) {
5 |q = 1, 3 - - - - - - - Arista a = (Arista) b.recupera();
Comprobar == inf evita 1|q = 3, 4 - - - - 3- - -
int w = a..dest();
- - - - - - -
que distanciaMin[3] - - - - - - -
if (distanciaMin[w] == INFINITO ) {
pase a valer 3 1 2 0 2 3 - 1 - distanciaMin[w] = distanciaMin[v] + 1 ;
q.insertar(new Integer(w));
}
distanciaMin[4] = distanciaMin[3] + 1 b.siguiente(); }
} catch (DesbordamientoInferior e) {// No puede ocurrir } }
Grafos. EDA. Curso 2002/03 Grafos. EDA. Curso 2002/03
25 26
Usar un vector para guardar el camino: P[i] es el vértice void imprimirCamino(int destino) {
anterior a i en el camino mínimo if (P[destino]!=-1) {
CaminoMinimoSinPeso(origen) imprimirCamino(P[destino]);
vV: distanciaMin[v]=f ; vV: P[v]=-1 ; }
distanciaMin[origen] = 0 ; System.out.println(tabla[destino].nombre);
q.insertar(origen); }
while ( !q.esVacia()) {
v=q.quitarprimero() ;
wAdyacentes(v):
if (distanciaMin[w] == f) {
P[w]=v;
distanciaMin[w] = distanciaMin[v] + 1 ;
q.insertar(w);
} Grafos. EDA. Curso 2002/03 Grafos. EDA. Curso 2002/03
27 28
Resolución del problema de caminos
mínimos con pesos Algoritmo de Dijkstra
Algoritmo de Dijkstra
Dijkstra (origen)
] Cambio en el ajuste del vector de distancias vV: distanciaMin[v]=f ;
Coste del algoritmo: O(|V|2)
\ El valor distanciaMin[v] sólo se modificaba una vez Mejora: Usar una Cola de Prioridad
distanciaMin[origen] = 0 ;
\ Ahora el algoritmo debe decidir si para llegar a un cierto vértice C={V}; //todos los vértices por tratar para representar C
w es mejor pasar por v o no:
while ( C!=) {
distanciaMin[w]=min(distanciaMin[w], distanciaMin[v]+coste(v,w)) v=el elemento de C con menor valor de distanciaMin;
] Cambio en la selección del vértice a tratar Eliminar v de C;
\ Seleccionar el vértice más próximo ahora no es el tratado más wAdyacentes(v):
recientemente sino el de menor coste if (distanciaMin[w]>distanciaMin[v]+coste(v,w)) {
[ La estrategia NO es usar una cola (First-In First-Out) distanciaMin[w] = distanciaMin[v] + coste(v,w) ;
[ El primero visitado no es el más próximo necesariamente }
\ En general utilizaremos un conjunto C para guardar los vértices no
tratados: al principio son todos y en cada iteración se elimina uno,
aquel que tiene el valor de distanciaMin menor.
Grafos. EDA. Curso 2002/03 Grafos. EDA. Curso 2002/03
29 30
public void dijkstra(int origen){ 1.- Hacer una traza del algoritmo de Dijkstra sobre este grafo, tomando como
distanciaMin = new int[numVertices]; 2
vértice origen v2 v v
for (int i=0 ; i<=numVertices ; i++) distanciaMin[i] = INFINITO ; 0 1
qPrioridad = new MonticuloBinario(new new ElementoHeap()); 4 10
distanciaMin[vOrigen] = 0; qPrioridad.insertar(new ElementoHeap(origen, 0)); 4 1
try { while ( !q.esVacia()) { v2 v3 v4
2 8 4 2
ElementoHeap par = ((ElementoHeap)q.eliminarMin()); v = par..dest();
if (desencolados[v] == 0) { 5 6
v5 v6
desencolados[v] = 1; 1
Lista b= tabla[v].ady(); b.inicio();
while ( !b.esFin()) { 2.- Implementar en Java las operaciones sobre grafos, incluyendo recorridos y
Arista a = (Arista) b.recupera(); obtención de caminos siguiendo los algoritmos vistos en clase
int w = a..dest; int costeVW = a..coste();
if ( distanciaMin[w] > distanciaMin[v] + costeVW) {
3.- Implementar en Java las operaciones sobre grafos, incluyendo recorridos y
distanciaMin[w] = distanciaMin[v] + costeVW ;
qPrioridad.insertar(new ElementoQ(w, distanciaMin[w] ));
obtención de caminos bajo el supuesto de que los grafos con los que vamos a
} trabajar sean densos
b.siguiente();
}
} catch (DesbordamientoInferior e) {// No puede ocurrir } }
Grafos. EDA. Curso 2002/03 Grafos. EDA. Curso 2002/03
35 36