26.07.2013 Views

Algoritmos sobre Grafos - Departamento de Ciencias e Ingeniería ...

Algoritmos sobre Grafos - Departamento de Ciencias e Ingeniería ...

Algoritmos sobre Grafos - Departamento de Ciencias e Ingeniería ...

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

<strong>Algoritmos</strong> y Complejidad<br />

<strong>Algoritmos</strong> <strong>sobre</strong> <strong>Grafos</strong><br />

Pablo R. Fillottrani<br />

Depto. <strong>Ciencias</strong> e <strong>Ingeniería</strong> <strong>de</strong> la Computación<br />

Universidad Nacional <strong>de</strong>l Sur<br />

Primer Cuatrimestre 2011<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

los grafos constituyen una <strong>de</strong> las más importantes Estructuras <strong>de</strong><br />

Datos en las <strong>Ciencias</strong> <strong>de</strong> Computación. Un inmensa variedad <strong>de</strong><br />

problemas basan su solución en el uso <strong>de</strong> grafos<br />

en esta materia sólo nos interesaremos en aquellos problemas<br />

dón<strong>de</strong> es posible una representación total <strong>de</strong>l grafo en la<br />

memoria <strong>de</strong> la máquina<br />

las heurísticas para el manejo <strong>de</strong> grafos implícitos se ven en<br />

Inteligencia Artificial<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

<strong>Algoritmos</strong> <strong>sobre</strong> <strong>Grafos</strong><br />

1 Introducción<br />

2 Recorridos<br />

3 Or<strong>de</strong>namiento topológico<br />

4 Componentes fuertemente conexos<br />

5 Puntos <strong>de</strong> articulación y puentes<br />

6 Flujo máximo<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Representación <strong>de</strong> grafos<br />

Representación <strong>de</strong> <strong>Grafos</strong><br />

Matriz <strong>de</strong> Adyacencia<br />

Lista <strong>de</strong> Adyacencia<br />

los arcos pue<strong>de</strong>n o no tener peso y/o etiquetas<br />

los arcos pue<strong>de</strong>n o no ser dirigidos<br />

se pue<strong>de</strong>n permitir o no varios arcos entre los mismos nodos<br />

(multigrafos)<br />

se pue<strong>de</strong>n permitir o no arcos hacia el mismo nodo<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Representación grafos no dirigidos<br />

Memoria<br />

matriz <strong>de</strong> adyacencia Θ(n 2 )<br />

lista <strong>de</strong> adyacencia Θ(n + 2a) = Θ(max(n,a))<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

un recorrido es un algoritmo que visita todos los nodos <strong>de</strong> un<br />

grafo<br />

supondremos los grafos representados por matrices <strong>de</strong><br />

adyacencia<br />

los algoritmos más usados para recorrer grafos generalizan los<br />

recorridos <strong>de</strong> árboles<br />

para el caso <strong>de</strong> grafo se necesita guardar información <strong>sobre</strong> los<br />

nodos que ya han sido visitados, <strong>de</strong> modo <strong>de</strong> no volver a<br />

visitarlos<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Representación grafos dirigidos<br />

Memoria<br />

matriz <strong>de</strong> adyacencia Θ(n 2 )<br />

lista <strong>de</strong> adyacencia Θ(n + a) = Θ(max(n,a))<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

para recorrer grafos, se etiquetarán dinámicamente los nodos<br />

como:<br />

nodos blancos: todavía no han sido visitados<br />

nodos grises: ya han sido visitados, pero no se ha controlado la<br />

visita a todos sus adyacentes<br />

nodos negros: ya han sido visitados, al igual que todos sus<br />

adyacentes<br />

esta caracterización implica que ningún nodo negro tiene un<br />

nodo blanco como adyacente<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por niveles<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

el recorrido por niveles, o breadth-first search (BF), basa el or<strong>de</strong>n<br />

<strong>de</strong> visita <strong>de</strong> los nodos <strong>de</strong>l grafo en una E.D. Cola, incorporándole<br />

en cada paso los adyacentes al nodo actual<br />

esto implica que se visitarán todos los hijos <strong>de</strong> un nodo antes <strong>de</strong><br />

proce<strong>de</strong>r con sus <strong>de</strong>más <strong>de</strong>scendientes<br />

las operaciones <strong>sobre</strong> la E.D. Cola se suponen implementadas<br />

en tiempo Θ(1)<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

PROCEDURE bfs(G=N,A)<br />

FOR cada vértice v en N<br />

color[v]::=blanco<br />

ENDFOR<br />

Q.ColaVacía()<br />

FOR cada vértice v en N<br />

IF color[v]=blanco<br />

color[v]::=gris<br />

Q.insertar(v)<br />

visitarBF(G,Q)<br />

ENDIF<br />

ENDFOR<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

costo veces<br />

a n<br />

a 1<br />

a n<br />

a ≤ n<br />

a ≤ n<br />

TvBF (n) ≤ n<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Algoritmo recorrido por niveles<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

el algoritmo que se presenta a continuación es no <strong>de</strong>terminístico:<br />

la elección <strong>de</strong> los nodos en cada ciclo pue<strong>de</strong> hacerse en forma<br />

arbitraria, o <strong>de</strong>pendiente <strong>de</strong>l contexto si es necesario<br />

pue<strong>de</strong> aplicarse tanto a grafos dirigidos y como a no dirigidos<br />

está dividido en dos procedimientos<br />

bfs inicializa las estructuras <strong>de</strong> datos, inicia el recorrido y<br />

controla que todos los nodos hayan sido visitados<br />

visitaBF realiza el recorrido propio a partir <strong>de</strong> un nodo ya<br />

elegido<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

PROCEDURE visitarBF(G,Q)<br />

WHILE no Q.vacía()<br />

u::=Q.primero()<br />

IF existe w adyacente a u<br />

tal que color[w]=blanco<br />

color[w]::=gris<br />

Q.insertar(w)<br />

ELSE<br />

color[u]::=negro<br />

Q.sacarDeCola()<br />

ENDIF<br />

ENDWHILE<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

costo veces<br />

b ≤ n<br />

b ≤ n<br />

b ≤ a × n<br />

b ≤ a × n


Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Análisis <strong>de</strong>l tiempo <strong>de</strong> ejecución<br />

TBF (n) ≤<br />

n<br />

∑<br />

i=1<br />

(a + TvisitarBF (n)) =<br />

la cota obtenida es muy mala<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

n<br />

∑<br />

i=1<br />

(a + O(a × n)) ∈ O(n 4 )<br />

una análisis más <strong>de</strong>tallado resulta en una cota mejor<br />

Ejemplo <strong>de</strong> BFS (I)<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

se pue<strong>de</strong> probar por inducción <strong>sobre</strong> el número <strong>de</strong> iteraciones<br />

que todo nodo es coloreado blanco, gris y negro exactamente una<br />

vez, y en ese or<strong>de</strong>n<br />

que todos los nodos en Q son grises y solamente estan una vez<br />

en Q<br />

que los controles <strong>de</strong> adyacencia se hace exactamente una vez<br />

por cada arco.<br />

esto resulta TBF (n) = Θ(max(n,a)), tomando como barómetros<br />

las operaciones <strong>sobre</strong> la E.D. Cola<br />

Ejemplo <strong>de</strong> BFS (II)<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Ejemplo <strong>de</strong> BFS (III)<br />

Ejemplo <strong>de</strong> BFS (V)<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Ejemplo <strong>de</strong> BFS (IV)<br />

Propieda<strong>de</strong>s<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

al mismo tiempo que se hace un recorrido por niveles <strong>de</strong> un grafo<br />

se pue<strong>de</strong>n calcular algunos datos adicionales que serán útiles<br />

para las aplicaciones <strong>de</strong> este algoritmo<br />

la foresta <strong>de</strong>l recorrido es el subgrafo <strong>de</strong> G formado por todos los<br />

arcos utilizados en el recorrido<br />

se pue<strong>de</strong> probar que siempre es una foresta (conjunto <strong>de</strong><br />

árboles)<br />

se representa a través <strong>de</strong> un arreglo adicional padre[1..n]<br />

don<strong>de</strong> cada nodo guarda su antecesor en la foresta; si<br />

padre[i] = 0 entonces el nodo es una raíz<br />

este arreglo se inicializa en 0<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Lema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

el Nivel <strong>de</strong> cada nodo es la distancia (cantidad <strong>de</strong> arcos) que<br />

<strong>de</strong>ben recorrerse en la foresta para llegar <strong>de</strong>s<strong>de</strong> la raíz al nodo<br />

correspondiente<br />

se representa por un arreglo adicional nivel[1..n], inicializado<br />

en 0<br />

se <strong>de</strong>be recordar que la raíz es en principio un nodo arbitrario<br />

se pue<strong>de</strong>n calcular esta información adicional al mismo tiempo<br />

que se hace el recorrido; esto no agrega tiempo adicional al<br />

or<strong>de</strong>n <strong>de</strong>l algoritmo<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

se pue<strong>de</strong>n probar las siguientes propieda<strong>de</strong>s <strong>sobre</strong> los recorridos<br />

por nivel<br />

Si el grafo es conexo, entonces la foresta <strong>de</strong> recorrido es un árbol<br />

Lema<br />

en el caso <strong>de</strong> un grafo dirigido, conexo significa que existe un<br />

camino <strong>de</strong> ida y <strong>de</strong> vuelta entre cada par <strong>de</strong> nodos<br />

al finalizar un recorrido BF, nivel[v] contiene la mínima distancia<br />

<strong>de</strong>s<strong>de</strong> la raíz <strong>de</strong>l árbol <strong>de</strong> v en la foresta <strong>de</strong> recorrido hasta v<br />

ejercicio: comparar con el algoritmo <strong>de</strong> Dijkstra<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

PROCEDURE visitarBF(G,Q)<br />

WHILE no Q.esVacía()<br />

u::=Q.primero()<br />

IF existe w adyacente a u<br />

tal que color[w]=blanco<br />

color[w]::=gris<br />

padre[w]::=u; nivel[w]::=nivel[u]+1<br />

Q.insertar(w)<br />

ELSE<br />

color[u]::=negro<br />

Q.sacarDeCola()<br />

ENDIF<br />

ENDWHILE<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

el recorrido permite clasificar los arcos <strong>de</strong>l grafo en las siguientes<br />

categorías:<br />

arcos <strong>de</strong> la foresta son los arcos (padre[v],v) utilizados en el<br />

recorrido<br />

arcos hacia atrás son arcos (u,v) en don<strong>de</strong> v es un ancestro <strong>de</strong><br />

u en la foresta <strong>de</strong>l recorrido<br />

arcos hacia a<strong>de</strong>lante son arcos (u,v) en don<strong>de</strong> v es<br />

<strong>de</strong>scendiente <strong>de</strong> u en la foresta <strong>de</strong>l recorrido<br />

arcos que cruzan son los <strong>de</strong>más arcos que no entran en las otras<br />

categorías. Los extremos pue<strong>de</strong>n estar en el mismo árbol o en<br />

árboles diferentes<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

si el grafo es no dirigido, como cada arco es consi<strong>de</strong>rado dos<br />

veces esta clasificación pue<strong>de</strong> ser ambigua. Se toma la primera<br />

<strong>de</strong> las categorías posibles según el or<strong>de</strong>n dado<br />

estas categorías pue<strong>de</strong>n calcularse en el mismo algoritmo <strong>de</strong>l<br />

recorrido, sin aumentar el or<strong>de</strong>n <strong>de</strong>l tiempo <strong>de</strong> ejecución (la<br />

<strong>de</strong>mostración queda como ejercicio)<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por profundidad<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

el recorrido por profundidad, o <strong>de</strong>pth-first search (DF), basa el<br />

or<strong>de</strong>n <strong>de</strong> visita <strong>de</strong> los nodos <strong>de</strong>l grafo en una E.D. Pila,<br />

agregando en cada paso los adyacentes al nodo actual<br />

esto hace que agote los nodos accesibles <strong>de</strong>s<strong>de</strong> un hijo antes <strong>de</strong><br />

proce<strong>de</strong>r con sus hermanos<br />

las operaciones <strong>sobre</strong> la E.D. Pila se suponen <strong>de</strong> tiempo en Θ(1)<br />

al igual que el recorrido por profundidad, se presenta un<br />

algoritmo no <strong>de</strong>terminístico que pue<strong>de</strong> modificarse para incluir un<br />

or<strong>de</strong>n en la elección <strong>de</strong> los nodos<br />

pue<strong>de</strong> aplicarse tanto a grafos dirigidos como a grafos no<br />

dirigidos<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Propieda<strong>de</strong>s<br />

Teorema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Si el grafo es dirigido, entonces un recorrido BF no genera arcos hacia<br />

a<strong>de</strong>lante<br />

Teorema<br />

Si el grafo es no dirigido, entonces un recorrido BF no genera arcos<br />

hacia atrás ni hacia a<strong>de</strong>lante<br />

Algoritmo<br />

las <strong>de</strong>mostraciones se hacen por el absurdo (ejercicio)<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

PROCEDURE dfs(G=N,A)<br />

FOR cada vértice v en N<br />

color[v]::=blanco<br />

ENDFOR<br />

P.pilaVacía()<br />

FOR cada vértice v en N<br />

IF color[v]=blanco<br />

color[v]::=gris<br />

P.apilar(v)<br />

visitarDF(G,P)<br />

ENDIF<br />

ENDFOR<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

PROCEDURE visitarDF(G,P)<br />

WHILE no P.esVacía()<br />

u::=P.tope()<br />

IF existe nodo w adyacente a u<br />

tal que color[w]=blanco<br />

color[w]::=gris<br />

P.apilar(w)<br />

ELSE<br />

color[u]::=negro<br />

P.<strong>de</strong>sapilar()<br />

ENDIF<br />

ENDWHILE<br />

Ejemplo (I)<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Ejemplo (II)<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

en forma análoga al recorrido por niveles, se prueba por<br />

inducción que<br />

todo nodo es coloreado blanco, gris y negro exactamente una<br />

vez, y en ese or<strong>de</strong>n<br />

todos los nodos en P son grises y solamente estan una vez en P<br />

los controles <strong>de</strong> adyacencia se hace exactamente una vez por<br />

cada arco<br />

resultando en un algoritmo Θ(n + a)<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Ejemplo (III)<br />

Ejemplo (V)<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Ejemplo (IV)<br />

Ejemplo (VI)<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Ejemplo (VII)<br />

Propieda<strong>de</strong>s<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

al igual que en los recorridos por niveles, es posible obtener la<br />

foresta <strong>de</strong>l recorrido <strong>de</strong> un recorrido por profundidad<br />

en cambio, la numeración nivel[u] no tiene sentido<br />

sí es posible en este tipo <strong>de</strong> recorrido numerar a los nodos <strong>de</strong><br />

acuerdo al tiempo <strong>de</strong>l evento <strong>de</strong> <strong>de</strong>scubrimiento (numeración<br />

preor<strong>de</strong>n), o <strong>de</strong> finalización (numeración postor<strong>de</strong>n)<br />

la numeración en preor<strong>de</strong>n se hace simultáneamente con la<br />

coloración en gris; y se guarda en un arreglo d[1..n]<br />

la numeración en postor<strong>de</strong>n coinci<strong>de</strong> con la colaración en negro;<br />

y se guarda en un arreglo f[1..n]<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Ejemplo (VIII)<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Cálculo <strong>de</strong> numeración<br />

PROCEDURE dfs(G=N,A)<br />

FOR cada vértice v en N<br />

color[v]::=blanco<br />

ENDFOR<br />

P.pilaVacía(); tiempo::=0<br />

FOR cada vértice v en N<br />

IF color[v]=blanco<br />

color[v]::=gris<br />

tiempo++; d[v]::=tiempo<br />

P.apilar(v)<br />

visitarDF(G,P)<br />

ENDIF<br />

ENDFOR<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

PROCEDURE visitarDF(G,P)<br />

WHILE no P.esVacía()<br />

u::=P.tope()<br />

IF existe nodo w adyacente a u<br />

tal que color[w]=blanco<br />

color[w]::=gris<br />

tiempo++; d[w]::=tiempo<br />

P.apilar(w)<br />

ELSE<br />

color[u]::=negro<br />

tiempo++; f[u]::=tiempo<br />

P.<strong>de</strong>sapilar()<br />

ENDIF<br />

ENDWHILE<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Ejemplo numeración y arcos<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Lema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Sea G = 〈N,A〉 un grafo, y d[],f[] la numeración <strong>de</strong> <strong>de</strong>scubrimiento y<br />

finalización obtenida mediante un recorrido DF. Entonces<br />

Teorema<br />

(u,v) es un arco <strong>de</strong> la foresta o hacia a<strong>de</strong>lante si y solo si<br />

d[u] < d[v] < f[v] < f[u]<br />

(u,v) es un arco hacia atrás si y solo si<br />

d[v] < d[u] < f[u] < f[v]<br />

(u,v) es un arco que cruza si y solo si<br />

d[v] < f[v] < d[u] < f[u]<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

muchas propieda<strong>de</strong>s surgen a partir <strong>de</strong> la información obtenida<br />

en un recorrido DF<br />

En un recorrido DF <strong>de</strong> un grafo no dirigido G, todos sus arcos son <strong>de</strong><br />

la foresta o hacia atrás<br />

Demostración.<br />

Sea (u,v) un arco <strong>de</strong>l grafo, y supongamos que u es <strong>de</strong>scubierto<br />

antes que v. Luego v es <strong>de</strong>scubierto y finalizado antes <strong>de</strong> finalizar u.<br />

Si el nodo v tiene como padre a u entonces (u,v) es un arco <strong>de</strong> la<br />

foresta; si el nodo v tiene otro padre, entonces (u,v) es un arco hacia<br />

atrás. En forma similar se prueba si v es <strong>de</strong>scubierto antes que u.<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Lema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

En un recorrido DF <strong>de</strong> un grafo G, para cualquier par <strong>de</strong> nodos<br />

distintos u,v vale exactamente uno <strong>de</strong>:<br />

los intervalos [d[u],f[u]] y [d[v],f[v]] son totalmente disjuntos<br />

[d[u],f[u]] ⊂ [d[v],f[v]] y u es <strong>de</strong>scendiente <strong>de</strong> v<br />

[d[v],f[v]] ⊂ [d[u],f[u]] y v es <strong>de</strong>scendiente <strong>de</strong> u<br />

Demostración.<br />

Analizando caso por caso si d[u] < d[v] < f[u], d[u] < f[u] < d[v],<br />

d[v] < d[u] < f[v] y d[v] < f[v] < d[u]<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Corolario (anidamiento <strong>de</strong> <strong>de</strong>scendientes)<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

v es un <strong>de</strong>scendiente propio <strong>de</strong> u en la foresta <strong>de</strong> recorrido si y solo si<br />

d[u] < d[v] < f[v] < f[u]<br />

Demostración.<br />

Inmediato <strong>de</strong>l lema 7.<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Teorema (caminos blancos)<br />

Recorrido por Niveles<br />

Recorrido por profundidad<br />

En un recorrido DF <strong>de</strong> un grafo G, un nodo v es <strong>de</strong>scendiente <strong>de</strong> un<br />

nodo u si y solo si en el momento d[u] cuando u es <strong>de</strong>scubierto existe<br />

un camino <strong>de</strong> u a v que consiste totalmente <strong>de</strong> nodos blancos.<br />

Demostración.<br />

Para el solo si basta con aplicar el teorema 8 a todos los nodos<br />

intermedios.<br />

Para el si supongamos por el absurdo que v es alcanzable <strong>de</strong>s<strong>de</strong> u<br />

por un camino <strong>de</strong> nodos blancos en el momento d[u], pero v no es<br />

<strong>de</strong>scendiente <strong>de</strong> u. Se toma el primer nodo en el camino <strong>de</strong> u a v que<br />

no es <strong>de</strong>scendiente <strong>de</strong> u, y se <strong>de</strong>muestra que su intervalo está<br />

contenido en [d[u],f[u]], contradiciendo el teorema 8.<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Definición <strong>de</strong>l problema<br />

Problema: dado un grafo dirigido acíclico G, un or<strong>de</strong>n topológico<br />

es un or<strong>de</strong>namiento lineal <strong>de</strong> sus nodos <strong>de</strong> forma que si el arco<br />

(u,v) ∈ G entonces u aparece antes <strong>de</strong> v en el or<strong>de</strong>namiento<br />

si el grafo tiene ciclos, entonces tal or<strong>de</strong>namiento no existe<br />

el or<strong>de</strong>n topológico es usado para planificar una serie <strong>de</strong><br />

acciones que tienen prece<strong>de</strong>ncias: cada nodo representa una<br />

acción, y cada arco (u,v) significa que la acción u <strong>de</strong>be<br />

ejecutarse necesariamente antes <strong>de</strong> v<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

PROCEDURE Or<strong>de</strong>nTopológico(G)<br />

array f[1..n]<br />

DFS(G,f) % calculando f[v]<br />

L::= lista <strong>de</strong> nodos or<strong>de</strong>nada<br />

por f en forma <strong>de</strong>creciente<br />

RETURN L<br />

el tiempo <strong>de</strong> ejecución <strong>de</strong> este algoritmo claramente es<br />

Θ(n logn), pero es posible reducirlo a Θ(n + a) cambiando<br />

levemente el algoritmo <strong>de</strong>l recorrido (ejercicio)<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Correctitud<br />

Lema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

la numeración <strong>de</strong> los nodos en un recorrido DFS da una i<strong>de</strong>a <strong>de</strong>l<br />

algoritmo para resolver el problema<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Un grafo dirigido G es acíclico si y solo si cualquier recorrido DFS <strong>de</strong><br />

G no produce arcos hacia atrás.<br />

Demostración.<br />

El solo si es inmediato. Para el si basta aplicar el teorema 9 al primer<br />

nodo <strong>de</strong>l ciclo.<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Teorema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

El resultado <strong>de</strong>l algoritmo anterior es un or<strong>de</strong>n topológico.<br />

Demostración.<br />

Basta con mostrar que para todo arco (u,v) en G dirigido acíclico,<br />

f[v] < f[u].<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

sea G un grafo, su grafo traspuesto G T se <strong>de</strong>fine como<br />

G T = 〈N,{(u,v) : (v,u) ∈ A}〉<br />

es interesante observar que G y G T tienen los mismos CFC<br />

(ejercicio)<br />

el algoritmo para CFC hace dos recorridos: uno <strong>de</strong>l grafo G y otro<br />

<strong>de</strong>l grafo G T<br />

en el segundo recorrido, los nodos se consi<strong>de</strong>ran en or<strong>de</strong>n<br />

<strong>de</strong>creciente <strong>de</strong> f[]<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Definición <strong>de</strong>l problema<br />

dado un grafo dirigido G = 〈N,A〉 un componente fuertemente<br />

conexo (CFC) es un conjunto U ⊆ N maximal tal que para todo<br />

u,v ∈ U valen u G v y v G u (don<strong>de</strong> a G b significa que<br />

existe en G un camino <strong>de</strong> a a b)<br />

Problema: encontrar todos los CFC <strong>de</strong> un grafo dirigido G<br />

para el caso <strong>de</strong> grafos no dirigidos, el problema se <strong>de</strong>nomina<br />

componentes conexos y pue<strong>de</strong> resolverse directamente a partir<br />

<strong>de</strong> cualquiera <strong>de</strong> los recorridos vistos<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

PROCEDURE CFC(G)<br />

array f[1..n]<br />

DFS(G,f)<br />

calcular GT % el traspuesto <strong>de</strong> G<br />

array padre[1..n]<br />

DFS(GT, padre, f)<br />

% padre es la foresta <strong>de</strong>l recorrido,<br />

% tomando los nodos por f <strong>de</strong>creciente<br />

RETURN padre<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Correctitud<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

cada Árbol <strong>de</strong> la foresta representado en padre contiene<br />

exactamente los elementos <strong>de</strong> un CFC<br />

suponiendo una representación <strong>de</strong>l grafo mediante lista <strong>de</strong><br />

adyacencia, el tiempo y espacio <strong>de</strong>l algoritmo anterior es <strong>de</strong><br />

Θ(n + a) (ejercicio)<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

para <strong>de</strong>mostrar la correctitud <strong>de</strong>l algoritmo, se usará el concepto<br />

<strong>de</strong> grafo <strong>de</strong> componentes G CFC = 〈N CFC ,A CFC 〉 que está<br />

formado por un nodo que representa a cada componente<br />

fuertemente conexo en G, y para cada par <strong>de</strong> CFC u,v se<br />

agrega un arco (u,v) si en G existe en el componente u un nodo<br />

que presenta un arco hacia otro nodo en el componente v<br />

la principal propiedad <strong>de</strong> G CFC es que siempre se trata <strong>de</strong> un dag<br />

(ejercicio)<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Ejemplo<br />

Lema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Sean u,v ∈ N CFC entonces la existencia <strong>de</strong> (u,v) ∈ A CFC implica que<br />

(v,u) ∈ A CFC<br />

Demostración.<br />

Si existen los dos arcos, entonces u y v serían el mismo CFC en<br />

G.<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Teorema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

se extien<strong>de</strong> la numeración <strong>de</strong> <strong>de</strong>scubrimiento y finalización para<br />

conjuntos <strong>de</strong> nodos <strong>de</strong> la forma:<br />

d[C] = minu∈C(d[u])<br />

f[C] = maxu∈C(f[u])<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

El algoritmo calcula correctamente los CFC <strong>de</strong> cualquier grafo G.<br />

Demostración.<br />

Por inducción <strong>sobre</strong> la cantidad <strong>de</strong> árboles en la foresta <strong>de</strong>l segundo<br />

recorrido. Para el caso inductivo se muestra que si u es la raíz <strong>de</strong>l<br />

k-ésimo árbol <strong>de</strong>l segundo recorrido, entonces todos los nodos <strong>de</strong>l<br />

CFC <strong>de</strong> u pertenecen a ese árbol. A<strong>de</strong>más, por el corolario 13<br />

cualquier arco que toca el CFC <strong>de</strong> u <strong>de</strong>be ser tal que conecta un<br />

<strong>de</strong>scendiente <strong>de</strong> u con un nodo en un árbol anterior en la foresta.<br />

Luego el árbol con raíz u contiene exactamente el CFC <strong>de</strong> u.<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Lema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Sean u,v ∈ N CFC tal que (u,v) ∈ A CFC . Entonces f[u] > f[v].<br />

Demostración.<br />

Se distinguen dos casos <strong>de</strong> acuerdo a cual componente u o v es<br />

encontrado primero en el primer recorrido. Si primero se encuentra u<br />

entonces v es <strong>de</strong>scendiente <strong>de</strong> u.Si primero se encuentra v, dado que<br />

existe (u,v) entonces no existe (v,u) por el lema 12. Esto significa<br />

que en el momento f[v] todos los nodos en u son blancos, por lo que<br />

f[u] > f[v].<br />

Corolario<br />

Sea C,C ′ dos CFC distintos <strong>de</strong> un grafo G = 〈N,A〉, entonces si<br />

existe (u,v) ∈ A T tal que u ∈ C y v ∈ C ′ vale que f[C] < f[C ′ ].<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Definición <strong>de</strong>l problema<br />

sea G no dirigido, conexo. Un punto <strong>de</strong> articulación es un nodo<br />

<strong>de</strong> G cuya eliminación (junto con todos sus arcos inci<strong>de</strong>ntes) <strong>de</strong>ja<br />

al grafo resultante disconexo<br />

un puente es un arco <strong>de</strong> G cuya eliminación <strong>de</strong>ja al grafo<br />

resultante disconexo<br />

Problema: dado un grafo no dirigido conexo G = 〈N,A〉 encontrar<br />

todos sus puntos <strong>de</strong> articulación<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Lema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

se pue<strong>de</strong>n <strong>de</strong>terminar los puntos <strong>de</strong> articulación mediante un<br />

solo recorrido DFS <strong>de</strong> G<br />

los siguientes resultados permiten <strong>de</strong>finir el algoritmo<br />

Sea G un grafo no dirigido conexo, y consi<strong>de</strong>remos n ∈ N el nodo<br />

inicial <strong>de</strong> un recorrido DF. Entonces n es un punto <strong>de</strong> articulación si y<br />

solo tiene al menos dos hijos.<br />

Demostración.<br />

Es claro el si. Para el solo si, sean n1,n2 dos <strong>de</strong>scendientes <strong>de</strong> n. Si n<br />

no fuera punto <strong>de</strong> articulación existiría un camino blanco entre n1 y n2<br />

en el momento <strong>de</strong> visitar el primero <strong>de</strong> ellos, con lo que el segundo<br />

sería <strong>de</strong>scendiente <strong>de</strong>l primero.<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

<strong>de</strong> acuerdo al lema anterior, para saber si un nodo n es un punto<br />

<strong>de</strong> articulación es suficiente con verificar si se pue<strong>de</strong> acce<strong>de</strong>r a<br />

un ancestro propio <strong>de</strong>s<strong>de</strong> un <strong>de</strong>scendiente <strong>de</strong> n por un arco fuera<br />

<strong>de</strong> la foresta<br />

teniendo en cuenta la numeración <strong>de</strong> <strong>de</strong>scubrimiento generada<br />

por un recorrido DFS, se pue<strong>de</strong> computar para cada nodo el<br />

ancestro más viejo que se alcanza a través <strong>de</strong> arcos hacia atrás<br />

⎧<br />

⎪⎨<br />

d[v]<br />

d[w] : (v,w) es un arco hacia atrás<br />

masviejo[v] = min<br />

⎪⎩<br />

masviejo[w] : (v,w) es un arco<br />

<strong>de</strong> la foresta<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Lema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Sea G un grafo no dirigido conexo, y consi<strong>de</strong>remos n ∈ N un nodo no<br />

inicial en un recorrido DF. Entonces n ∈ N es punto <strong>de</strong> articulación si y<br />

solo existe un hijo u <strong>de</strong> n tal que ningún <strong>de</strong>scendiente v <strong>de</strong> u tiene un<br />

arco (v,w) don<strong>de</strong> w es ancestro propio <strong>de</strong> n.<br />

Demostración.<br />

Es claro que si n es punto <strong>de</strong> articulación entonces tal arco no pue<strong>de</strong><br />

existir. Para el solo si, suponemos que existe u hijo <strong>de</strong> n tal que<br />

ninguno <strong>de</strong> sus <strong>de</strong>scendientes v tiene un arco hacia un ancestro<br />

propio w <strong>de</strong> n. Entonces, removiendo n <strong>de</strong>l grafo no existe ningún<br />

camino posible <strong>de</strong> u a w, por lo que n es punto <strong>de</strong> articulación.<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

PROCEDURE PuntosArticulación(G)<br />

array d[1..n], masviejo[1..n], pa[1..n]<br />

DFS(G,d)<br />

calcular masviejo en otro recorrido DFS <strong>de</strong> G<br />

pa[1]::= tiene más <strong>de</strong> un hijo en la foresta<br />

FOR cada v en N-{1}<br />

pa[v]::= existe un hijo u <strong>de</strong> v<br />

tal que d[v]


Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

el tiempo <strong>de</strong> ejecución es <strong>de</strong> Θ(a) (dos recorridos más una<br />

iteración <strong>sobre</strong> todos los nodos)<br />

se podrían mejorar las constantes realizando el cálculo completo<br />

en un sólo recorrido (ejercicio)<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

se pue<strong>de</strong> obtener entonces un algoritmo en tiempo O(a) que<br />

encuentre los puentes, a partir <strong>de</strong> un recorrido DF <strong>de</strong>l grafo<br />

ejercicio: especificar un algoritmo para encontrar los puentes en<br />

un sólo recorrido <strong>de</strong>l grafo<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Puentes<br />

Lema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

para <strong>de</strong>terminar los puentes es útil la siguiente propiedad<br />

Sea G = 〈N,A〉 un grafo no dirigido. Un arco (u,v) ∈ A es un puente<br />

en G si y solo si (u,v) no pertenece a ningún ciclo simple en G.<br />

Demostración.<br />

⇒): entonces removiendo (u,v) existiría un otro camino <strong>de</strong> u a v, con<br />

lo que el grafo resultante sería conexo, contradiciendo el hecho <strong>de</strong><br />

que es puente. ⇐): luego el grafo obtenido removiendo (u,v) es<br />

conexo por lo que existe un camino <strong>de</strong> u a v que no use (u,v).<br />

Tomando ese camino más (u,v) se forma un ciclo simple, con lo se<br />

obtiene una contradicción.<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Definición <strong>de</strong>l problema<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

una red <strong>de</strong> flujo es un grafo dirigido G = 〈N,A〉 don<strong>de</strong> cada arco<br />

(u,v) ∈ A tiene asociado una capacidad c(u,v) ≥ 0, y se<br />

distinguen dos nodos s y t llamados fuente y <strong>de</strong>stino, tal que<br />

ningún arco llega a la fuente, o sale <strong>de</strong>l <strong>de</strong>stino<br />

a<strong>de</strong>más, por conveniencia, si (u,v) ∈ A entonces se supone<br />

c(u,v) = 0<br />

también que para todo n ∈ N, s G n G t<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

un flujo en G es una función f : N × N −→ R que satisface:<br />

restricción <strong>de</strong> capacidad: f(u,v) ≤ c(u,v) para todo u,v ∈ N<br />

simetría oblicua: f(u,v) = −f(v,u) para todo u,v ∈ N<br />

conservación <strong>de</strong> flujo: ∑v∈N−{s,t} f(u,v) = 0<br />

el valor <strong>de</strong> un flujo |f| se <strong>de</strong>fine como<br />

|f| = ∑v∈N f(s,v) = ∑v∈N f(v,t).<br />

Problema: dada una red <strong>de</strong> flujo G, el problema MAXFLUJO<br />

consiste en encontrar el máximo flujo que admite G<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

en el flujo sólo se representan los valores positivos<br />

también se cancelaran flujos opuestos entre dos nodos, <strong>de</strong> forma<br />

que el flujo representado sea positivo en a lo sumo uno <strong>de</strong> los<br />

sentidos<br />

se supondrá que todas las capacida<strong>de</strong>s son enteros<br />

si las capacida<strong>de</strong>s son racionales, se pue<strong>de</strong>n escalar para que<br />

se consi<strong>de</strong>ren enteros<br />

también usaremos en la notación la sumatoria implícita,<br />

f(U,V) = ∑<br />

∑<br />

x∈U y∈V<br />

f(x,y)<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Ejemplo <strong>de</strong> flujo<br />

Propieda<strong>de</strong>s<br />

Lema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

Sea G una red <strong>de</strong> flujo, y f un flujo en G. Entonces valen:<br />

para todo X ⊆ N, f(X,X) = 0<br />

para todo X,Y ⊆ N, f(X,Y ) = −f(Y ,X)<br />

para todo X,Y ,Z ⊆ N tal que X ∩ Y = /0, valen<br />

f(X ∪ Y ,Z) = f(X,Z) + f(Y ,Z) y<br />

f(Z,X ∪ Y ) = f(Z,X) + f(Z,Y )<br />

Demostración.<br />

ejercicio, usando las propieda<strong>de</strong>s <strong>de</strong> flujo<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Corolario<br />

| f |= f(V,t)<br />

Demostración.<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

| f |= f(s,V) = f(V,V) − f(V − s,V) = −f(V − s,V) = f(V,V − s) =<br />

f(V,t) + f(V,V − s − t) = f(V,t)<br />

Red residual<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

sea G una red <strong>de</strong> flujo, y f un flujo <strong>sobre</strong> G. Una red residual es<br />

un grafo Gf = 〈N,Ef 〉, don<strong>de</strong> los arcos son<br />

Ef = {(u,v) : c(u,v) − f(u,v) > 0} y la capacidad es<br />

precisamente c(u,v) − f(u,v)<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Método <strong>de</strong> Ford-Fulkerson<br />

Lema<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

el método <strong>de</strong> Ford-Fulkerson permite resolver el problema<br />

MAXFLUJO<br />

lo llamamos método porque produce distintos algoritmos, con<br />

distintos tiempos <strong>de</strong> ejecución <strong>de</strong> acuerdo a la implementación<br />

se basa en los conceptos <strong>de</strong> red residual, camino <strong>de</strong> aumento, y<br />

corte<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

Sea G una red <strong>de</strong> flujo, f un flujo <strong>sobre</strong> G, Gf la red residual y f ′ un<br />

flujo <strong>sobre</strong> Gf . Entonces el flujo sum f + f ′ , <strong>de</strong>finido<br />

(f + f ′ )(u,v) = f(u,v) + f ′ (u,v), es un flujo en G tal que<br />

| f + f ′ |=| f | + | f ′ |.<br />

Demostración.<br />

Se <strong>de</strong>be verificar que cumple con las tres propieda<strong>de</strong>s <strong>de</strong> flujo, y que<br />

su valor es exactamente la suma <strong>de</strong> los valores <strong>de</strong> f y f ′ (ejercicio).<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Camino <strong>de</strong> aumento<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

sea G una red <strong>de</strong> flujo, y f un flujo <strong>sobre</strong> G. Un camino <strong>de</strong><br />

aumento es un camino s Gf t en la red residual Gf<br />

la capacidad residual <strong>de</strong> s Gf t es la mínima capacidad <strong>de</strong> los<br />

arcos que pertenecen al camino, y se nota cf (p)<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Lema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

Sea G una red <strong>de</strong> flujo, f un flujo <strong>sobre</strong> G y p un camino <strong>de</strong> aumento<br />

en Gf . Entonces existe un flujo fp <strong>de</strong>finido<br />

⎧<br />

⎨<br />

fp(u,v) =<br />

⎩<br />

con valor | fp |= cf (p) > 0.<br />

Demostración.<br />

cf (p) si (u,v) está en p<br />

−cf (p) si (v,u) está en p<br />

0 sino<br />

Es suficiente con probar las tres propieda<strong>de</strong>s <strong>de</strong> flujo, y verificar el<br />

valor <strong>de</strong> fp.<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Corte <strong>de</strong> una red <strong>de</strong> flujo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

G una red <strong>de</strong> flujo, y f un flujo <strong>sobre</strong> G. Un corte es una partición<br />

<strong>de</strong> N en S y T = N − S tal que s ∈ S y t ∈ T<br />

el flujo neto a través el corte (S,T ) es f(S,T ). La capacidad <strong>de</strong><br />

un corte (S,T ) es c(S,T )<br />

el corte mínimo <strong>de</strong> una red es un corte cuya capacidad es<br />

mínima entre todos los cortes<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Algoritmo<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

el teorema anterior permite <strong>de</strong>finir un algoritmo iterativo, a partir<br />

<strong>de</strong> un flujo nulo, que compute el flujo máximo <strong>de</strong> una red <strong>de</strong> flujo<br />

se <strong>de</strong>nomina Ford-Fulkerson, y en cada iteración encuentra un<br />

camino <strong>de</strong> aumento, obtiene el flujo <strong>de</strong> ese camino y se lo suma<br />

al flujo anterior, resultando en un flujo con valor mayor<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Teorema (Máximo flujo, mínimo corte)<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

Sea G una red <strong>de</strong> flujo, y f un flujo en G. Entonces son equivalentes:<br />

1 f es un flujo máximo <strong>de</strong> G<br />

2 la red residual Gf no contiene caminos <strong>de</strong> aumento<br />

3 | f |= c(S,T ) para algún corte (S,T ) <strong>de</strong> G<br />

Demostración.<br />

1)⇒ 2): si f es el máximo flujo y Gf tiene camino <strong>de</strong> aumento p existe<br />

un flujo fp (lema 22) y f + fp es un flujo en G <strong>de</strong> mayor valor que f .<br />

2)⇒ 3): entonces sea S = {v ∈ N : s Gf v} y T = N − S. Se pue<strong>de</strong><br />

ver que (S,T ) es un corte y que | f |= f(S,T ) = c(S,T ). 3) ⇒ 1):<br />

para todos los cortes (S,T ) se pue<strong>de</strong> ver que | f |≤ c(S,T ). Luego<br />

| f |= c(S,T ) implica que f es un flujo máximo.<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

PROCEDURE FordFulkerson (G,s,t,c)<br />

FOR cada arco (u,v) en A<br />

f[u,v]::=0; f[v,u]::=0<br />

ENDFOR<br />

WHILE existe un camino <strong>de</strong> aumento p en Gf<br />

cf(p)::=min{(c[u,v]-f[u,v])<br />

para todo (u,v) en p}<br />

FOR cada arco (u,v) en p<br />

f[u,v]::=f[u,v]+c_f(p)<br />

f[v,u]::=-f[u,v]<br />

ENDFOR<br />

ENDWHILE<br />

RETURN f<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Ejemplo (I)<br />

Ejemplo (III)<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Ejemplo (II)<br />

Ejemplo (IV)<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Ejemplo (V)<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

la <strong>de</strong>pen<strong>de</strong>ncia <strong>de</strong>l tiempo <strong>de</strong> ejecución en el valor <strong>de</strong>l flujo, y no<br />

en la longitud <strong>de</strong> su representación, no es bueno<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Análisis <strong>de</strong>l tiempo <strong>de</strong> ejecución<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

PROCEDURE FordFulkerson (G,s,t,c)<br />

FOR cada arco (u,v) en A<br />

f[u,v]::=0; f[v,u]::=0<br />

ENDFOR<br />

WHILE existe un camino <strong>de</strong><br />

aumento p en Gf<br />

cf(p)::= capacidad mínima <strong>de</strong> p<br />

FOR cada arco (u,v) en p<br />

f[u,v]::=f[u,v]+cf(p)<br />

f[v,u]::=-f[u,v]<br />

ENDFOR<br />

ENDWHILE; RETURN f<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Algoritmo <strong>de</strong> Edmonds-Karp<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

costo veces<br />

b a<br />

Θ(n + a) O(|f ∗ |)<br />

O(a) O(|f ∗ |)<br />

b O(a|f ∗ |)<br />

b O(a|f ∗ |)<br />

f ∗ es el resultado<br />

el algoritmo <strong>de</strong> Edmonds-Karp es una instancia <strong>de</strong>l método <strong>de</strong><br />

Ford-Fulkerson en don<strong>de</strong> la búsqueda <strong>de</strong>l camino <strong>de</strong> aumento p<br />

se hace mediante una búsqueda por niveles comenzando por s<br />

el recorrido por niveles permite encontrar los caminos mínimos<br />

(en cuanto a cantidad <strong>de</strong> arcos) <strong>de</strong>s<strong>de</strong> el origen a cada nodo<br />

entonces en la red residual, el camino mínimo ya no existe. Esto<br />

permite ajustar la cantidad <strong>de</strong> iteraciones <strong>de</strong>l ciclo WHILE<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad


Lema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

En el algoritmo EK, si v ∈ N − {s,t} entonces la distancia mínima<br />

nivel[v] en la red residual Gf aumenta con cada aumento <strong>de</strong> flujo.<br />

Demostración.<br />

Sea v el nodo con menor nivel <strong>de</strong> todos los w tal que<br />

niveli[w] > niveli+1[w], y s fi+1 u → v el camino mínimo que<br />

redujo el nivel <strong>de</strong> v. Sabemos que niveli+1[u] = niveli+1[v] − 1 y<br />

que niveli+1[u] ≥ niveli[u] (por la elección <strong>de</strong> v). Se <strong>de</strong>duce que<br />

(u,v) ∈ Efi y (u,v) ∈ Efi+1 , y como el camino <strong>de</strong> aumento es el<br />

camino más corto (por el algoritmo), entonces (v,u) pertenece al<br />

camino <strong>de</strong> aumento en la iteración i + 1. Luego<br />

niveli[v] = niveli[u] − 1 ≤ niveli+1[u] − 1 = niveli+1[v] − 2<br />

lo que contradice la disminución <strong>de</strong> la distancia mínima.<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

como cada iteración (construir el grafo residual, hacer el recorrido<br />

BFS, encontrar el camino <strong>de</strong> aumento y la capacidad residual, y<br />

actualizar el flujo) <strong>de</strong>l algoritmo EK toma <strong>de</strong> O(a), <strong>de</strong> acuerdo al<br />

teorema anterior el tiempo total <strong>de</strong> ejecución es <strong>de</strong> O(na 2 )<br />

se elimina <strong>de</strong> esta forma la <strong>de</strong>pen<strong>de</strong>ncia <strong>de</strong>l tiempo <strong>de</strong> ejecución<br />

en f ∗<br />

existen algoritmos asintóticamente mejores (O(n 2 a), O(n 3 )) para<br />

el mismo problema<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Teorema<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

El número total <strong>de</strong> iteraciones <strong>de</strong>l algoritmo EK en una red <strong>de</strong> flujo<br />

G = 〈N,A〉 es a lo sumo O(na).<br />

Demostración.<br />

Primero se muestra que la cantidad <strong>de</strong> veces que cada arco (u,v)<br />

pue<strong>de</strong> ser crítico (ie coinci<strong>de</strong> con la capacidad residual) es n/2 − 1<br />

veces. Sea i la iteración don<strong>de</strong> (u,v) es arco crítico, y j la iteración<br />

don<strong>de</strong> (v,u) es arco crítico. Entonces<br />

niveli[u] = niveli[v] + 1 ≤ nivelj[v] + 1 = nivelj[v] + 2, con<br />

lo que la distancia mínima disminuye al menos en 2 entre cada para<br />

<strong>de</strong> iteraciones don<strong>de</strong> (u,v) es arco crítico. Y (n − 2) es una cota <strong>de</strong> la<br />

máxima distancia mínima. Entonces como hay O(a) arcos posibles a<br />

ser arcos críticos, no pue<strong>de</strong> haber más <strong>de</strong> O(na) iteraciones.<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad<br />

Introducción<br />

Recorridos<br />

Or<strong>de</strong>namiento topológico<br />

Componentes fuertemente conexos<br />

Puntos <strong>de</strong> articulación y puentes<br />

Flujo máximo<br />

Red residual<br />

Camino <strong>de</strong> aumento<br />

Corte<br />

Método <strong>de</strong> Ford-Fulkerson<br />

otras variantes <strong>de</strong>l problema <strong>de</strong> máximo flujo se pue<strong>de</strong>n reducir a<br />

la versión analizada. Por ejemplo, si se tienen múltiples orígenes<br />

o <strong>de</strong>stinos<br />

Pablo R. Fillottrani <strong>Algoritmos</strong> y Complejidad

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!