Skip to content

26.5 The relabel-to-front algorithm

26.5-1

Illustrate the execution of RELABEL-TO-FRONT\text{RELABEL-TO-FRONT} in the manner of Figure 26.10 for the flow network in Figure 26.1(a). Assume that the initial ordering of vertices in LL is v1,v2,v3,v4\langle v_1, v_2, v_3, v_4 \rangle and that the neighbor lists are

v1.N=s,v2,v3,v2.N=s,v1,v3,v4,v3.N=v1,v2,v4,t,v4.N=v2,v3,t. \begin{aligned} v_1.N & = \langle s, v_2, v_3 \rangle, \\ v_2.N & = \langle s, v_1, v_3, v_4 \rangle, \\ v_3.N & = \langle v_1, v_2, v_4, t \rangle, \\ v_4.N & = \langle v_2, v_3, t \rangle. \end{aligned}

When we initialize the preflow, we have 2929 units of flow leaving ss. Then, we consider v1v_1 since it is the first element in the LL list. When we discharge it, we increase it's height to 11 so that it can dump 1212 of it's excess along its edge to vertex v3v_3, to discharge the rest of it, it has to increase it's height to V+1|V| + 1 to discharge it back to ss. It was already at the front, so, we consider v2v_2. We increase its height to 11. Then, we send all of its excess along its edge to v4v_4. We move it to the front, which means we next consider v1v_1, and do nothing because it is not overflowing. Up next is vertex v3v_3. After increasing its height to 11, it can send all of its excess to tt. This puts v3v_3 at the front, and we consider the non-overflowing vertices v2v_2 and v1v_1. Then, we consider v4v_4, it increases its height to 11, then sends 44 units to tt. Since it still has an excess of 99 units, it increases its height once again. Then it becomes valid for it to send flow back to v2v_2 or to v3v_3. It considers v2v_2 first because of the ordering of its neighbor list. This means that 99 units of flow are pushed back to v2v_2. Since v4.hv_4.h increased, it moves to the front of the list Then, we consider v2v_2 since it is the only still overflowing vertex. We increase its height to 33. Then, it is overflowing by 99 so it increases its height to 33 to send 99 units to v4v_4. It's height increased so it goes to the of the list. Then, we consider v4v_4, which is overflowing. It pushes 77 units to v3v_3. Since it is still overflowing by 22, it increases its height to 44 and pushes the rest back to v2v_2 and goes to the front of the list. Up next is v2v_2, which increases its height by 22 to sends its overflow to v4v_4. The excess flow keeps bobbing around the four vertices, each time requiring them to increase their height a bit to discharge to a neighbor only to have that neighbor increase to discharge it back until v2v_2 has increased in height enough to send all of it's excess back to s. Last but not least, v3v_3 pushes its overflow of 77 units to tt, and gives us a maximum flow of 2323.

26.5-2 \star

We would like to implement a push-relabel algorithm in which we maintain a firstin, first-out queue of overflowing vertices. The algorithm repeatedly discharges the vertex at the head of the queue, and any vertices that were not overflowing before the discharge but are overflowing afterward are placed at the end of the queue. After the vertex at the head of the queue is discharged, it is removed. When the queue is empty, the algorithm terminates. Show how to implement this algorithm to compute a maximum flow in O(V3)O(V^3) time.

Initially, the vertices adjacent to ss are the only ones which are overflowing. The implementation is as follows:

PUSH-RELABEL-QUEUE(G, s)
    INITIALIZE-PREFLOW(G, s)
    let q be a new empty queue
    for v ∈ G.Adj[s]
        PUSH(q, v)
    while q.head != NIL
        DISCHARGE(q.head)
        POP(q)

Note that we need to modify the DISCHARGE\text{DISCHARGE} algorithm to push vertices vv onto the queue if vv was not overflowing before a discharge but is overflowing after one.

Between lines 7 and 8 of DISCHARGE(u)\text{DISCHARGE}(u), add the line "if v.e>0v.e > 0, PUSH(q,v)\text{PUSH}(q, v)." This is an implementation of the generic push-relabel algorithm, so we know it is correct. The analysis of runtime is almost identical to that of Theorem 26.30. We just need to verify that there are at most V|V| calls to DISCHARGE\text{DISCHARGE} between two consecutive relabel operations. Observe that after calling PUSH(u,v)\text{PUSH}(u, v), Corollary 26.28 tells us that no admissible edges are entering vv. Thus, once vv is put into the queue because of the push, it can't be added again until it has been relabeled. Thus, at most V|V| vertices are added to the queue between relabel operations.

26.5-3

Show that the generic algorithm still works if RELABEL\text{RELABEL} updates u.hu.h by simply computing u.h=u.h+1u.h = u.h + 1. How would this change affect the analysis of RELABEL-TO-FRONT\text{RELABEL-TO-FRONT}?

If we change relabel to just increment the value of uu, we will not be ruining the correctness of the Algorithm. This is because since it only applies when u.hv.hu.h \le v.h, we won't be every creating a graph where hh ceases to be a height function, since u.hu.h will only ever be increasing by exactly 11 whenever relabel is called, ensuring that u.h+1v.hu.h + 1 \le v.h. This means that Lemmatae 26.15 and 26.16 will still hold. Even Corollary 26.21 holds since all it counts on is that relabel causes some vertex's hh value to increase by at least 11, it will still work when we have all of the operations causing it to increase by exactly 11. However, Lemma 26.28 will no longer hold. That is, it may require more than a single relabel operation to cause an admissible edge to appear, if for example, u.hu.h was strictly less than the hh values of all its neighbors. However, this lemma is not used in the proof of Exercise 26.4-3, which bounds the number of relabel operations. Since the number of relabel operations still have the same bound, and we know that we can simulate the old relabel operation by doing (possibly many) of these new relabel operations, we have the same bound as in the original algorithm with this different relabel operation.

26.5-4 \star

Show that if we always discharge a highest overflowing vertex, we can make the push-relabel method run in O(V3)O(V^3) time.

We'll keep track of the heights of the overflowing vertices using an array and a series of doubly linked lists. In particular, let AA be an array of size V|V|, and let A[i]A[i] store a list of the elements of height ii. Now we create another list LL, which is a list of lists. The head points to the list containing the vertices of highest height. The next pointer of this list points to the next nonempty list stored in AA, and so on. This allows for constant time insertion of a vertex into AA, and also constant time access to an element of largest height, and because all lists are doubly linked, we can add and delete elements in constant time. Essentially, we are implementing the algorithm of Exercise 26.5-2, but with the queue replaced by a priority queue with constant time operations. As before, it will suffice to show that there are at most V|V| calls to discharge between consecutive relabel operations.

Consider what happens when a vertex vv is put into the priority queue. There must exist a vertex uu for which we have called PUSH(u,v)\text{PUSH}(u, v). After this, no ad- missible edge is entering vv, so it can't be added to the priority queue again until after a relabel operation has occurred on vv. Moreover, every call to DISCHARGE\text{DISCHARGE} terminates with a PUSH\text{PUSH}, so for every call to DISCHARGE\text{DISCHARGE} there is another vertex which can't be added until a relabel operation occurs. After V|V| DISCHARGE\text{DISCHARGE} operations and no relabel operations, there are no remaining valid PUSH\text{PUSH} operations, so either the algorithm terminates, or there is a valid relabel operation which is performed. Thus, there are O(V3)O(V^3) calls to DISCHARGE\text{DISCHARGE}. By carrying out the rest of the analysis of Theorem 26.30, we conclude that the runtime is O(V3)O(V^3).

26.5-5

Suppose that at some point in the execution of a push-relabel algorithm, there exists an integer 0<kV10 < k \le |V| - 1 for which no vertex has v.h=kv.h = k. Show that all vertices with v.h>kv.h > k are on the source side of a minimum cut. If such a kk exists, the gap heuristic updates every vertex vV{s}v \in V - \{s\} for which v.h>kv.h > k, to set v.h=max(v.h,V+1)v.h = \max(v.h, |V| + 1). Show that the resulting attribute hh is a height function. (The gap heuristic is crucial in making implementations of the push-relabel method perform well in practice.)

Suppose to try and obtain a contradiction that there were some minimum cut for which a vertex that had v.h>kv.h > k were on the sink side of that cut. For that minimum cut, there is a residual flow network for which that cut is saturated. Then, if there were any vertices that were also on the sink side of the cut which had an edge going to vv in this residual flow network, since it's hh value cannot be equal to kk, we know that it must be greater than kk since it could be only at most one less than vv. We can continue in this way to let SS be the set of vertices on the sink side of the graph which have an hh value greater than kk. Suppose that there were some simple path from a vertex in SS to ss. Then, at each of these steps, the height could only decrease by at most 11, since it cannot get from above kk to 00 without going through kk, we know that there is no path in the residual flow network going from a vertex in SS to ss. Since a minimal cut corresponds to disconnected parts of the residual graph for a maximum flow, and we know there is no path from SS to ss, there is a minimum cut for which SS lies entirely on the source side of the cut. This was a contradiction to how we selected vv, and so have shown the first claim.

Now we show that after updating the hh values as suggested, we are still left with a height function. Suppose we had an edge (u,v)(u, v) in the residual graph. We knew from before that u.hv.h+1u.h \le v.h + 1. However, this means that if u.h>ku.h > k, so must be v.hv.h. So, if both were above kk, we would be making them equal, causing the inequality to still hold. Also, if just v.kv.k were above kk, then we have not decreased it's hh value, meaning that the inequality also still must hold. Since we have not changed the value of s.hs.h, and t.ht.h, we have all the required properties to have a height function after modifying the hh values as described.