毕业设计,毕业论文代写。专业水平。钻石水准,黄金品质。

计算机专业毕业设计,论文,设计代写。电邮:elevenor@gmail.com。专业水平,质优价廉。

翻译 The relabel-to-front algorithm---麻省理工算法导论部分翻译(由于原创,所以很烂)收藏

新一篇: C++Primer 第四版 部分习题解答 | 旧一篇: 华容道游戏与算法

The relabel-to-front algorithm

The push-relabel method allows us to apply the basic operations in any order at all. By choosing the order carefully and managing the network data structure efficiently, however, we can solve the maximum-flow problem faster than the O(V2E) bound. We shall now examine the relabel-to-front algorithm, a push-relabel algorithm whose running time is O(V3), which is asymptotically at least as good as O(V2E), and better for dense networks.

The relabel-to-front algorithm maintains a list of the vertices in the network. Beginning at the front, the algorithm scans the list, repeatedly selecting an over-flowing vertex u and then "discharging" it, that is, performing push and relabel operations until u no longer has a positive excess. Whenever a vertex is relabeled, it is moved to the front of the list (hence the name "relabel-to-front") and the algorithm begins its scan anew.

The correctness and analysis of the relabel-to-front algorithm depend on the notion of "admissible" edges: those edges in the residual network through which flow can be pushed. After proving some properties about the network of admissible edges, we shall investigate the discharge operation and then present and analyze the relabel-to-front algorithm itself.

Admissible edges and networks

If G = (V, E) is a flow network with source s and sink t, f is a preflow in G, and h is a height function, then we say that (u, v) is an admissible edge if cf(u, v) > 0 and h(u) = h(v) + 1. Otherwise, (u, v) is inadmissible. The admissible network is Gf,h = (V, Ef,h), where Ef,h is the set of admissible edges.

The admissible network consists of those edges through which flow can be pushed. The following lemma shows that this network is a directed lemma graph (dag).

Lemma 26.27: (The admissible network is acyclic)

If G = (V, E) is a flow network, f is a preflow in G, and h is a height function on G, then the admissible network Gf,h = (V, Ef,h) is acyclic.

Proof The proof is by contradiction. Suppose that Gf,h contains a cycle p = v0, v1 , . . . ,vk, where v0 = vk and k > 0. Since each edge in p is admissible, we have h(vi-1) = h(vi) + 1 for i = 1, 2, . . . ,k. Summing around the cycle gives

Because each vertex in cycle p appears once in each of the summations, we derive the contradiction that 0 = k.

The next two lemmas show how push and relabel operations change the admissible network.

Lemma 26.28

Let G = (V, E) be a flow network, let f be a preflow in G, and suppose that the attribute h is a height function. If a vertex u is overflowing and (u, v) is an admissible edge, then PUSH(u, v) applies. The operation does not create any new admissible edges, but it may cause (u, v) to become inadmissible.

Proof By the definition of an admissible edge, flow can be pushed from u to v. Since u is overflowing, the operation PUSH(u, v) applies. The only new residual edge that can be created by pushing flow from u to v is the edge (v, u). Since h[v] = h[u] - 1, edge (v, u) cannot become admissible. Then cf(u, v) = 0 afterward and (u, v) becomes inadmissible.

Lemma 26.29

Let G = (V, E) be a flow network, let f be a preflow in G, and suppose that the attribute h is a height function. If a vertex u is overflowing and there are no admissible edges leaving u, then RELABEL(u) applies. After the relabel operation, there is at least one admissible edge leaving u, but there are no admissible edges entering u.

Proof If u is overflowing, then by Lemma 26.15, either a push or a relabel operation applies to it. If there are no admissible edges leaving u, then no flow can be pushed from u and so RELABEL(u) applies. After the relabel operation, h[u] = 1 + min {h[v] : (u, v) Ef}. Thus, if v is a vertex that realizes the minimum in this set, the edge (u, v) becomes admissible. Hence, after the relabel, there is at least one admissible edge leaving u.

To show that no admissible edges enter u after a relabel operation, suppose that there is a vertex v such that (v, u) is admissible. Then, h[v] = h[u] + 1 after the relabel, and so h[v] > h[u] + 1 just before the relabel. But by Lemma 26.13, no residual edges exist between vertices whose heights differ by more than 1. Moreover, relabeling a vertex does not change the residual network. Thus, (v, u) is not in the residual network, and hence it cannot be in the admissible network.

Neighbor lists

Edges in the relabel-to-front algorithm are organized into "neighbor lists." Given a flow network G = (V, E), the neighbor list N[u] for a vertex u V is a singly linked list of the neighbors of u in G. Thus, vertex v appears in the list N[u] if (u, v) E or (v, u) E. The neighbor list N[u] contains exactly those vertices v for which there may be a residual edge (u, v). The first vertex in N[u] is pointed to by head[N[u]]. The vertex following v in a neighbor list is pointed to by next-neighbor[v]; this pointer is NIL if v is the last vertex in the neighbor list.

The relabel-to-front algorithm cycles through each neighbor list in an arbitrary order that is fixed throughout the execution of the algorithm. For each vertex u, the field current[u] points to the vertex currently under consideration in N[u]. Initially, current[u] is set to head[N[u]].

Discharging an overflowing vertex

An overflowing vertex u is discharged by pushing all of its excess flow through admissible edges to neighboring vertices, relabeling u as necessary to cause edges leaving u to become admissible. The pseudocode goes as follows.

DISCHARGE(u)
1  while e[u] > 0
2      do v  current[u]
3          if v = NIL
4             then RELABEL(u)
5                  current[u]  head[N[u]]
6          elseif cf(u, v) > 0 and h[u] = h[v] + 1
7            then PUSH(u, v)
8          else current[u]  next-neighbor[v]

Figure 26.9 steps through several iterations of the while loop of lines 1-8, which executes as long as vertex u has positive excess. Each iteration performs exactly one of three actions, depending on the current vertex v in the neighbor list N[u].

1.    If v is NIL, then we have run off the end of N[u]. Line 4 relabels vertex u, and then line 5 resets the current neighbor of u to be the first one in N[u]. (Lemma 26.30 below states that the relabel operation applies in this situation.)

2.    If v is non-NIL and (u, v) is an admissible edge (determined by the test in line 6), then line 7 pushes some (or possibly all) of u's excess to vertex v.

3.    If v is non-NIL but (u, v) is inadmissible, then line 8 advances current[u] one position further in the neighbor list N[u].

Figure 26.9: Discharging a vertex y. It takes 15 iterations of the while loop of DISCHARGE to push all the excess flow from y. Only the neighbors of y and edges entering or leaving y are shown. In each part, the number inside each vertex is its excess at the beginning of the first iteration shown in the part, and each vertex is shown at its height throughout the part. To the right is shown the neighbor list N[y] at the beginning of each iteration, with the iteration number on top. The shaded neighbor is current[y]. (a) Initially, there are 19 units of excess to push from y, and current[y] = s. Iterations 1, 2, and 3 just advance current[y], since there are no admissible edges leaving y. In iteration 4, current[y] = NIL (shown by the shading being below the neighbor list), and so y is relabeled and current[y] is reset to the head of the neighbor list. (b) After relabeling, vertex y has height 1. In iterations 5 and 6, edges (y, s) and (y, x) are found to be inadmissible, but 8 units of excess flow are pushed from y to z in iteration 7. Because of the push, current[y] is not advanced in this iteration. (c) Because the push in iteration 7 saturated edge (y, z), it is found inadmissible in iteration 8. In iteration 9, current[y] = NIL, and so vertex y is again relabeled and current[y] is reset. (d) In iteration 10, (y, s) is inadmissible, but 5 units of excess flow are pushed from y to x in iteration 11. (e) Because current[y] was not advanced in iteration 11, iteration 12 finds (y, x) to be inadmissible. Iteration 13 finds (y, z) inadmissible, and iteration 14 relabels vertex y and resets current[y]. (f) Iteration 15 pushes 6 units of excess flow from y to s. (g) Vertex y now has no excess flow, and DISCHARGE terminates. In this example, DISCHARGE both starts and finishes with the current pointer at the head of the neighbor list, but in general this need not be the case.

The relabel-to-front algorithm

In the relabel-to-front algorithm, we maintain a linked list L consisting of all vertices in V - {s, t}. A key property is that the vertices in L are topologically sorted according to the admissible network, as we shall see in the loop invariant below. (Recall from Lemma 26.27 that the admissible network is a dag.)

The pseudocode for the relabel-to-front algorithm assumes that the neighbor lists N[u] have already been created for each vertex u. It also assumes that next[u] points to the vertex that follows u in list L and that, as usual, next[u] = NIL if u is the last vertex in the list.

RELABEL-TO-FRONT(G, s, t)
 1  INITIALIZE-PREFLOW(G, s)
 2  L  V[G] - {s, t}, in any order
 3  for each vertex u  V[G] - {s, t}
 4      do current[u]  head[N[u]]
 5  u  head[L]
 6  while u  NIL 
 7     do old-height  h[u]
 8        DISCHARGE(u)
 9        if h[u] > old-height
10           then move u to the front of list L
11        u  next[u]

 

 

relabel-to-front算法

push-relabel算法允许我们以任何的顺序应用这些基本操作。然而,通过仔细选择顺序并且设计出有效的网络数据结构,我们可以以快于O(V2E)的界限解决最大流问题。我们现在仔细检查relabel-to-front算法,它是一种运行时间为O(V3)push-relabel算法。Asymptotically算法的时间最少为O(V2E),并且该算法对于稠密图更加有效。

relabel-to-front算法维护网络图中的一系列的节点。在开始的时候,算法首先扫描链表,反复选择一个标记为u的节点并将其“开除”出去,这就是说,通过pushrelabel操作,直到u节点不再有正向溢出。当一个节点被重新标记的时候,它被移动到链表的开始(relabel-to-front算法由此得名),然后算法重新进行扫描。

对于relabel-to-front算法的分析和校正依赖于我们对“可接受”边的观察:这些边位于网络的剩余部分,并且流在这些边中可以运动。在证明了一些关于可接受网络边的特性之后,我们将深入探讨“开除”操作,并且将展示和分析relabel-to-front algorithm本身。

可接受的边和网络

如果图G = (V, E)是一个有源s和终点t的网络流,f是图G的前导流,h是一个求高度的函数,那么我们可以认为若cf(u, v) > 0h(u) = h(v) + 1,则边(u, v)是一条可接受边,否则边(u, v)为不可接受的。可接受的网络则是图Gf,h = (V, Ef,h),其边集Ef,h是一个由可接受边所组成的集合。

可接受网络则是由一组流可以通过的边组成。下面的引理表明该网络是一个有向图。

引理26.27:可接受网络是没有回路的。

如果图G = (V, E)是一组网络流, f是图G的前导流,h是一个求高度的函数,那么可接受网络Gf,h = (V, Ef,h)是没有回路的。

证明:

我们通过反证法来证明之。假设图Gf,h含有一个回路p = v0, v1 , . . . ,vk〉,在该回路中,v0 = vk 且有k > 0,由于任何一个边都是可接受边,我们有对于i = 1, 2, . . . 来说,h(vi-1) = h(vi) + 1。对于回路中的各边相加可得:

由于环中的任何一个节点在相加的时候只出现一次,所以我们由此可得k=0,进而推出矛盾。下面一个引理将表明pushrelabel操作是如何改变一个可接受网络的。

引理26.28

如果图G = (V, E)是一组网络流,f是图G的前导流,h是一个求高度的函数。那么如果一个节点u是溢出点且边(u, v)是一条可接受边,则我们可以应用push(u, v)操作。该操作并不产生任何可接受边,反而有可能导致边(u, v)变为不可接受边。

证明:通过定义一个可接受边,流可以从u点推向v点,而由于节点u是溢出点,所以可以应用push(u, v)操作。通过流从u点到v点而产生的唯一的剩余边就是边(u, v)。而由于h[v] = h[u] – 1,故边(u, v)为不可接受边。这样一来,cf(u, v) = 0,从而(u, v)边成为不可接受边。

引理26.29

如果图G = (V, E)是一组网络流,f是图G的前导流,h是一个求高度的函数。如果节点u是一个溢出点且从u出发没有可接受边,这样我们可以应用Relabel(u)操作。在进行relabel操作后,从节点u出发至少有一个可接受边,但是没有任何可接受边指向u

证明:

如果u点为溢出点,那么根据引理26.15,我们或是应用push操作,或是应用relabel操作。如果从u出发没有可接受边,那么我们不能从u点出发导出流,因此我们应用relabel(u)操作。在relabel操作结束后,h[u] = 1 + min {h[v] : (u, v) Ef}。因此,如果有点v使得该集合中的最小值成立,则边(u, v)为可接受边。这样一来,在relabel操作结束后,从u出发至少有一个可接受边。

为了证明在relabel操作后,并没有任何可接受边离开u点,我们假设存在一个点v使得(u, v)边为可接受边。这样一来,在relabel操作后,有h[v] = h[u] + 1,并且在操作前有h[v] > h[u] + 1。但是通过引理26.13我们可以得知,对于两点之间高度差大于1的节点,并没有多余边存在。另外,对于一个节点的relabel操作并不影响网络的剩余部分。因此,边(u, v)并不在网络的剩余部分,这样一来它就不可能出现在可接受网络中。

邻接表

relabel-to-front算法中的节点被存储在“邻接表”中。我们给出网络流G = (V, E),在邻接表中对于节点u V,邻接表N[u]表示G图中所有与其相邻的节点。这样一来,若(u, v) E或者 (v u) E,则点v必出现在N[u]表中。邻接表N[u]准确地包含了有诸如边(u, v)一样的节点v。我们通过head[N[u]]来指向N[u]中的第一个节点;通过next-neighbor[v]来指向v节点的下一个节点,若v点是邻接表的最后一个节点,则该指针为空。

relabel-to-front算法通过以算法执行期间所确定的方式以不定的顺序遍历每一个邻接表,对于任何一个节点ucurrent[u]指向N[u]中当前正在被处理的节点。在算法开始的时候,current[u]被设为指向head[N[u]]

剔除溢出节点

通过削除其所有通过可接受边流向邻接点的溢出流,我们可以剔除溢出节点。重新标记节点u来使得所有从u点出发的边为可接受边。伪例程如下:

DISCHARGE(u)
1  while e[u] > 0
2      do v  current[u]
3          if v = NIL
4             then RELABEL(u)
5                  current[u]  head[N[u]]
6          else if cf(u, v) > 0 and h[u] = h[v] + 1
7            then PUSH(u, v)
8          else current[u]  next-neighbor[v]

只要u点有正向溢出,我们可以通过1~8行的while循环重复几个步骤当前在邻接表N[u]中的当前节点v决定了每一次循环所采取的步骤:

1.      如果点v为空,那么我们必须离开N[u]的尾部,第四行对u节点进行relabel操作。(我们将在下面的引理26.30表明该情况适用于重新标记操作)

2.      若点v不空,且(u, v)边为可接受边(由第六行的测试决定),那么第七行将u点的部分或者所有溢出点推至v节点。

3.      v点非空且边(u, v)为不可接受边,则第八行将current[u]在邻接表N[u]中前移一位。

26.29:在本图中,我们将分析剔除一个节点y。在本例中这需要相应得while循环中的15步来将y产生的所有溢出流削去。在本图中,我们仅显示进入和离开y点的节点。在程序的每一部分,节点内的数字就是其自身在循环开始时的溢出量。权值是在每次循环开始的时候在邻接表N[y]中显示的。在每一部分的最上面显示了循环的次数,用阴影标记的邻接点也即current[y],从上图中我们可以得知(a)在算法的开始的时候,图中共有19个单位的溢出流从y节点流出。current[y]=s,由于从y节点出发并没有可接受边,所以在循环的第123步我们使current[y]前移。在第四次循环的时候,current[y]=NIL(通过邻接表下面的阴影表示出来)。这样一来,y节点就被重新标记了。Current[y]被重置为当前邻接表的头部。(b)在算法执行重新标记的操作以后,y节点的高度变成了1。在循环的第五步和第六步中,边(y,s)和边(y,x)均被认为是不可接受的边。但是在循环的第七步,由于有八个单位的溢出流从y节点流向z节点,正是因为该溢出流,故在本次循环中,current[y]并不前移。(c)由于在边(y,z)上的溢出流,所以在循环的第八步中,我们认为该边是不可接受的边。因此,在第九次的循环中,本算法置current[y]=NIL,这样一来,我们不难发现,y点仍然需要被重新标记,所以,我们需要重新设定current[y](d)在第十次循环中,可以发现边(y,s)为不可接受的边,但是在第十一次循环中,我们依然可以发现,从节点y到节点x仍然有五个单位的溢出。(e)由于在第十一次循环的时候,current[y]并没有被算法前移,所以在第十二次循环的时候,我们依然认为边(y,x)是不可接受的边。在第十三次循环的时候,我们将认为边(y,z)是不可接受的边。在算法的第十四次循环的时候,不难发现,我们需要重新标记点y并且需要重置current[y]的值。(f)在算法的第十五次循环中,我们需要将从节点y到节点s的六个单位的溢出流导出。(g)在这个时候,由于节点y现在不含有任何的溢出流,所以我们需要中止剔除操作。在本例中,剔除操作均以邻接表的表头为开始和结束,这是一个特例,通常情况下并不是这个样子的。

  Relabel-to-front算法的伪代码中,我们假定每个节点的邻接表N[u]在算法开始之前已经被建立完毕。并且算法假定next[u]指向在链表Lu节点的下一个节点。因此,如果节点u是表中的最后一个节点,我们可以得出next[u]为空。

通过上面的讨论,我们给出relabel-to-front算法的伪代码如下:

 

RELABEL-TO-FRONT(G, s, t)
 1  INITIALIZE-PREFLOW(G, s)
 2  L  V[G] - {s, t}, in any order
 3  for each vertex u  V[G] - {s, t}
 4      do current[u]  head[N[u]]
 5  u  head[L]
 6  while u  NIL 
 7     do old-height  h[u]
 8        DISCHARGE(u)
 9        if h[u] > old-height
10           then move u to the front of list L
11        u  next[u]
更多内容:
软件课程设计--C语言设计火车票订票系统之源代码(模拟数据库功能)
http://blog.csdn.net/ctu_85/archive/2007/09/20/1793381.aspxa
C++Primer 第四版 部分习题解答
http://blog.csdn.net/ctu_85/archive/2007/07/04/1677834.aspx
麻省理工算法导论翻译
http://blog.csdn.net/ctu_85/archive/2007/06/08/1643179.aspx
浙江大学ACM试题解答(四月)
http://blog.csdn.net/ctu_85/archive/2007/04/24/1576831.aspx
浙江大学ACM试题解答(三月)
http://blog.csdn.net/ctu_85/archive/2007/03/20/1535556.aspx
华容道游戏与算法
http://blog.csdn.net/ctu_85/archive/2007/05/15/1610722.aspx
中国象棋对战程序C语言源代码
http://blog.csdn.net/ctu_85/archive/2007/05/04/1596351.aspx
Prim算法代码分析
http://blog.csdn.net/ctu_85/archive/2006/12/16/1445156.aspx
Kruskal算法代码分析
http://blog.csdn.net/ctu_85/archive/2006/12/16/1445147.aspx
文件加密解密源代码分析
http://blog.csdn.net/ctu_85/archive/2006/12/23/1455515.aspx
银行家算法代码分析
http://blog.csdn.net/ctu_85/archive/2006/09/09/1198551.aspx
更多试题解答:
两种计算Ack(m,n)的非递归算法
http://blog.csdn.net/ctu_85/archive/2006/11/29/1419396.aspx
上海交通大学1999年
http://blog.csdn.net/ctu_85/archive/2006/11/09/1376289.aspx
东北大学2001年
http://blog.csdn.net/ctu_85/archive/2006/11/09/1376287.aspx
清华大学1994年
http://blog.csdn.net/ctu_85/archive/2006/10/24/1349754.aspx
中国科学院2002年
http://blog.csdn.net/ctu_85/archive/2006/10/24/1349704.aspx
浙江大学计算机复试解答1
http://blog.csdn.net/ctu_85/archive/2006/10/15/1334936.aspx
浙江大学计算机复试解答2
http://blog.csdn.net/ctu_85/archive/2006/10/16/1336101.aspx
浙江大学计算机复试解答3
http://blog.csdn.net/ctu_85/archive/2006/11/02/1363159.aspx
软件可行性报告
http://blog.csdn.net/ctu_85/archive/2006/06/06/775894.aspx
软件需求分析报告
http://blog.csdn.net/ctu_85/archive/2006/06/06/775892.aspxa

发表于 @ 2007年06月08日 00:19:00|评论(loading...)|编辑

新一篇: C++Primer 第四版 部分习题解答 | 旧一篇: 华容道游戏与算法

评论:没有评论。

发表评论  


登录
Csdn Blog version 3.1a
Copyright © ctu_85