In the previous article we mentioned the network flow algorithm Push-relabel, that is the 90 's proposed algorithm, is relatively new, and now to say the dinic algorithm is by the Israelis Dinitz in the Cold War period, namely the 60-70 years proposed algorithm variant, its algorithm complexity is O (mn^2 )。
The main idea of the Dinic algorithm is also based on the FF algorithm, and the improvement is also to reduce the number of iterations to find the augmented path. Here Dinitz a very clever data structure, layer network, layered networks, the structure is inspired by the BFS tree, it is different from the BFS tree, the BFS tree is only saved to one side of each layer, which leads to the use of BFS The tree can only discover one augmented path at a time, while a layered network holds all the edges of each layer, but the edges within the layer are not saved.
Introduced the data structure, began to talk about the steps of the algorithm, 1) from the remaining graph of the network using the BFS width-first traversal technology to generate layered networks. 2) constantly call the DFS generation augmentation path in the layered network until s unreachable T, this step embodies the greedy characteristics of the dinic algorithm. 3) max_flow+= The flow of all augmented paths generated this time, regenerate the remaining graphs, and go to 1).
The source code is as follows:
The use of recursive implementation of BFS and DFS, the efficiency is not high.
__author__ = ' Xanxus ' nodenum, edgenum = 0, 0arcs = []class Arc (object): Def __init__ (self): SELF.SRC = 1 SELF.DST = 1 Self.cap = -1class Layer (object): Def __init__ (self): Self.nodeset = set () Self.arc List = []s, t =-1, -1with open (' Demo.dimacs ') as F:for line in F.readlines (): line = Line.strip () if Li Ne.startswith (' P '): tokens = Line.split (") nodenum = Int (tokens[2]) Edgenum = tokens[3] If Line.startswith (' n '): tokens = Line.split (") if tokens[2] = = ' s ': s = in T (Tokens[1]) if tokens[2] = = ' t ': t = Int (tokens[1]) if Line.startswith (' a '): Tokens = Line.split (") Arc = arc () arc.src = Int (tokens[1]) arc.dst = Int (tokens[2]) arc.cap = Int (tokens[3]) arcs.append (ARC) nodes = [-1] * nodenumfor I in range (s, T + 1): Nodes[i- S] = Iadjacent_matrix =[[0 for I in range (Nodenum)] for J in Range (Nodenum)]for arc in arcs:adjacent_matrix[arc.src-s][arc.dst-s] = ARC.C Apdef getlayernetwork (current, LN, augment_set): If T-S in Ln[current].nodeset:return for I in Ln[current] . NodeSet:augment_set.add (i) Has_augment = False for J in Range (Len (Adjacent_matrix)): If ADJACENT_MATRIX[I][J]! = 0:if len (LN) = = current + 1:ln.append (Layer ()) If J not in Augment_set and j is ln[current].nodeset:has_augment = True ln[cur Rent + 1].nodeset.add (j) Arc = Arc () arc.src, arc.dst, Arc.cap = i, J, Adjacent_matr IX[I][J] Ln[current].arclist.append (ARC) if not has_augment and (i! = t or I! = 0): Augment_set.remove (i) filter (lambda x:x = = i, ln[current].nodeset) newarclist = [] fo R arc in Ln[current-1]. arclist:if ARC.DST! = I:newarclist.append (ARC) ln[current-1].arclist = n ewarclist If len (ln) = = current + 1:return getlayernetwork (current + 1, LN, augment_set) def get_path (Layerne Twork, SRC, Current, path): For arc in layernetwork[current].arclist:if arc.src = = src and Arc.cap! = 0: Path.append (ARC) Get_path (Layernetwork, ARC.DST, current + 1, path) returndef Find_blocking_flo W (layernetwork): Sum_flow = 0 while (True): Path = [] Get_path (layernetwork, 0, 0, path) if Pat H[-1].dst! = T: Break else:bottleneck = min ([arc.cap to arc in Path]) for AR C in Path:arc.cap-= bottleneck Sum_flow + bottleneck return sum_flowmax_flow = 0while (Tru E): Layernetwork = [] Firstlayer = Layer () firstLayer.nodeSet.add (0) layernetwork.append (firstlayer) augmen T_set = set () augment_set.add (0) getlayernetwork (0, Layernetwork, augment_set) if T-s not in Layernetwork[-1].nodeset:break Current_flow = Find_blocking_flow (layernetwork) if Current_flow = = 0:break Else:max_flow + = Current_ Flow # Add the backward arcs for layer in layernetwork:for arc in Layer.arclist: ADJACENT_MATRIX[ARC.DST][ARC.SRC] + = adjacent_matrix[arc.src][arc.dst]-Arc.cap adjacent_matrix[arc.src][a RC.DST] = arc.capfor arc in Arcs:print ' F%d%d%d '% (ARC.SRC, ARC.DST, Arc.cap-adjacent_matrix[arc.src-s][arc.ds T-S])
Python implementation of network stream algorithm Dinic