1. Problemas de flujos.
Existen muchos problemas de flujos en redes. Una red es un sistema de líneas o canales
que conectan diferentes puntos y trasmiten algún tipo de información. Algunos
ejemplos de redes son las líneas de comunicación, redes de ferrocarril, redes de tuberías
de agua, redes de carreteras, redes de aviación, etc. En todas estas redes estaremos
interesados en enviar alguna mercancía específica desde ciertos puntos de suministro a
algunos puntos de demanda. Por ejemplo, en un sistema de tuberías podríamos enviar
agua. Muchos de los problemas de flujos en redes se pueden formular como problemas
de programación lineal y obtener su solución mediante el método del simplex. Sin
embargo, se han desarrollado otras técnicas más eficientes que varían con el problema
en cuestión. De entre este tipo de problemas destacamos los siguientes:
- Problema de flujo máximo.
- Problema de flujo a coste mínimo.
Problema de flujo Máximo.
Se considera el problema de trasladar una cierta mercancía desde un punto específico,
llamado fuente a un punto de destino, denominado sumidero. Para ello se considera un
grafo dirigido G = (V,A), en el que se consideran dos nodos o vértices: uno denominado
nodo fuente y otro denominado nodo destino. Por supuesto, se considera que no existe
un arco directo que conecte el nodo fuente con el nodo destino. Por supuesto, el grafo
estará formado por unos nodos intermedios conocidos como puntos de transbordo a
través de los cuales el flujo (la mercancía) es desviado.
Sea
V = conjunto de todos los vértices o nodos del grafo.
fij = el flujo que circula por el arco (i,j).
f = cantidad total de flujo que se lleva desde el nodo fuente al nodo destino.
kij = capacidad del arco (i,j).
1
Ejemplo:
s
s = nodo fuente n
n = nodo destino
2
1, 2 = nodos intermedios
2. Objetivo:
Determinar el máximo flujo f que se puede enviar desde el nodo fuente s al nodo
destino n, teniendo en cuenta las capacidades kij sobre el flujo de cada arco (i,j) y que el
flujo se debe conservar.
Modelo de programación lineal:
Max z =f
s.a.
∑f ij − ∑f ji =0 ∀i ∈ V - {s, n} (1.1)
j∈Γ + ( i ) j∈Γ − ( i )
0 ≤ f ij ≤ k ij ∀(i, j) ∈ A (1.2)
Las ecuaciones (1.1) representan la conservación del flujo en los nodos. Mientras que
las restricciones (1.2) son sobre el flujo que circula por cada arco, para que no sea
negativo y no supere la capacidad del arco.
En el ejemplo anterior se traduce en
Max z= f
s.a. f s1 + f s 2 = f
f12 + f 1n = f s1 + f 21
f 21 + f 2 n = f s 2 + f12
f1n + f 2 n = f
0 ≤ f s1 ≤ k s1
0 ≤ f s2 ≤ ks2
0 ≤ f 12 ≤ k12
0 ≤ f 21 ≤ k 21
0 ≤ f1n ≤ k1n
0 ≤ f 2n ≤ k 2n
Veamos un método eficiente para resolver el problema del flujo máximo directamente
sin usar el método del simplex.
Conceptos previos:
Definición: Dado cualquier nodo i todos los arcos que salen del nodo i se denominan
arcos hacia delante con respecto al nodo i.
Definición: Dado cualquier nodo i todos los arcos que entran al nodo i se denominan
arcos hacia atrás para el nodo i.
3. Definición: Un corte que separa el nodo fuente del nodo destino es una partición de los
nodos de la red en dos subconjuntos S y S* tal que el nodo fuente está en S y el nodo
destino está en S*.
Un ejemplo de corte en el ejemplo anterior podría ser (S, S*) dado por S = {s,1,2}.
1
s
n
2
Corte
Otro corte que separa s y n es el siguiente:
1
s
n
2
Corte
Definición:
La capacidad de un corte es la suma de todas las capacidades de los arcos procedentes
de los nodos de S a los nodos en S*. Se denota K(S, S*). Esto es
K (S , S * ) = ∑k ij
( i , j )∈( S , S * )
En los cortes anteriores, sus capacidades son:
S = {s,1,2}, K(S,S*) = k1n + k2n
S = {s,2}, K(S,S*) = ks1 + k21 + k2n
Definición: El corte con la capacidad más pequeña se denomina corte mínimo.
A partir de los ejemplos anteriores de cortes se puede apreciar que si todos los arcos de
un corte se eliminan de la red entonces no existe un camino que una el nodo fuente con
el nodo destino, de aquí que el flujo de s a n no seria posible. En otras palabras,
cualquier flujo de s a n debe atravesar los arcos en el corte, y por consiguiente, el flujo f
estará limitado por la capacidad de ese corte. La relación entre flujos y cortes vendrá
dada por el siguiente lema:
4. Lema: Para cualquier red dirigida, si f es el flujo desde el nodo fuente al nodo destino,
y (S, S*) es un corte, entonces el valor de f es menor o igual que la capacidad de ese
corte K(S,S*).
Como consecuencia de este lema se tiene que cualquier flujo compatible desde el nodo
fuente al nodo destino no puede exceder la capacidad de ningún corte. Por tanto, el flujo
máximo a través de la red está limitado por la capacidad del corte mínimo. El siguiente
teorema establece que siempre es posible encontrar el flujo de s a n igual a la capacidad
del corte mínimo.
Teorema de flujo máximo-corte mínimo: (Ford Fulkerson).
Para cualquier red el flujo máximo desde el nodo fuente al nodo destino es igual a la
capacidad del corte mínimo.
A partir de este teorema el problema de encontrar el flujo máximo en una red se traduce
en encontrar las capacidades de todos los cortes y elegir la mínima capacidad. Por otra
parte, dado el valor máximo de f no se especifica como este flujo es distribuido a través
de los distintos arcos. Además este método es poco recomendable ya que el número de
posibles cortes que separan el nodo fuente del destino son 2n-2.
Definición: Dada una red G = (V,A) llamamos Red Residual o Incrementeal R(f), a
aquella red formada a partir de G, con el mismo conjunto de nodos que ésta, y dado
cada arco dirigido (i,j) ∈ A en la red original, que no tiene arco en la dirección opuesta
(es decir, (j,i) ∉ A), tal que 0 ≤ fij ≤ kij se consideran en la Red Incremental dos arcos
(i,j) y (j,i) con capacidades rij = kij - fij y rji = fij , respectivamente. A dichas
capacidades se las denomina capacidades residuales o incrementales.
Al principio que no circula ningún flujo por los arcos de la red original, la red residual
difiere de la original en que para cada arco dirigido de la red original sin arco opuesto,
ahora se le añade su opuesto con capacidad nula.
Definición: Se denomina Camino Incremental a todo camino dirigido desde el nodo
fuente al nodo destino en la red incremental.
Definición: Llamamos Cuello de Botella y lo denotamos por δ a la menor capacidad
residual de los arcos en un camino incremental, es decir, δ = min (i,j) ∈P rij. Dado el
siguiente camino P ⊂ R(f)
5 2
s a b n δ= 2
3
5. Definición: Un arco se dice saturado sí y solo sí fij = kij ó rij = 0 y kij > 0.
El motivo de introducir el concepto de red residual o red incremental se
debe a los siguiente, fijémonos en la red siguiente:
1
1 2
1
2
1 1
s n
1
3
Si se elige como primer camino incremental P = {(s,1),(1,3),(3,2),(2,n)}
entonces saturo los arcos (1,3),(3,2) y (2,n) y no podemos enviar más flujo
de s a n consiguiendo un valor para f = 1, cuando el flujo máximo es f = 2.
Sin embargo, tomando ahora el camino incremental P’ =
{(s,1),(1,2),(2,3),(3,n)} podemos enviar una unidad más de s a n y deshacer
el error cometido al enviar una unidad de flujo a través del arco (3,2).
Notemos que ahora se ha enviado una unidad de flujo a través del arco
(2,3), el cual no existe en la red original.
El algoritmo de flujo máximo consiste en encontrar un camino a través del
cual se puede enviar un flujo positivo desde el nodo fuente al nodo destino.
Tal camino es a lo que denominabamos camino incremental, y se usa para
enviar tanto flujo como sea posible desde s a n. El proceso se repite hasta
que no se pueda encontrar ningún otro camino incremental, que mejore el
flujo total de s a n. En dicho caso, se ha encontrado el flujo máximo.
6. Proceso de etiquetado:
Este proceso se usa para encontrar un camino incremental desde el nodo
fuente al nodo destino. Comenzando con el nodo fuente s, se dice que
cualquier nodo j se puede etiquetar si podemos enviar un flujo positivo
desde s a j. En general, desde cualquier nodo i podemos etiquetar el nodo j
si se satisface una de las siguientes condiciones:
1.- El arco que conecta los nodos i y j es un arco hacia delante y el flujo en
el arco (i,j) es menor que su capacidad ( es decir, fij ≤ kij).
2.- El arco que conecta i y j es un arco hacia atrás y el flujo en el arco (j,i)
es mayor que 0.
Se continúa el proceso de etiquetado hasta que el nodo destino sea
etiquetado. Entonces se ha conseguido un camino incremental.
Algoritmo del Flujo Máximo:
El algoritmo se inicializa con un flujo nulo o cualquier flujo factible en
todos los arcos, esto es, satisfaciendo las restricciones de capacidad y
conservación de los flujos en todos los nodos. Para mejorar este flujo, se
etiqueta inicialmente el nodo s y se aplica el proceso de etiquetado para
etiquetar los otros nodos hasta alcanzar el destino. Cuando esto ocurra
tendremos un camino incremental desde s a n a través del cual se puede
enviar un flujo positivo. A continuación, volvemos hacia atrás en el camino
incremental con la ayuda de las etiquetas de los nodos y calculamos el flujo
máximo δ que puede ser enviado por el camino. Entonces incrementamos
el flujo en δ unidades en todos los arcos hacia delante en el camino
incremental y decrementamos el flujo en δ unidades en todos los arcos
hacia atrás. Repetimos el proceso de etiquetado para encontrar otro camino
incremental desde s a n. El algoritmo termina cuando no se pueda encontrar
ningún otro camino incremental, lo que nos conduce al máximo flujo
posible de s a n.
7. ALGORITMO:
Paso 0:
Se inicializa f = 0 ( o cualquier flujo factible) y fij = 0 ∀ (i,j) ∈ A.
Se construye la red incremental, que coincide con la original. Esto es,
rij = kij para todo arco en la red original y se añade su opuesto con rji = 0.
Sea δ = ∝. Sea hace i = s el nodo fuente, se marca con Predi = 0.
Paso 1:
Se elige un j ∈ Γ(i) no marcado tal que rij > 0 para el arco (i,j) y se marca
con Predj = i.
Se asigna δ = min{δ,rPredj j}. En caso de que no exista y si i = s parar ya que
se ha alcanzado el máximo flujo posible que se puede enviar desde s a n.
Si i ≠ s se hace i = Predi y se busca otro j ∈ Γ(i), no marcado con rij > 0.
Paso 2:
Si j = n, hacer f = f + δ, e ir al paso 3.
En caso contrario, hacer i = j y repetir el paso 1.
Paso 3:
Cambiamos rPredj j = rPredj j - δ y rj Predj = rj Predj + δ.
Hacer j = Predj, si j = s ir al paso 4. En otro caso, repetimos el paso 3.
Paso 4:
Se borran todas las marcas menos la de s, sea s = i. Se vuelve a asignar δ =
∝ y se va al paso 1.
8. Ejemplo: Sea la siguiente red en la cual los números sobre los arcos
representan las capacidades.
1 9
7
f=0 f=0
s n
3
9
8
2
Camino incremental
7 1
s n
3
8
2
1 9
4
3
f=3 f=3
s n
3 0 3
9
5
2
9. Nuevo camino incremental
1 9
4
s n
1 5
0
7 4
f = 12 f = 12
s n
0 3 0
5
4
8
2
1
5
s n
3
4
2
1 7
0
7 2
f = 15 7 f = 15
s n
3 0
8
8
1
0
2
10. Extensiones:
Caso dirigido: Consideremos una red que contiene aristas en lugar de arcos. Dada una
arista que conecta los nodos i y j, con capacidad K lo interpretamos como sigue:
fij ≤ K
fji ≤ K
fij * fji = 0
En otras palabras, un máximo de K unidades de flujo es posible entre los nodos i y j en
cualquier dirección, pero el flujo se permite en una única dirección. Tengamos en
cuenta que el algoritmo visto anteriormente sólo se puede aplicar a redes dirigidas
donde la dirección del flujo se especifica en todos los arcos. Para encontrar el flujo
máximo en una red no dirigida primero convertimos la red en una red equivalente
dirigida, y entonces aplicamos el método de etiquetado.
Ejemplo:
Consideremos una red de calles como se muestra en el grafo
1 30 3
40
50
s
s 15 25
20
30
30
2 50 4
11. Problema de flujo a coste mínimo.-
Sea G = (V,A) un grafo con dos vértices fijos, s el nodo fuente y t el nodo destino. Cada
arco (i,j) ∈ A tiene asociada una capacidad kij y un coste por unidad de flujo que circula
por cada arco cij. Sea Φ la cantidad de flujo demandada desde el nodo t, para ser
servida desde el nodo s. Entonces podemos plantear el problema de flujo a coste
mínimo en los siguientes términos: enviar Φ unidades de flujo desde el nodo s al nodo
t de G = (V,A) con el patrón de flujo cuyo coste asociado sea el mínimo, satisfaciendo
las restricciones de capacidad y conservación en los nodos V – {s,t}.
En este caso el patrón de flujo f de ser tal que :
∑f ij − ∑f ij =0 ∀ V − {s , t }
j∈Γi + j∈Γi −
Conservación del flujo
∑f sj = ∑f jt =Φ
j∈Γs + j∈Γt −
Restricciones de capacidad 0 ≤ f ij ≤ k ij ∀(i, j) ∈ A
Mientras que el coste del patrón de flujo viene dado por
Z( f ) = ∑c
( i , j )∈ A
ij f ij
Red residual.-
La red residual R(f) correspondiente a un flujo f se define como sigue: Reemplazamos
cada arco (i,j) ∈ A por dos arcos (i,j) y (j,i). El arco (i,j) tiene un coste cij y una
capacidad residual de rij = kij – fij, y el arco (j,i) tiene un coste de cji = -cij y una
capacidad residual de rji = fij. En la red residual se consideran sólo los arcos con
capacidad positiva.
12. Algoritmo de Busacker.
El algoritmo de Busacker y Gowen (1961) intenta enviar las Φ unidades de flujo de s a t
eligiendo en cada iteración el camino de mínimo coste de s a t, que envía un flujo igual
al cuello de botella del camino. El algoritmo termina cuando se han enviado las Φ
unidades de flujo, o no hay camino de s a t. En este último caso el problema no tiene
solución. Denotamos:
CT = coste total del camino que envía las Φ unidades
CC = coste del camino mínimo que se calcula en cada iteración.
Sea G = (V,A) un grafo dado, y s y t dos vértices fijados a priori.
Paso 1:
Asignar CT = 0.
Construir la red incremental de G, y asignar
⎧k ij si (i, j ) ∈ A ⎧cij si (i, j ) ∈ A
rij = ⎨ cij = ⎨
*
⎩0 en otro caso ⎩∞ en otro caso
Paso 2:
Buscar el camino mínimo de s a t en la red incremental usando el
algoritmo de Ford, y almacenarlo en Predi ∀ i = s,...,t.
Asignar a CC el coste de tal camino .
Si no existe tal camino Parar, no hay solución factible. Sea δ = ∝ e i = t.
Paso 3:
Si i = s, hacer i = t e ir al Paso 4.
En otro caso , si δ > rPredi,i entonces δ = rPredi,i . Hacer i = Predi y repetir el
paso 3.
Paso 4:
Si Φ - δ > 0 entonces asignar θ = δ.
En otro caso hacer θ = Φ.
13. Paso 5:
Si i = s, ir al Paso 6.
En otro caso,
rPredi,i = rPredi,i - θ, ri,Predi = ri,Predi + θ
ci,Predi* = - cPredi,i*
y para aquellos arcos tales que rPredi,i = 0 entonces cPredi,i* = ∝.
Hacer i = Predi y repetir el Paso 5.
Paso 6:
Asignar CT = CT + θ * CC.
Si Φ - δ > 0 hacer Φ = Φ - δ y buscar un nuevo camino de coste mínimo de
s a t pero con los nuevos costes asignados a los arcos. Almacenarlo en Predi
∀ i = s,...,t y asignar a CC el coste de tal camino.
Hacer δ = ∝ e i = t e ir al Paso 3.
En otro caso de que no exista tal camino, parar puesto que no existe
solución factible.
Si Φ - δ ≤ 0, parar hemos encontrado el camino de flujo a coste mínimo.
Ejemplo:
(5,20)
1 2
(3,18)
(5,14)
s (4,15) t
(8,12)
(8,20) (3,17)
3