El método Ford–Fulkerson o algoritmo Ford–Fulkerson ( FFA ) es un algoritmo voraz que calcula el flujo máximo en una red de flujo . A veces se lo llama «método» en lugar de «algoritmo», ya que el enfoque para encontrar rutas de aumento en un gráfico residual no está completamente especificado [1] o se especifica en varias implementaciones con diferentes tiempos de ejecución. [2] Fue publicado en 1956 por LR Ford Jr. y DR Fulkerson . [3] El nombre «Ford–Fulkerson» también se usa a menudo para el algoritmo Edmonds–Karp , que es una implementación completamente definida del método Ford–Fulkerson.
La idea detrás del algoritmo es la siguiente: siempre que exista una ruta desde la fuente (nodo de inicio) hasta el destino (nodo final), con capacidad disponible en todos los bordes de la ruta, enviamos flujo a lo largo de una de las rutas. Luego, encontramos otra ruta, y así sucesivamente. Una ruta con capacidad disponible se denomina ruta de aumento .
Sea un grafo y, para cada arista de u a v , sea la capacidad y el caudal. Queremos encontrar el caudal máximo desde la fuente s hasta el sumidero t . Después de cada paso del algoritmo se mantiene lo siguiente:
Restricciones de capacidad | El flujo a lo largo de un borde no puede exceder su capacidad. | |
---|---|---|
Simetría oblicua | El flujo neto de u a v debe ser opuesto al flujo neto de v a u (ver ejemplo). | |
Conservación del flujo | El flujo neto hacia un nodo es cero, excepto para la fuente, que "produce" flujo, y el sumidero, que "consume" flujo. | |
Valor(f) | El flujo que sale de s debe ser igual al flujo que llega a t . |
Esto significa que el flujo a través de la red es un flujo legal después de cada ronda del algoritmo. Definimos la red residual como la red con capacidad y sin flujo. Observe que puede suceder que se permita un flujo de v a u en la red residual, aunque no se permita en la red original: si y entonces .
Algoritmo Ford-Fulkerson
La ruta del paso 2 se puede encontrar, por ejemplo, con una búsqueda en amplitud (BFS) o una búsqueda en profundidad en . La primera se conoce como algoritmo de Edmonds-Karp .
Cuando no se pueden encontrar más caminos en el paso 2, s no podrá alcanzar t en la red residual. Si S es el conjunto de nodos alcanzables por s en la red residual, entonces la capacidad total en la red original de aristas desde S hasta el resto de V es, por un lado, igual al flujo total que encontramos desde s hasta t y, por otro lado, sirve como límite superior para todos esos flujos. Esto demuestra que el flujo que encontramos es máximo. Véase también Teorema de flujo máximo y corte mínimo .
Si el grafo tiene múltiples fuentes y sumideros, actuamos de la siguiente manera: Supongamos que y . Añadimos una nueva fuente con una arista desde a cada nodo , con capacidad . Y añadimos un nuevo sumidero con una arista desde cada nodo a , con capacidad . A continuación, aplicamos el algoritmo de Ford-Fulkerson.
Además, si un nodo u tiene una restricción de capacidad , reemplazamos este nodo con dos nodos , y una arista , con capacidad . Luego aplicamos el algoritmo de Ford–Fulkerson.
Al agregar la ruta de aumento de flujo al flujo ya establecido en el gráfico, se alcanzará el flujo máximo cuando no se puedan encontrar más rutas de aumento de flujo en el gráfico. Sin embargo, no hay certeza de que esta situación se alcance alguna vez, por lo que lo mejor que se puede garantizar es que la respuesta será correcta si el algoritmo termina. En el caso de que el algoritmo se ejecute para siempre, el flujo podría ni siquiera converger hacia el flujo máximo. Sin embargo, esta situación solo ocurre con valores de flujo irracionales. [4] Cuando las capacidades son números enteros, el tiempo de ejecución de Ford-Fulkerson está limitado por (ver notación O grande ), donde es el número de aristas en el gráfico y es el flujo máximo en el gráfico. Esto se debe a que cada ruta de aumento se puede encontrar en el tiempo y aumenta el flujo en una cantidad entera de al menos , con el límite superior .
Una variación del algoritmo de Ford-Fulkerson con terminación garantizada y un tiempo de ejecución independiente del valor máximo de flujo es el algoritmo de Edmonds-Karp , que se ejecuta en el tiempo.
El siguiente ejemplo muestra los primeros pasos de Ford–Fulkerson en una red de flujo con 4 nodos, source y receiver . Este ejemplo muestra el comportamiento del algoritmo en el peor de los casos. En cada paso, solo se envía un flujo de a través de la red. Si se utilizara la búsqueda en amplitud, solo se necesitarían dos pasos.
Considere la red de flujo que se muestra a la derecha, con fuente , sumidero , capacidades de los bordes , y , y la capacidad de todos los demás bordes algún entero . La constante se eligió de modo que . Usamos caminos de aumento de acuerdo con la siguiente tabla, donde , y .
Paso | Ampliación de ruta | Flujo enviado | Capacidades residuales | ||
---|---|---|---|---|---|
0 | |||||
1 | |||||
2 | |||||
3 | |||||
4 | |||||
5 |
Nótese que después del paso 1 así como después del paso 5, las capacidades residuales de los bordes , y están en la forma , y , respectivamente, para algunos . Esto significa que podemos usar caminos de aumento , , y infinitas veces y las capacidades residuales de estos bordes siempre estarán en la misma forma. El flujo total en la red después del paso 5 es . Si continuamos usando caminos de aumento como se indicó anteriormente, el flujo total converge a . Sin embargo, observe que hay un flujo de valor , al enviar unidades de flujo a lo largo de , 1 unidad de flujo a lo largo de , y unidades de flujo a lo largo de . Por lo tanto, el algoritmo nunca termina y el flujo ni siquiera converge al flujo máximo. [5]
Backman y Huynh (2018) dan otro ejemplo no terminante basado en el algoritmo euclidiano , donde también muestran que el tiempo de ejecución en el peor caso del algoritmo Ford-Fulkerson en una red en números ordinales es .
importar coleccionesClase Gráfica : """ Esta clase representa un gráfico dirigido utilizando representación de la matriz de adyacencia. """ def __init__ ( self , gráfico ): self . graph = graph # gráfico residual self . row = len ( gráfico ) def bfs ( self , s , t , padre ): """ Devuelve verdadero si hay una ruta desde fuente 's' al sumidero 't' en el gráfico residual. También llena parent[] para almacenar la ruta. """ # Marcar todos los vértices como no visitados visitado = [ Falso ] * self . row # Crear una cola para BFS cola = colecciones . deque () # Marcar el nodo de origen como visitado y ponerlo en cola cola .add ( s ) visitado [ s ] = Verdadero # Bucle BFS estándar mientras cola : u = cola . popleft () # Obtener todos los vértices adyacentes del vértice desencolado u # Si no se ha visitado un adyacente, márquelo # lo visitó y lo puso en cola para ind , val en enumerate ( self.graph [ u ] ) : si ( visitó [ ind ] == Falso ) y ( val > 0 ): cola .append ( ind ) visitó [ ind ] = Verdadero padre [ ind ] = u # Si llegamos al sumidero en BFS comenzando desde la fuente, entonces regresamos # verdadero, de lo contrario falso volver visitado [ t ] # Devuelve el flujo máximo de s a t en el gráfico dado def edmonds_karp ( self , fuente , sumidero ): # Esta matriz se llena con BFS y para almacenar la ruta padre = [ - 1 ] * self . fila max_flow = 0 # No hay flujo inicialmente # Aumentar el flujo mientras haya una ruta desde la fuente hasta el sumidero mientras self . bfs ( fuente , receptor , padre ): # Encuentra la capacidad residual mínima de los bordes a lo largo de la # ruta completada por BFS. O podemos decir que encontramos el caudal máximo # a través de la ruta encontrada. path_flow = float ( "Inf" ) s = hundirse mientras s != fuente : path_flow = min ( path_flow , self . graph [ padre [ s ]][ s ]) s = padre [ s ] # Agregar flujo de ruta al flujo general flujo_máximo += flujo_ruta # Actualizar las capacidades residuales de los bordes y bordes inversos. # a lo largo del camino v = hundirse mientras v != fuente : u = padre [ v ] auto . grafo [ u ][ v ] -= flujo_de_ruta auto . grafo [ v ][ u ] += flujo_de_ruta v = padre [ v ] devolver flujo máximo
{{cite book}}
: CS1 maint: multiple names: authors list (link)Medios relacionados con el algoritmo de Ford-Fulkerson en Wikimedia Commons