def dinic(graph, capacity, source, target): """Maximum flow by Dinic :param graph: adjacency list or adjacency dictionary of directed graph :param capacity: matrix or adjacency dictionary :param int source: vertex :param int target: vertex :returns: skew symmetric flow matrix, flow value :complexity: :math:`O(|V|^2 |E|)` """ assert source != target add_reverse_arcs(graph, capacity) Q = deque() total = 0 n = len(graph) flow = [[0] * n for u in range(n)] # flot init. vide while True: # répéter tant qu'on peut augmenter Q.appendleft(source) lev = [None] * n # construire niveaux, None = inaccessible lev[source] = 0 # par parcours BFS while Q: u = Q.pop() for v in graph[u]: if lev[v] is None and capacity[u][v] > flow[u][v]: lev[v] = lev[u] + 1 Q.appendleft(v) if lev[target] is None: # arrêt si puits inaccessible return flow, total # UB = borne supérieure UB = sum(capacity[source][v] for v in graph[source]) - total total += _dinic_step(graph, capacity, lev, flow, source, target, UB)
def dinic(graph, capacity, source, target): """Maximum flow by Dinic :param graph: directed graph in listlist or listdict format :param capacity: in matrix format or same listdict graph :param int source: vertex :param int target: vertex :returns: skew symmetric flow matrix, flow value :complexity: :math:`O(|V|^2 |E|)` """ assert source != target add_reverse_arcs(graph, capacity) Q = deque() total = 0 n = len(graph) flow = [[0] * n for u in range(n)] # flow initially empty while True: # repeat while we can increase Q.appendleft(source) level = [None] * n # build levels, None = inaccessible level[source] = 0 # by BFS while Q: u = Q.pop() for v in graph[u]: if level[v] is None and capacity[u][v] > flow[u][v]: level[v] = level[u] + 1 Q.appendleft(v) if level[target] is None: # stop if sink is not reachable return flow, total up_bound = sum(capacity[source][v] for v in graph[source]) - total total += _dinic_step(graph, capacity, level, flow, source, target, up_bound)
def ford_fulkerson(graph, capacity, s, t): """Maximum flow by Ford-Fulkerson :param graph: directed graph in listlist or listdict format :param capacity: in matrix format or same listdict graph :param int s: source vertex :param int t: target vertex :returns: flow matrix, flow value :complexity: `O(|V|*|E|*max_capacity)` """ add_reverse_arcs(graph, capacity) n = len(graph) flow = [[0] * n for _ in range(n)] INF = float('inf') while _augment(graph, capacity, flow, INF, s, t, [False] * n) > 0: pass # corps de boucle vide return (flow, sum(flow[s])) # flot, valeur du flot
def edmonds_karp(graph, capacity, source, target): """Maximum flow by Edmonds-Karp :param graph: directed graph in listlist or listdict format :param capacity: in matrix format or same listdict graph :param int source: vertex :param int target: vertex :returns: flow matrix, flow value :complexity: :math:`O(|V|*|E|^2)` """ add_reverse_arcs(graph, capacity) V = range(len(graph)) flow = [[0 for v in V] for u in V] while True: augm_path, delta = _augment(graph, capacity, flow, source, target) if delta == 0: break v = target # go back to source while v != source: u = augm_path[v] # augment flow flow[u][v] += delta flow[v][u] -= delta v = u return (flow, sum(flow[source])) # flow network, amount of flow
def edmonds_karp(graph, capacity, source, target): """Maxmum flow by Edmonds-Karp :param graph: directed graph in listlist or listdict format :param capacity: in matrix format or same listdict graph :param int source: vertex :param int target: vertex :returns: flow matrix, flow value :complexity: :math:`O(|V|*|E|^2)` """ add_reverse_arcs(graph, capacity) V = range(len(graph)) flow = [[0 for v in V] for u in V] while True: augm_path, delta = _augment(graph, capacity, flow, source, target) if delta == 0: break v = target # remonter vers la source while v != source: u = augm_path[v] # et augmenter le flot flow[u][v] += delta flow[v][u] -= delta v = u return (flow, sum(flow[source])) # flot, valeur du flot
def edmonds_karp(graph, capacity, source, target): """Maxmum flow by Edmonds-Karp :param graph: adjacency list or adjacency dictionary of a directed graph :param capacity: matrix or adjacency dictionary :param int source: vertex :param int target: vertex :returns: flow matrix, flow value :complexity: :math:`O(|V|*|E|^2)` """ add_reverse_arcs(graph, capacity) V = range(len(graph)) flow = [[0 for v in V] for u in V] while True: augm_path, delta = _augment(graph, capacity, flow, source, target) if delta == 0: break v = target # remonter vers la source while v != source: u = augm_path[v] # et augmenter le flot flow[u][v] += delta flow[v][u] -= delta v = u return (flow, sum(flow[source])) # flot, valeur du flot