最短路径最大流的SAP算法

来源:互联网 发布:linux ubuntu安装 rpm 编辑:程序博客网 时间:2024/06/10 17:53

EK算法的时间复杂度为O(VE^2),效率比较低。使用最短路径最大流的SAP算法,时间复杂度为O(EV^2),速度快很多。

EK算法使用BFS计算增广路径,耗费时间长。SAP算法在求增广路径时,引入了距离标号,加快了计算求增广路径的过程。

下面介绍一些概念:
距离标号:每个结点到宿结点所需要经过的弧数量的下界。
允许弧:d[u] = d[v] + 1,并且c[u, v]>0的边称为允许弧。每次都走允许弧可以保证走的路径时最短路径。

那么SAP的算法框架可以归纳如下:
1. 用BFS初始化网络中结点的距离标号。
2. 从源点依次往后遍历允许弧到宿点。得到一个增广路。
3. 更新残量网络。重复步骤1~3。
4. 当更新到某个点找不到允许弧时,更新当前结点的d。更新方法d[u] = min(d[vi] + 1)。然后回溯到上一个点重新允许弧。当没有任何可达边时,复制为无效值。
5. 当源点的d值大与网络中结点的数量时,表示网络中再无增广路,结束循环。

编码实现如下:

#-*- coding: utf-8 -*-topo = { 1 : {2 : 2, 3 : 5},         2 : {1 : 0, 3 : 2, 4 : 2},         3 : {1 : 0, 2 : 0, 4 : 3},         4 : {2 : 0, 3 : 0} }def init_dis(s, t, dis):    if s == t: return    for node in topo[t]:        if topo[node][t] > 0 and dis[node] == 0:            dis[node] = dis[t] + 1            init_dis(s, node, dis)def get_augment_path(s, t, dis, pre, remain):    if s == t: return remain    for node, cap in topo[s].items():        if cap > 0 and dis[s] == dis[node] + 1 and pre[node] == 0:            if remain > cap: remain = cap            pre[node] = s            rst = get_augment_path(node, t, dis, pre, remain)            if rst != 999:                topo[s][node] = topo[s][node] - rst                topo[node][s] = topo[node][s] + rst                return rst            else: # 回溯                rst = get_augment_path(node, t, dis, pre, remain)                if rst != 999:                    topo[s][node] = topo[s][node] - rst                    topo[node][s] = topo[node][s] + rst                    return rst    else: # 没有允许弧,更新d        min_d = 999        for node in topo[s]:            if dis[node] + 1 < min_d and topo[s][node] > 0: min_d = dis[node] + 1        dis[s] = min_d    return 999def sap(s, t):    dis = [0 for i in range(len(topo) + 1)]    init_dis(1, 4, dis)    flow = 0    while dis[s] < len(topo):        pre = [0 for i in range(len(topo) + 1)]        rst = get_augment_path(1, 4, dis, pre, 999)        if rst != 999: flow = flow + rst    print flowif __name__ == '__main__':    sap(1, 4)
0 0
原创粉丝点击