python实现最大流问题 push-relabel与Edmonds-karp

EK代码如下:

import time
start_1=time.time()
edgeLinks=dict()#边
edgeWeight=dict()#权重

stack_bfs_i=[]#
stack_bfs_o=[]# 放点判断
bfs_road=[]#路
Pre_set=dict()#前驱集合
ju=0#连通判断
MIN=99999
SUB=[]#MIN的集合,最后相加即最大流

def BFS(start,end):
    global edgeLinks,edgeWeight,ju
    bfs_road.clear()
    stack_bfs_i.clear()
    stack_bfs_i.append(start)
    stack_bfs_o=set()
    stack_bfs_o.add(start)
    while(len(stack_bfs_i)>0):
        d=stack_bfs_i.pop(0)
        if d in edgeLinks.keys():
            nodes=edgeLinks[d]
            # print(nodes)
            for t in nodes:
                if(t==end):
                    Pre_set[t] = d
                    ju=1
                    bfs_road.append(end)
                    while(start not in bfs_road):
                        bfs_road.append(Pre_set[bfs_road[-1]])
                    bfs_road.reverse()
                    return

                if t not in stack_bfs_o:
                    Pre_set[t] = d
                    stack_bfs_i.append(t)
                    stack_bfs_o.add(t)
        ju=-1


def UPDATA(start,end):
    global bfs_road,edgeLinks,edgeWeight,ju,MIN,SUB
    for item in range(len(bfs_road)-1):
        if MIN>edgeWeight[bfs_road[item]][bfs_road[item+1]] :
            MIN=edgeWeight[bfs_road[item]][bfs_road[item+1]]
    SUB.append(MIN)
    for item1 in range(len(bfs_road)-1):#进行权重和边的更新
        if edgeWeight[bfs_road[item1]][bfs_road[item1+1]]-MIN==0:
            del edgeWeight[bfs_road[item1]][bfs_road[item1+1]]
            edgeLinks[bfs_road[item1]].remove(bfs_road[item1+1])
            if bfs_road[item1+1] not in edgeLinks:
                edgeLinks[bfs_road[item1+1]] = set()
            edgeLinks[bfs_road[item1+1]].add(bfs_road[item1])
            if bfs_road[item1+1] not in edgeWeight:
                edgeWeight[bfs_road[item1+1]] = dict()
                edgeWeight[bfs_road[item1+1]].update({bfs_road[item1]: MIN})
            else:
                if bfs_road[item1] in edgeWeight[bfs_road[item1 + 1]].keys():
                    edgeWeight[bfs_road[item1 + 1]][bfs_road[item1]] = edgeWeight[bfs_road[item1 + 1]][bfs_road[item1]] + MIN
                if bfs_road[item1] not in edgeWeight[bfs_road[item1 + 1]].keys():
                    edgeWeight[bfs_road[item1 + 1]].update({bfs_road[item1]: MIN})

        else:
            edgeWeight[bfs_road[item1]][bfs_road[item1 + 1]]=edgeWeight[bfs_road[item1]][bfs_road[item1 + 1]]-MIN
            if bfs_road[item1 + 1] not in edgeLinks:
                edgeLinks[bfs_road[item1 + 1]] = set()
            edgeLinks[bfs_road[item1 + 1]].add(bfs_road[item1])
            if bfs_road[item1 + 1] not in edgeWeight:
                edgeWeight[bfs_road[item1 + 1]] = dict()
                edgeWeight[bfs_road[item1 + 1]].update({bfs_road[item1]: MIN})
            else:
                if bfs_road[item1] in edgeWeight[bfs_road[item1 + 1]].keys():
                    edgeWeight[bfs_road[item1 + 1]][bfs_road[item1]] = edgeWeight[bfs_road[item1 + 1]][bfs_road[item1]] + MIN
                if bfs_road[item1] not in edgeWeight[bfs_road[item1 + 1]].keys():
                    edgeWeight[bfs_road[item1 + 1]].update({bfs_road[item1]: MIN})


def load():
    global ju,MIN,stack_bfs_i,stack_bfs_o,edgeWeight,edgeLinks,Pre_set
    f = open("测试用例2.txt",'r')
    N,E=map(int,f.readline().split())
    start,end=f.readline().split()
    for item in range(E):
        a,b,c=map(int,f.readline().split())
        if str(a) not in edgeLinks: edgeLinks[str(a)] = set()
        edgeLinks[str(a)].add(str(b))
        if str(a) not in edgeWeight:
            edgeWeight[str(a)] = dict()
        edgeWeight[str(a)].update({str(b): c})
    while(ju!=-1):
        BFS(start,end)
        if(ju!=-1):
            UPDATA(start,end)
load()
print(sum(SUB))
end_1= time.time()
print('Running time: %s Seconds' % (end_1 - start_1))

结果如下:
读取格式为(存放至txt文档里)

10 25
1 8
1 8 5
1 4 1
1 6 6
1 5 1
2 7 2
2 9 1
3 10 1
3 9 4
3 2 6
3 1 4
3 8 3
4 8 9
4 6 4
4 3 8
5 4 3
5 9 9
6 7 7
6 10 2
7 10 3
7 8 10
7 5 10
9 7 6
9 10 7
10 4 7
10 2 2
截图如下:
在这里插入图片描述

结果如下:
在这里插入图片描述

PR算法:

import time
start_1=time.time()

edgeLinks=dict()#边
RedgeLinks=dict()#反向边
edgeWeight=dict()#权重
dot_height=dict()
height=0
stack_bfs_i=[]#
stack_bfs_o=[]# 放点判断
bfs_road=[]#路
Pre_set=dict()#前驱集合
ju=0#连通判断
Capacity=dict()
ju_C=0
height_set=[]
V_set=set()

def RBFS(start,end):
    global N,edgeLinks,edgeWeight,ju,Pre_set,dot_height,height,RedgeLinks
    bfs_road.clear()
    stack_bfs_i.clear()
    stack_bfs_i.append(start)
    stack_bfs_o=set()
    stack_bfs_o.add(start)
    dot_height[height] = set()
    dot_height[height].add(start)
    while(len(stack_bfs_i) > 0):
        d=stack_bfs_i.pop(0)
        if d in RedgeLinks.keys():
            nodes=RedgeLinks[d]
            for t in nodes:
                if t not in stack_bfs_o:
                    Pre_set[t] = d
                    stack_bfs_i.append(t)
                    stack_bfs_o.add(t)
    ju=-1
    len_dot=1
    while len_dot != N-1:
        height = height + 1
        dot_height[height] = set()
        for i in Pre_set.keys():
            for t in dot_height[height - 1]:
                if Pre_set[i] == t and i != end:
                    dot_height[height].add(i)
                    len_dot = len_dot + 1

    dot_height[N]=set()
    dot_height[N].add(end)

def Initial(start,end):
    global edgeLinks,dot_height,edgeWeight,Capacity
    nodes=edgeLinks[start]
    for i in list(nodes):
        edgeLinks[start].remove(i)
        if i not in edgeLinks:edgeLinks[i]=set()
        edgeLinks[i].add(start)
        n=edgeWeight[start][i]
        Capacity.update({i: n})
        del edgeWeight[start][i]
        if i not in edgeWeight: edgeWeight[i] = dict()
        if start in edgeWeight[i].keys():
            edgeWeight[i][start]=edgeWeight[i][start]+n
        else:
            edgeWeight[i].update({start : n})

def Check(end):
    global dot_height,Capacity,edgeWeight,edgeLinks,ju_C
    for i in Capacity.keys():
        if i!=end and Capacity[i]!=0:
            ju_C=1
            return
    ju_C=-1

def FindPoint(start):
    global Capacity,dot_height,edgeLinks,edgeWeight,height_set
    height_set.clear()
    Capacity[start]=0
    for i in list(dot_height.keys()):
        height_set.append(i)
    height_set.reverse()
    for length in height_set:
        for point in dot_height[length]:
            if Capacity[point]!=0:
                v_height=length
                return point,v_height

def Check_residue(point,height):
    global edgeLinks,edgeWeight,dot_height
    for p in edgeLinks[point]:
        if height<1:
            return -1
        if p in dot_height[height-1]:
            return p
    else:
        return -1

def Push(v,e):
    global edgeLinks,edgeWeight,dot_height,Capacity,start
    if Capacity[v] >= edgeWeight[v][e]:
        if e not in edgeWeight: edgeWeight[e]=dict()
        if v in list(edgeWeight[e].keys()):
            edgeWeight[e][v]=edgeWeight[e][v]+edgeWeight[v][e]
        else:
            edgeWeight[e].update({v:edgeWeight[v][e]})
        edgeLinks[v].remove(e)
        if e not in edgeLinks:
            edgeLinks[e]=set()
        edgeLinks[e].add(v)
        Capacity[v]=Capacity[v]-edgeWeight[v][e]
        Capacity[e]=Capacity[e]+edgeWeight[v][e]
        del edgeWeight[v][e]
    else:
        if e not in edgeWeight:
            edgeWeight[e]=dict()
        edgeWeight[v][e]=edgeWeight[v][e]-Capacity[v]
        if v in list(edgeWeight[e].keys()):
            edgeWeight[e][v]=edgeWeight[e][v]+Capacity[v]
        else:
            edgeWeight[e].update({v:Capacity[v]})
        if e not in edgeLinks:
            edgeLinks[e]=set()
        edgeLinks[e].add(v)
        Capacity[e] = Capacity[e] + Capacity[v]
        Capacity[v]=0

    Capacity[start]=0

def height_change(v,height):
    global dot_height
    if height+1 in dot_height.keys():
        dot_height[height + 1].add(v)
        dot_height[height].remove(v)
    else:
        dot_height[height+1]=set()
        dot_height[height+1].add(v)
        dot_height[height].remove(v)


def load():
    global V_set,start,end,ju,stack_bfs_i,stack_bfs_o,edgeWeight,edgeLinks,Pre_set,dot_height,height,N,V,RedgeLinks,Capacity,ju_C
    f = open("测试用例4.txt",'r')
    N,E=map(int,f.readline().split())
    start,end=f.readline().split()
    for item in range(E):
        a,b,c=map(int,f.readline().split())
        V_set.add(str(a))
        V_set.add(str(b))
        if str(a) not in edgeLinks: edgeLinks[str(a)] = set()
        if str(b) not in RedgeLinks: RedgeLinks[str(b)]=set()
        RedgeLinks[str(b)].add(str(a))
        edgeLinks[str(a)].add(str(b))
        if str(a) not in edgeWeight:
            edgeWeight[str(a)] = dict()
        edgeWeight[str(a)].update({str(b): c})
    RBFS(end,start)#反向BFS找高度
    for i in list(V_set):#容量初始化
        Capacity.update({i:0})
    Initial(start,end) #图初始化,源点出边反向
    Check(end) #判断是否存在盈余点
    while ju_C!=-1:
        PointMax,v_height=FindPoint(start)#找v点和高度
        ju2=Check_residue(PointMax,v_height)
        if ju2!=-1:
            Push(PointMax,ju2)
        else:
            height_change(PointMax,v_height)
        Check(end)
    print(Capacity[end])


load()
end_1= time.time()
print('Running time: %s Seconds' % (end_1 - start_1))


读取格式和刚刚相同:
在这里插入图片描述

借鉴了点个赞呗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值