Algoritmo Ford – Fulkerson - Ford–Fulkerson algorithm
O método de Ford-Fulkerson ou algoritmo de Ford-Fulkerson ( FFA ) é um algoritmo mais que calcula o fluxo máximo em uma rede de fluxo . Às vezes, é chamado de "método" em vez de "algoritmo", pois a abordagem para encontrar caminhos crescentes em um gráfico residual não é totalmente especificada ou é especificada em várias implementações com diferentes tempos de execução. Foi publicado em 1956 por LR Ford Jr. e DR Fulkerson . O nome "Ford-Fulkerson" também é freqüentemente usado para o algoritmo Edmonds-Karp , que é uma implementação totalmente definida do método Ford-Fulkerson.
A ideia por trás do algoritmo é a seguinte: enquanto houver um caminho da fonte (nó inicial) até o coletor (nó final), com capacidade disponível em todas as arestas do caminho, enviamos o fluxo ao longo de um dos caminhos. Então encontramos outro caminho e assim por diante. Um caminho com capacidade disponível é chamado de caminho crescente .
Algoritmo
Seja um gráfico e, para cada aresta de u a v , seja a capacidade e o fluxo. Queremos encontrar o fluxo máximo da fonte s para o coletor t . Após cada etapa do algoritmo, o seguinte é mantido:
Restrições de capacidade O fluxo ao longo de uma borda não pode exceder sua capacidade. Simetria de enviesamento O fluxo líquido de u para v deve ser o oposto do fluxo líquido de v para u (veja o exemplo). Conservação de fluxo O fluxo líquido para um nó é zero, exceto para a fonte, que "produz" fluxo, e o sumidouro, que "consome" fluxo. Valor (f) O fluxo que sai de s deve ser igual ao fluxo que chega a t .
Isso significa que o fluxo pela rede é um fluxo legal após cada rodada do algoritmo. Definimos a rede residual como a rede com capacidade e sem fluxo. Observe que pode acontecer que um fluxo de v para u seja permitido na rede residual, embora não seja permitido na rede original: se e então .
Algorithm Ford–Fulkerson
- Entradas dada uma rede com capacidade de fluxo c , um nó de origem s e um nó coletor t
-
Saída Calcula um fluxo f de s para t de valor máximo
- para todas as bordas
- Embora haja um caminho p de s para t em , de modo que para todas as arestas :
- Achar
- Para cada borda
- ( Enviar fluxo ao longo do caminho )
- ( O fluxo pode ser "devolvido" mais tarde )
- "←" denota atribuição . Por exemplo, " maior ← item " significa que o valor do maior muda para o valor do item .
- " return " termina o algoritmo e produz o seguinte valor.
O caminho na etapa 2 pode ser encontrado com, por exemplo, uma pesquisa em largura (BFS) ou uma pesquisa em profundidade em . Se você usar o primeiro, o algoritmo é chamado de Edmonds – Karp .
Quando não for possível encontrar mais caminhos na etapa 2, s não será capaz de alcançar t na rede residual. Se S é o conjunto de nós alcançáveis por s na rede residual, então a capacidade total na rede original de arestas de S para o restante de V é, por um lado, igual ao fluxo total que encontramos de s para t , e por outro lado, serve como um limite superior para todos esses fluxos. Isso prova que o fluxo que encontramos é máximo. Veja também o teorema do corte mínimo do fluxo máximo .
Se o gráfico tiver várias fontes e sumidouros, agiremos da seguinte maneira: Suponha que e . Adicione uma nova fonte com uma borda de para cada nó , com capacidade . E adicione um novo coletor com uma borda de cada nó para , com capacidade . Em seguida, aplique o algoritmo Ford – Fulkerson.
Além disso, se um nó u tiver restrição de capacidade , substituímos esse nó por dois nós e uma aresta com capacidade . Em seguida, aplique o algoritmo Ford – Fulkerson.
Complexidade
Ao adicionar o caminho de aumento de fluxo ao fluxo já estabelecido no gráfico, o fluxo máximo será alcançado quando nenhum caminho de aumento de fluxo puder ser encontrado no gráfico. No entanto, não há certeza de que essa situação será atingida, então o melhor que pode ser garantido é que a resposta estará correta se o algoritmo terminar. No caso de o algoritmo funcionar para sempre, o fluxo pode nem mesmo convergir para o fluxo máximo. No entanto, esta situação ocorre apenas com valores de fluxo irracionais. Quando as capacidades são inteiras, o tempo de execução de Ford – Fulkerson é limitado por (veja a notação grande O ), onde é o número de arestas no gráfico e é o fluxo máximo no gráfico. Isso ocorre porque cada caminho de aumento pode ser encontrado no tempo e aumenta o fluxo em uma quantidade inteira de pelo menos , com o limite superior .
Uma variação do algoritmo Ford-Fulkerson com término garantido e tempo de execução independente do valor de fluxo máximo é o algoritmo Edmonds-Karp , que funciona no tempo.
Exemplo integral
O exemplo a seguir mostra as primeiras etapas de Ford – Fulkerson em uma rede de fluxo com 4 nós, fonte e coletor . Este exemplo mostra o pior caso de comportamento do algoritmo. Em cada etapa, apenas um fluxo de é enviado pela rede. Se, em vez disso, fosse usada a pesquisa ampla, apenas duas etapas seriam necessárias.
Caminho | Capacidade | Rede de fluxo resultante |
---|---|---|
Rede de fluxo inicial | ||
Depois de 1998 mais etapas ... | ||
Rede de fluxo final |
Observe como o fluxo é "empurrado" de para ao encontrar o caminho .
Exemplo de não terminação
Considere a rede de fluxo mostrado à direita, com a fonte , pia , capacidades das bordas , e , respectivamente , e e a capacidade de todas as outras bordas algum inteiro . A constante foi escolhida assim, isso . Usamos caminhos aumentantes de acordo com a tabela a seguir, onde , e .
Etapa | Caminho de aumento | Fluxo enviado | Capacidades residuais | ||
---|---|---|---|---|---|
0 | |||||
1 | |||||
2 | |||||
3 | |||||
4 | |||||
5 |
Note-se que após o passo 1, bem como depois do passo 5, as capacidades residuais de arestas , e estão sob a forma , e , respectivamente, para alguns . Isto significa que podemos usar caminhos aumentantes , , e um número infinito de vezes e capacidades residuais desses bordas estarão sempre na mesma forma. O fluxo total na rede após a etapa 5 é . Se continuarmos a usar caminhos de aumento como acima, o fluxo total converge para . No entanto, observe que há um fluxo de valor , enviando unidades de fluxo , 1 unidade de fluxo e unidades de fluxo . Portanto, o algoritmo nunca termina e o fluxo nem mesmo converge para o fluxo máximo.
Outro exemplo não terminante baseado no algoritmo Euclidiano é dado por Backman & Huynh (2018) , onde eles também mostram que o pior caso de tempo de execução do algoritmo de Ford-Fulkerson em uma rede em números ordinais é .
Implementação em Python do algoritmo Edmonds – Karp
import collections
class Graph:
"""This class represents a directed graph using adjacency matrix representation."""
def __init__(self, graph):
self.graph = graph # residual graph
self.row = len(graph)
def bfs(self, s, t, parent):
"""Returns true if there is a path from source 's' to sink 't' in
residual graph. Also fills parent[] to store the path."""
# Mark all the vertices as not visited
visited = [False] * self.row
# Create a queue for BFS
queue = collections.deque()
# Mark the source node as visited and enqueue it
queue.append(s)
visited[s] = True
# Standard BFS loop
while queue:
u = queue.popleft()
# Get all adjacent vertices of the dequeued vertex u
# If an adjacent has not been visited, then mark it
# visited and enqueue it
for ind, val in enumerate(self.graph[u]):
if (visited[ind] == False) and (val > 0):
queue.append(ind)
visited[ind] = True
parent[ind] = u
# If we reached sink in BFS starting from source, then return
# true, else false
return visited[t]
# Returns the maximum flow from s to t in the given graph
def edmonds_karp(self, source, sink):
# This array is filled by BFS and to store path
parent = [-1] * self.row
max_flow = 0 # There is no flow initially
# Augment the flow while there is path from source to sink
while self.bfs(source, sink, parent):
# Find minimum residual capacity of the edges along the
# path filled by BFS. Or we can say find the maximum flow
# through the path found.
path_flow = float("Inf")
s = sink
while s != source:
path_flow = min(path_flow, self.graph[parent[s]][s])
s = parent[s]
# Add path flow to overall flow
max_flow += path_flow
# update residual capacities of the edges and reverse edges
# along the path
v = sink
while v != source:
u = parent[v]
self.graph[u][v] -= path_flow
self.graph[v][u] += path_flow
v = parent[v]
return max_flow
Veja também
Notas
Referências
- Cormen, Thomas H .; Leiserson, Charles E .; Rivest, Ronald L .; Stein, Clifford (2001). "Seção 26.2: O método Ford-Fulkerson". Introdução aos algoritmos (segunda edição). MIT Press e McGraw-Hill. pp. 651–664. ISBN 0-262-03293-7.
- George T. Heineman; Gary Pollice; Stanley Selkow (2008). "Capítulo 8: Algoritmos de fluxo de rede". Algoritmos resumidos . Oreilly Media . pp. 226–250. ISBN 978-0-596-51624-6.
- Jon Kleinberg ; Éva Tardos (2006). "Capítulo 7: Extensões ao problema de fluxo máximo" . Projeto de algoritmos . Pearson Education. pp. 378–384 . ISBN 0-321-29535-8.
- Samuel Gutekunst (2009). ENGRI 1101 . Cornell University.
- Backman, Spencer; Huynh, Tony (2018). "Transfinite Ford – Fulkerson em uma rede finita". Computabilidade . 7 (4): 341–347. arXiv : 1504.04363 . doi : 10.3233 / COM-180082 . S2CID 15497138 .
links externos
- Um tutorial explicando o método Ford-Fulkerson para resolver o problema de fluxo máximo
- Outra animação Java
- Aplicativo Java Web Start
Mídia relacionada ao algoritmo de Ford-Fulkerson no Wikimedia Commons