33. Redes de flujo

Una red de flujo modela el transporte de una cantidad a través de conexiones con capacidad limitada. El flujo sale de una fuente, se conserva en los nodos intermedios y llega a un sumidero.

33.1 Introducción

Muchos sistemas transportan algo por una red: agua por tuberías, datos por enlaces, vehículos por carreteras o productos por rutas logísticas. Cada conexión admite una cantidad máxima y la pregunta habitual es cuánto puede enviarse desde un origen hasta un destino.

Las redes de flujo convierten esa situación en un grafo dirigido con reglas precisas. Sobre este modelo se construyen los algoritmos de flujo máximo.

33.2 Definición formal

Una red de flujo es un grafo dirigido G = (V, E) que incluye:

  • Una fuente s, donde se origina el flujo.
  • Un sumidero t, donde termina el flujo.
  • Una capacidad no negativa c(u,v) para cada arista.
  • Un valor f(u,v) que indica el flujo enviado por esa arista.
G = (V, E), fuente s, sumidero t y capacidades c : E → ℝ≥0

33.3 Restricción de capacidad

Ninguna arista puede transportar un flujo negativo ni superar su capacidad.

0 ≤ f(u,v) ≤ c(u,v)

Si una tubería tiene capacidad 8, son válidos los flujos entre 0 y 8. Un flujo 9 hace inválida toda la solución, aunque las demás aristas respeten sus límites.

33.4 Conservación del flujo

En todo vértice intermedio, la cantidad total que entra debe ser igual a la que sale. Los nodos no crean, destruyen ni almacenan flujo.

Para v ≠ s,t:   Σ f(u,v) = Σ f(v,w)

La fuente y el sumidero son las excepciones: la fuente produce el flujo neto y el sumidero lo recibe.

33.5 Valor de un flujo

El valor |f| es la cantidad neta que sale de la fuente. Por conservación, coincide con la cantidad neta que entra al sumidero.

|f| = Σ f(s,v) − Σ f(v,s) = Σ f(v,t) − Σ f(t,v)

Comprobar ambos extremos es una buena técnica para detectar errores al construir o actualizar una solución.

33.6 Laboratorio interactivo de flujo

Ajusta el flujo de cada arista. El laboratorio verifica capacidad, conservación y valor total. Puedes cargar directamente un ejemplo factible de valor 12.

Flujo / capacidad

Diagnóstico

El flujo cero es factible.
Flujo factible.
Sale de s0
Llega a t0
Valor |f|0
ResultadoFactible

Las etiquetas muestran flujo/capacidad. Un nodo rojo viola conservación y una arista roja excede su capacidad.

33.7 Flujo factible y flujo máximo

Un flujo es factible si respeta capacidad y conservación. El flujo cero siempre es factible, pero normalmente no es útil.

El problema de flujo máximo busca, entre todos los flujos factibles, uno cuyo valor |f| sea el mayor posible. Ser factible no implica ser máximo.

33.8 Capacidad residual

Si una arista u → v tiene capacidad 10 y actualmente transporta 6, todavía pueden enviarse 4 unidades adicionales.

capacidad residual hacia adelante: cf(u,v) = c(u,v) − f(u,v)

Una capacidad residual positiva indica que la arista admite más flujo en ese sentido.

33.9 Aristas residuales inversas

Por cada flujo f(u,v) aparece una capacidad residual f(u,v) en sentido contrario. No representa una tubería física: permite deshacer parte de una decisión anterior.

capacidad residual inversa: cf(v,u) = f(u,v)

Esta posibilidad de corregir elecciones es esencial. Un algoritmo no queda atrapado simplemente por haber enviado flujo por una ruta poco conveniente.

33.10 Red residual

La red residual Gf contiene todas las aristas con capacidad residual positiva, tanto hacia adelante como hacia atrás.

Situación en u → vResidual u → vResidual v → u
f = 0, c = 880
f = 3, c = 853
f = 8, c = 808

33.11 Caminos aumentantes

Un camino aumentante es un camino desde s hasta t dentro de la red residual. A lo largo de él puede enviarse flujo adicional.

La cantidad máxima que puede agregarse está limitada por la menor capacidad residual del camino, llamada cuello de botella.

Δ = min { cf(u,v) : (u,v) pertenece al camino }

33.12 Actualización del flujo

Al aumentar Δ unidades por un camino residual, se suma Δ sobre las aristas originales recorridas hacia adelante y se resta sobre las recorridas hacia atrás.

for (const arista of camino) {
  if (arista.esOriginal) {
    flujo[arista.u][arista.v] += delta;
  } else {
    flujo[arista.v][arista.u] -= delta;
  }
}

La actualización mantiene la conservación en los nodos internos del camino.

33.13 Cortes de la red

Un corte (S,T) divide los vértices en dos conjuntos: s pertenece a S y t pertenece a T. La capacidad del corte suma las capacidades de las aristas que van de S hacia T.

c(S,T) = Σ c(u,v), con u ∈ S y v ∈ T

Las aristas que van de T hacia S no se suman porque el corte respeta la dirección del transporte.

33.14 Cota proporcionada por un corte

Todo flujo de s a t debe atravesar cualquier corte que los separe. Por lo tanto, el valor de un flujo nunca puede superar la capacidad de un corte.

Para todo flujo f y todo corte (S,T): |f| ≤ c(S,T)

Encontrar un flujo y un corte con el mismo valor demuestra que ambos son óptimos.

33.15 Teorema flujo máximo–corte mínimo

El teorema central afirma que el valor del flujo máximo es exactamente igual a la capacidad del corte mínimo.

máx |f| = mín c(S,T)

La igualdad conecta una solución constructiva —enviar flujo— con un certificado de imposibilidad —un cuello de botella que ninguna solución puede superar—.

33.16 Representación en código

Una implementación suele almacenar capacidad, flujo y conexiones residuales. Una matriz resulta sencilla; las listas de adyacencia son más eficientes en redes dispersas.

function crearRed(cantidadVertices) {
  return {
    adyacentes: Array.from({ length: cantidadVertices }, () => []),
    capacidad: Array.from(
      { length: cantidadVertices },
      () => Array(cantidadVertices).fill(0)
    ),
    flujo: Array.from(
      { length: cantidadVertices },
      () => Array(cantidadVertices).fill(0)
    )
  };
}

function agregarArista(red, u, v, capacidad) {
  red.adyacentes[u].push(v);
  red.adyacentes[v].push(u); // necesaria para la red residual
  red.capacidad[u][v] += capacidad;
}

33.17 Aplicaciones

  • Distribución de agua, electricidad, mercancías o datos.
  • Asignación de personas a tareas mediante grafos bipartitos.
  • Planificación de producción y cadenas logísticas.
  • Segmentación de imágenes mediante cortes mínimos.
  • Selección de proyectos con dependencias.
  • Rutas disjuntas y análisis de robustez de redes.

33.18 Errores comunes

  • Superar la capacidad de una arista.
  • No conservar el flujo en un nodo intermedio.
  • Sumar todos los flujos de la red para calcular |f|.
  • Olvidar las aristas inversas de la red residual.
  • Confundir capacidad original con capacidad residual.
  • Tratar una red dirigida como si las capacidades fueran simétricas.
  • Suponer que cualquier flujo factible ya es máximo.

33.19 Qué debes recordar de este tema

  • Una red de flujo posee fuente, sumidero y capacidades.
  • Un flujo factible respeta capacidad y conservación.
  • Su valor es la salida neta de la fuente.
  • La red residual indica cómo aumentar o corregir el flujo.
  • Un camino aumentante admite flujo adicional.
  • Todo corte proporciona una cota superior.
  • El flujo máximo tiene el mismo valor que el corte mínimo.

33.20 Conclusión

Las redes de flujo combinan límites locales y una regla global de conservación. La red residual revela no solo cuánto espacio queda disponible, sino también cómo revisar decisiones anteriores.

En el próximo tema utilizaremos estas ideas para estudiar Ford-Fulkerson, un método que aumenta repetidamente el flujo a través de caminos residuales.