Content deleted Content added
Line 82:
It can be shown that the algorithm executes {{nowrap|''O''(''V''<sup>2</sup>)}} relabels, {{nowrap|''O''(''VE'')}} saturating pushes and {{nowrap|''O''(''V''<sup>2</sup>''E'')}} nonsaturating pushes.<ref name="clrs26"/> Data structures can be designed to pick an applicable operation in {{nowrap|''O''(1)}} time. Therefore, the time complexity of the algorithm is {{nowrap|''O''(''V''<sup>2</sup>''E'')}}.
==Practical implementations==
==Relabel-to-Front Algorithm==▼
While the generic push-relabel algorithm has {{nowrap|''O''(''V''<sup>2</sup>''E'')}} time complexity, efficient implementations can achieve {{nowrap|''O''(''V''<sup>3</sup>)}} or lower time complexity by enforcing appropriate rules in selecting applicable push and relabel operations.
==="Current-edge" data structure and discharge operation===
The "current-edge" data structure is a mechanism for visiting the in- and out-neighbors of a vertex in the flow network in a static circular order. If a singly linked list of neighbors is created for a vertex, the data structure can be as simple as a pointer into the list that steps through the list and rewinds to the head when it runs off the end.
Based on the "current-edge" data structure, the discharge operation can be defined. A discharge operation applies on an active node and repeatedly pushes flow from the node until it becomes inactive, relabeling it as necessary to create admissible edges.
if current-edge[u] has run off the end of neighbors[u]
rewind current-edge[u]
if (u, v) is admissible
let current-edge[u] point to the next neighbor of u
===Active vertex selection rules===
Definition of the discharge operation reduces the push-relabel algorithm to repeatedly selecting an active node to discharge. Depending on the selection rule, the algorithm exhibits different time complexities. For the sake of brevity, we ignore ''s'' and ''t'' when referring to the vertices in the following discussion.
▲ while excess(u) > 0:
▲ push(u, u.currentNeighbour);
▲ else:
▲ relabel(u);
===
The [[FIFO]] push-relabel algorithm<ref name="goldberg86"/> organizes the active vertices into a queue. The initial active nodes can be inserted in arbitrary order. The algorithm always removes the vertex at the front of the queue for discharging. Whenever an inactive vertex is becomes active, it is appended to the back of the queue.
The algorithm has {{nowrap|''O''(''V''<sup>3</sup>)}} time complexity.
▲ discharge(u);
▲ current = current.next;
The relabel-to-front push-relabel algorithm<ref name="clrs26"/> organizes all vertices into a linked list. The nodes can be inserted in arbitrary order. The algorithm scans the list from front to back and performs a discharge operation on the current vertex if it is active. If the node is relabeled, it is moved to the front of the list, and the scan is restarted from the front.
The algorithm also has {{nowrap|''O''(''V''<sup>3</sup>)}} time complexity.
====Highest-label selection rule====
The highest-label push-relabel algorithm<ref name="cheriyan88"/> organizes all vertices into buckets indexed by their heights. The algorithm always selects an active vertex with the largest height to discharge.
The algorithm has {{nowrap|''O''(''V''^2{{sqrt|''E''}})}} time complexity.
==Sample implementation==
|