Recent from talks
Nothing was collected or created yet.
Dinic's algorithm
View on WikipediaDinic's algorithm or Dinitz's algorithm is a strongly polynomial algorithm for computing the maximum flow in a flow network, conceived in 1970 by Israeli (formerly Soviet) computer scientist Yefim Dinitz.[1] The algorithm runs in time and is similar to the Edmonds–Karp algorithm, which runs in time, in that it uses shortest augmenting paths. The introduction of the concepts of the level graph and blocking flow enable Dinic's algorithm to achieve its performance.
History
[edit]Dinitz invented the algorithm in January 1969, as a master's student in Georgy Adelson-Velsky's group. A few decades later, he would recall:[2]
In Adel'son-Vel'sky's Algorithms class, the lecturer had a habit of giving the problem to be discussed at the next meeting as an exercise to students. The DA was invented in response to such an exercise. At that time, the author was not aware of the basic facts regarding [the Ford–Fulkerson algorithm]….
⋮ Ignorance sometimes has its merits. Very probably, DA would not have been invented then, if the idea of possible saturated edge desaturation had been known to the author.
In 1970, Dinitz published a description of the algorithm in Doklady Akademii Nauk SSSR. In 1974, Shimon Even and (his then Ph.D. student) Alon Itai at the Technion in Haifa were very curious and intrigued by Dinitz's algorithm as well as Alexander V. Karzanov's related idea of blocking flow. However it was hard for them to decipher these two papers, each being limited to four pages to meet the restrictions of journal Doklady Akademii Nauk SSSR. Even did not give up, and after three days of effort managed to understand both papers except for the layered network maintenance issue. Over the next couple of years, Even gave lectures on "Dinic's algorithm", mispronouncing the name of the author while popularizing it. Even and Itai also contributed to this algorithm by combining BFS and DFS, which is how the algorithm is now commonly presented.[2]
For about 10 years of time after the Ford–Fulkerson algorithm was invented, it was unknown if it could be made to terminate in polynomial time in the general case of irrational edge capacities. This caused a lack of any known polynomial-time algorithm to solve the max flow problem in generic cases. Dinitz's algorithm and the Edmonds–Karp algorithm (published in 1972) both independently showed that in the Ford–Fulkerson algorithm, if each augmenting path is the shortest one, then the length of the augmenting paths is non-decreasing and the algorithm always terminates.
Definition
[edit]Let be a network with and the capacity and the flow of the edge , respectively.
- The residual capacity is a mapping defined as,
- if ,
- if ,
- otherwise.
- if ,
- The residual graph is an unweighted graph , where
- .
- An augmenting path is an – path in the residual graph .
- Define to be the length of the shortest path from to in . Then the level graph of is the graph , where
- .
Algorithm
[edit]Dinic's Algorithm
- Input: A network .
- Output: An – flow of maximum value.
- Set for each .
- Construct from of . If , stop and output .
- Find a blocking flow in .
- Augment flow by and go back to step 2.
Analysis
[edit]It can be shown that the number of layers in each blocking flow increases by at least 1 each time and thus there are at most blocking flows in the algorithm. For each of them:
- the level graph can be constructed by breadth-first search in time
- a blocking flow in the level graph can be found in time[Note 2]
with total running time for each layer. As a consequence, the running time of Dinic's algorithm is .[2]
Using a data structure called dynamic trees, the running time of finding a blocking flow in each phase can be reduced to and therefore the running time of Dinic's algorithm can be improved to .
Special cases
[edit]In networks with unit capacities, a much stronger time bound holds. Each blocking flow can be found in time, and it can be shown that the number of phases does not exceed and .[Note 3] Thus the algorithm runs in time.[4]
In networks that arise from the bipartite matching problem, the number of phases is bounded by , therefore leading to the time bound. The resulting algorithm is also known as Hopcroft–Karp algorithm. More generally, this bound holds for any unit network — a network in which each vertex, except for source and sink, either has a single entering edge of capacity one, or a single outgoing edge of capacity one, and all other capacities are arbitrary integers.[3]
Example
[edit]The following is a simulation of Dinic's algorithm. In the level graph , the vertices with labels in red are the values . The paths in blue form a blocking flow.
See also
[edit]Notes
[edit]- ^ This means that the subgraph resulting from removing all saturated edges (edges with ) does not contain any path from to . In other terms, the blocking flow is such that every possible path from to contains a saturated edge.
- ^ Finding the blocking flow can be implemented in per path via a sequence of Advance and Retreat operations. See http://courses.csail.mit.edu/6.854/06/scribe/scribe11.pdf for more details.
- ^ The bound assumes that no two edges connect the same pair of vertices in the same direction, while the bound makes no such assumption.
- ^ E. A. Dinic (1970). "Algorithm for solution of a problem of maximum flow in a network with power estimation" (PDF). Doklady Akademii Nauk SSSR. 11: 1277–1280.
- ^ a b c Dinitz, Yefim (2006). "Dinitz' Algorithm: The Original Version and Even's Version". In Oded Goldreich; Arnold L. Rosenberg; Alan L. Selman (eds.). Theoretical Computer Science: Essays in Memory of Shimon Even. Lecture Notes in Computer Science. Vol. 3895. Springer. pp. 218–240. doi:10.1007/11685654_10. ISBN 978-3-540-32880-3.
- ^ a b Tarjan 1983, p. 102.
- ^ Even, Shimon; Tarjan, R. Endre (1975). "Network Flow and Testing Graph Connectivity". SIAM Journal on Computing. 4 (4): 507–518. doi:10.1137/0204043. ISSN 0097-5397.
References
[edit]- Dinitz, Yefim (2006). "Dinitz' Algorithm: The Original Version and Even's Version". In Oded Goldreich; Arnold L. Rosenberg; Alan L. Selman (eds.). Theoretical Computer Science: Essays in Memory of Shimon Even. Lecture Notes in Computer Science. Vol. 3895. Springer. pp. 218–240. doi:10.1007/11685654_10. ISBN 978-3-540-32880-3.
- Kadar, Ilan; Albagli, Sivan (18 April 2019). Dinitz's algorithm for finding a maximum flow in a network. Ben-Gurion University. Archived from the original on 22 December 2023.
- Korte, B. H.; Vygen, Jens (2008). "8.4 Blocking Flows and Fujishige's Algorithm". Combinatorial Optimization: Theory and Algorithms (Algorithms and Combinatorics, 21). Springer Berlin Heidelberg. pp. 174–176. ISBN 978-3-540-71844-4.
- Tarjan, R. E. (1983). Data structures and network algorithms.
Dinic's algorithm
View on GrokipediaBackground
Maximum Flow Problem
The maximum flow problem seeks to determine the maximum rate at which some commodity can be sent from a source vertex to a sink vertex in a flow network, subject to capacity constraints on the edges.[4] This problem models scenarios such as transporting goods through a transportation network or routing data in communication systems, where the goal is to maximize the total throughput without violating edge limits.[5] Central to the problem are two distinguished vertices: the source , from which flow originates, and the sink , at which flow arrives.[6] The value of a flow, denoted , is defined as the total outflow from (equivalently, the total inflow to ), representing the net amount of commodity transferred.[4] A valid flow must satisfy two key constraints: for every edge from vertex to , the flow cannot exceed the edge's capacity ; and at every intermediate vertex (neither nor ), the total incoming flow equals the total outgoing flow, ensuring conservation of the commodity.[5] Formally, given a directed graph with vertex set and edge set , the capacity function is , where if no edge exists from to , and the flow function is , satisfying for all .[6] The maximum flow problem is to find a flow that maximizes while adhering to these capacity and conservation constraints.[4] This formulation originates from the work of Ford and Fulkerson, who introduced the problem in their seminal 1956 paper on maximal flows in networks.Flow Networks
A flow network is formally defined as a directed graph , where is the finite set of vertices and is the set of directed edges, equipped with a capacity function that assigns a nonnegative real number to each edge , representing the maximum amount of flow that can traverse that edge.[7] This structure models scenarios where commodities or resources are transported from origins to destinations through interconnected nodes subject to edge-specific limits.[7] The network designates two distinguished vertices: the source , characterized by having no incoming flow (i.e., the net flow into is zero), and the sink , characterized by having no outgoing flow (i.e., the net flow out of is zero).[7] These vertices serve as the starting point for flow injection and the endpoint for flow extraction, respectively, with all other vertices adhering to flow conservation.[7] A flow in the network assigns a real value to each edge, interpreted as the rate of flow along that edge. An admissible flow is one that satisfies two key properties: (i) the capacity constraint, requiring for every edge , ensuring no edge exceeds its limit or carries negative flow; and (ii) the conservation of flow, requiring that for every vertex , the total incoming flow equals the total outgoing flow, formally .[7] The value of such a flow is the net amount leaving the source (or equivalently, entering the sink), given by .[7] Central to analyzing and augmenting flows is the residual graph , derived from with respect to a given admissible flow , where and the residual capacity is defined as for all .[7] This formulation accounts for potential flow reversals: if flow has been sent from to , the term (which equals the backward flow component) enables "undoing" part of that flow by adding a residual edge from to , effectively adjusting the net flow without violating capacities.[7] The residual graph thus captures the remaining potential for increasing the overall flow from to .[7] This framework underpins the maximum flow problem, which aims to find an admissible flow of maximum value in the network.[7]History
Origins
Dinic's algorithm was invented by the Soviet mathematician Yefim A. Dinic in 1970.[8] The algorithm was first published in Russian as "Algoritm resheniya zadachi o maksimal'ном potoke v seti s ocenkoj stepeni" in Doklady Akademii Nauk SSSR, volume 191, number 1, pages 49–52, and later translated into English as "Algorithm for Solution of a Problem of Maximum Flow in a Network with Power Estimates" in Soviet Mathematics Doklady, volume 11, pages 1277–1280.[8] The development occurred amid growing interest in efficient algorithms for the maximum flow problem in flow networks, a fundamental challenge in combinatorial optimization. Dinic's work was motivated by limitations in the Ford–Fulkerson method, introduced in 1956, which relies on augmenting paths but lacks a guaranteed polynomial-time bound in the worst case, potentially leading to exponential running times on certain inputs. To address this, Dinic incorporated breadth-first search to build layered structures in the residual graph, allowing for the efficient identification and saturation of multiple paths simultaneously through blocking flow computations.[9] This innovation built upon emerging ideas for refining path selection in flow algorithms, particularly the use of BFS to prioritize shortest augmenting paths, a concept that would be independently formalized shortly thereafter in the Edmonds–Karp algorithm of 1972. By providing a strongly polynomial time complexity of O(V²E)—where V is the number of vertices and E the number of edges—Dinic's algorithm marked a significant advancement, establishing a reliable bound independent of edge capacities and influencing subsequent research in network flows.[10]Developments and Influences
Following the publication of the original Russian paper in 1970, an English translation by R. F. Rinehart appeared in the same year in Soviet Mathematics Doklady, facilitating its wider dissemination and adoption in Western academic and research communities. This translation, along with analyses in subsequent works, helped bridge the gap for non-Russian speakers, leading to rapid integration into the study of network flows. Dinic's algorithm significantly influenced subsequent maximum flow research, particularly through its layered (level graph) approach, which inspired similar hierarchical structures in later algorithms. For instance, the push-relabel algorithm developed by Goldberg and Tarjan in 1988 explicitly builds on layering ideas from Dinic and Karzanov, using dynamic distance labels to guide flow augmentation in a manner analogous to level graphs. Additionally, Even and Tarjan's 1975 paper analyzed and extended Dinic's method for unit-capacity networks, demonstrating its O(\sqrt{n} m) time bound for bipartite matching and establishing it as a foundational technique for connectivity testing in graphs.[9] Key refinements in the 1980s enhanced the efficiency of blocking flow computations in Dinic's framework. Cherkassky's 1983 algorithm improved the time complexity to O(V^2 E^{1/2}) for certain networks by using advanced data structures for path finding in level graphs.[11] Independently, Galil and Tarjan's 1984 variant provided a simplified approach to computing blocking flows, maintaining the original O(VE) time per phase.[12] Further advancements incorporated dynamic trees by Sleator and Tarjan in 1983, reducing the overall complexity to O(VE \log V).[13] By the 1980s, Dinic's algorithm had become a standard topic in combinatorial optimization literature, appearing in key texts on network flows and graph algorithms due to its strong polynomial-time guarantees and practical performance. It also found implementation in established software libraries, such as LEDA, which incorporates a Galil-Naamad variant of Dinic's method for robust maximum flow computations.[14]Algorithm Description
Level Graph Construction
In Dinic's algorithm, the level graph construction serves as a preprocessing step in each phase to organize the residual graph into layers based on shortest path distances from the source, facilitating efficient discovery of multiple augmenting paths. This process begins with a breadth-first search (BFS) initiated from the source vertex in the current residual graph , where edges with positive residual capacity are considered.[15] The BFS assigns a level to each vertex , defined as the shortest path distance from to in , with . Vertices unreachable from receive infinite levels, and the search terminates if the sink is unreachable, indicating that the maximum flow has been achieved.[16] Each such BFS traversal requires time, where is the number of vertices and is the number of edges in the graph.[15] The level graph, denoted , is then derived as a subgraph of consisting solely of edges where and the residual capacity is positive. This restriction ensures that all paths in from to are of minimal length in the original residual graph and that the graph is acyclic, as levels strictly increase along any path.[16] By confining edges to those spanning exactly one level, the level graph directs flow strictly forward through successive layers, preventing cycles and backtracking during subsequent path-finding operations.[15] This layering mechanism is repeated in multiple phases until no augmenting path exists to , with each phase updating the residual graph after computing a blocking flow in the current level graph. The level graph's structure partitions the network into ordered layers, enabling the algorithm to explore and saturate multiple disjoint shortest paths in parallel, which enhances efficiency over path-by-path augmentation methods.[16]Blocking Flow Computation
In Dinic's algorithm, the blocking flow computation occurs within the level graph, a directed acyclic subgraph of the residual graph consisting of edges that connect vertices at consecutive levels. A blocking flow in this graph is a feasible flow such that no augmenting path exists from the source to the sink relative to it, meaning every possible path from to in the level graph contains at least one saturated edge from this flow.[17] The computation proceeds via repeated depth-first searches (DFS) initiated from the source , traversing only level-increasing edges to identify and saturate paths to . In each DFS, flow is pushed along the discovered path up to the minimum residual capacity of its edges, after which the path is updated in the residual graph by reducing capacities forward and adding backward edges.[17] To efficiently explore multiple paths, the DFS maintains a tree structure through parent pointers, which link each visited vertex to its predecessor in the search tree. When a path reaches , augmentation occurs, and the search backtracks; if a subtree rooted at a vertex becomes blocked (no unsaturated outgoing edges lead to a viable path to ), the algorithm advances to the next unexplored child edge from that vertex, continuing the search until all branches are exhausted.[17] This iterative DFS process terminates when no further path from can reach in the current level graph, ensuring the blocking flow saturates all possible shortest augmenting paths. Multiple DFS calls per phase collectively find a maximal set of edge-disjoint paths, fully blocking the level graph without requiring exhaustive enumeration.[17]Procedure and Implementation
Overall Steps
Dinic's algorithm initializes the flow to zero on all edges of the given flow network, starting with an empty residual graph based on the initial capacities.[18] The algorithm proceeds in a series of phases within a main loop. In each phase, it first constructs a level graph of the current residual graph using breadth-first search (BFS) from the source vertex , where each vertex is assigned a level corresponding to the length of the shortest path from to that vertex; this level graph includes only edges that connect vertices whose levels differ by exactly one.[19] If the BFS does not reach the sink vertex , the algorithm terminates, as no augmenting path exists, and the current total flow is the maximum flow value.[20] Otherwise, it computes a blocking flow in the level graph—a maximal flow that saturates every path from to in this graph—using depth-first search traversals as a subroutine.[18] This blocking flow is then added to the overall flow, and the residual capacities are updated by adjusting the forward and backward edges accordingly.[20] Each phase advances the flow by saturating all shortest augmenting paths in the current residual graph, ensuring progress toward the maximum flow. The process repeats with a new level graph until termination. The number of such phases is at most , where is the number of vertices, because the shortest path lengths from to unsaturated vertices strictly increase with each phase.[21]Data Structures and Pseudocode
Dinic's algorithm requires specific data structures to efficiently represent the flow network and manage the residual capacities during execution. The graph is typically stored using adjacency lists, where each vertex maintains a list of outgoing edges in both the original network and the residual graph. Each edge structure includes fields for the target vertex, capacity, current flow, and a reference to the reverse edge to enable quick updates when augmenting paths are found. A level array, denoted as , stores the shortest path distances from the source to each vertex in the current level graph. Additionally, an array of iterators or current pointers (often called or similar) tracks the advancement position in each vertex's adjacency list during DFS traversals, ensuring that previously explored edges are not revisited in the same blocking flow phase, which optimizes the search for multiple augmenting paths.[22] When augmenting flow along a path, the residual graph is updated by reducing the residual capacity on forward edges and increasing it on corresponding reverse edges. For each forward edge from to with augmented flow , the reverse edge from to receives an additional capacity of , allowing for potential flow cancellation in future iterations. This bidirectional edge pairing is maintained in the adjacency lists from the outset, with reverse edges initialized to zero capacity. The overall space complexity for these structures—adjacency lists for edges (including reverses, so ), the level array for , and the pointer array for —is .[22][23] The pseudocode for Dinic's algorithm outlines three key procedures: BFS to construct the level graph, DFS to compute blocking flows by pushing flow along level-respecting paths, and the main loop to repeat phases until saturation. These implement the core logic of building layered networks and finding maximal flows within them without backtracking beyond levels. The BFS procedure assigns levels via shortest-path distances in the residual graph:BFS(s):
for each vertex v:
l[v] = -1
l[s] = 0
queue Q = empty
enqueue s to Q
while Q not empty:
u = dequeue Q
for each adjacent edge to v from u with positive residual capacity:
if l[v] == -1:
l[v] = l[u] + 1
enqueue v to Q
return true if l[t] != -1 else false
BFS(s):
for each vertex v:
l[v] = -1
l[s] = 0
queue Q = empty
enqueue s to Q
while Q not empty:
u = dequeue Q
for each adjacent edge to v from u with positive residual capacity:
if l[v] == -1:
l[v] = l[u] + 1
enqueue v to Q
return true if l[t] != -1 else false
DFS(u, min_flow, l, ptr):
if u == t:
return min_flow
for i = ptr[u] to end of adj[u]:
ptr[u] = i // advance pointer
v = target of edge i from u
if l[v] == l[u] + 1 and residual capacity (u, v) > 0:
pushed = DFS(v, min(min_flow, residual(u, v)), l, ptr)
if pushed > 0:
augment flow by pushed along the path
residual(u, v) -= pushed
residual(v, u) += pushed // update reverse
return pushed
l[u] = -1 // mark as unlevelled for optimization
return 0
DFS(u, min_flow, l, ptr):
if u == t:
return min_flow
for i = ptr[u] to end of adj[u]:
ptr[u] = i // advance pointer
v = target of edge i from u
if l[v] == l[u] + 1 and residual capacity (u, v) > 0:
pushed = DFS(v, min(min_flow, residual(u, v)), l, ptr)
if pushed > 0:
augment flow by pushed along the path
residual(u, v) -= pushed
residual(v, u) += pushed // update reverse
return pushed
l[u] = -1 // mark as unlevelled for optimization
return 0
Dinic(s, t):
max_flow = 0
while BFS(s) is true:
ptr = [0 for each vertex] // reset pointers
while true:
pushed = DFS(s, ∞, l, ptr)
if pushed == 0:
break
max_flow += pushed
return max_flow
Dinic(s, t):
max_flow = 0
while BFS(s) is true:
ptr = [0 for each vertex] // reset pointers
while true:
pushed = DFS(s, ∞, l, ptr)
if pushed == 0:
break
max_flow += pushed
return max_flow
Analysis
Time Complexity
Dinic's algorithm has a time complexity of for general flow networks, where is the number of vertices and is the number of edges.[24] This bound arises from the algorithm's phase-based structure, where each phase builds a level graph via breadth-first search (BFS) and computes a blocking flow using depth-first search (DFS) traversals.[1] The algorithm executes at most phases. In each phase, the shortest path distance from the source to the sink in the residual graph strictly increases by at least 1, and this distance cannot exceed .[24] Moreover, each phase saturates the outgoing edges of at least one vertex in the level graph, ensuring progress toward eliminating augmenting paths of the current shortest length.[1] Per phase, the BFS to construct the level graph takes time, as it traverses all vertices and edges in the residual graph.[24] The subsequent blocking flow computation requires time. Although each individual DFS traversal explores edges, the total work across all DFS calls in a phase—accounting for advances along edges, retreats during backtracking, and augmentations—is bounded by , since the level graph is acyclic and each edge is examined at most times in aggregate due to the limited depth and pointer optimizations in the DFS implementation.[24] Combining these, the total runtime is .[2] This improves upon the Edmonds-Karp algorithm's complexity, which relies on sequential augmentations each taking time to find a single path via BFS; Dinic's use of blocking flows enables multiple simultaneous augmentations per phase, drastically reducing the number of iterations needed.[24] In special cases like unit-capacity networks, the algorithm achieves tighter bounds such as .[1]Special Cases and Optimizations
In unit-capacity networks, where all edge capacities are one, Dinic's algorithm benefits from a reduced number of phases in level graph construction, leading to a time complexity of .[25] This improvement arises because the shortest path distances in the residual graph grow more rapidly, bounding the phases by , while each blocking flow phase takes time.[25] For bipartite graphs, Dinic's algorithm applied to unit-capacity networks for maximum matching reduces to the Hopcroft-Karp algorithm, achieving time.[23] This equivalence stems from the layered structure aligning with multiple shortest augmenting paths in bipartite matching, where the number of phases is .[23] Further optimizations employ dynamic trees to accelerate blocking flow computation within each phase. By representing the level graph's trees and enabling fast path queries and updates, the time per phase drops to , yielding an overall complexity of .[26] This enhancement, introduced via the link-cut tree data structure, supports efficient linking and cutting of paths during DFS traversals.[26] Parallel variants of Dinic's algorithm target multi-core architectures by distributing the DFS-based blocking flow searches across threads, improving scalability for dense graphs.[27] These implementations parallelize the traversal of advance vertices while maintaining level graph integrity, achieving speedups on multi-core processors for large networks.[28] In networks with large edge capacities, the worst-case time complexity remains , as the phase count is bounded by independently of capacities.[25] However, practical performance improves due to fewer effective phases, as high-capacity edges allow larger augmentations per blocking flow, reducing iterations in real-world instances.[26]Example
Network Illustration
To illustrate the setup for applying Dinic's algorithm, consider a simple directed flow network with 5 vertices labeled 1 through 5, where vertex 1 serves as the source and vertex 5 as the sink . The network consists of directed edges connecting the source to intermediate vertices and ultimately to the sink, each assigned a positive integer capacity representing the maximum flow allowable along that edge. The structure forms multiple paths from to , including routes through vertices 2 and 3 as intermediaries, and vertex 4 as a convergence point before the sink. The edges and their capacities are as follows:| From | To | Capacity |
|---|---|---|
| 1 | 2 | 4 |
| 1 | 3 | 3 |
| 2 | 4 | 2 |
| 2 | 5 | 3 |
| 3 | 4 | 3 |
| 4 | 5 | 2 |

