Python implementation of network stream algorithm Dinic

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.