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))


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

借鉴了点个赞呗

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Edmonds-Karp算法是一种最大算法,可以在网络问题中找到最大量。Matlab是一款数学软件,可以用于求解各种数学问题,包括网络问题。可以使用Matlab编写Edmonds-Karp算法的程序或者将现有的Edmonds-Karp算法移植到Matlab中进行求解。 ### 回答2: Edmonds-Karp算法是解决最大问题的一种经典算法。它是基于Ford-Fulkerson算法的改进版本,通过在寻找增广路径时使用BFS(广度优先搜索)来保证找到的路径是最短路径。以下是一个使用Matlab实现Edmonds-Karp算法的伪代码: 1. 输入: 邻接矩阵adjMatrix,表示图的连接关系;起始节点source和目标节点target。 2. 初始化残余容量矩阵residualCapacity,将其与adjMatrix相同并全部初始化为0。 3. 初始化最大量maxFlow为0。 4. 循环直到无法找到增广路径: 5. 使用BFS从source到target寻找增广路径,得到路径path。 6. 若无法找到增广路径,则退出循环。 7. 计算增广路径上的最小残余容量minCapacity。 8. 更新残余容量矩阵residualCapacity: - 对于路径上的每一条边(u, v),将residualCapacity[u][v]减去minCapacity。 - 对于路径上的每一条反向边(v, u),将residualCapacity[v][u]增加minCapacity。 9. 将maxFlow增加minCapacity。 10. 输出maxFlow作为最大量。 在Matlab中实现Edmonds-Karp算法,可以根据以下步骤进行编程: - 首先,使用邻接矩阵adjMatrix表示图的连接关系,可以使用Matlab中的二维数组进行表示。 - 然后,根据输入的source和target,使用BFS算法找到增广路径。可以使用队列(Queue)数据结构实现BFS。 - 计算增广路径上的最小残余容量minCapacity,可以使用带权图中的最小值函数进行计算。 - 更新残余容量矩阵residualCapacity,可以根据路径上的边进行更新操作。 - 循环直到无法找到增广路径,可以使用while循环实现。 - 输出最大量maxFlow作为结果。 总之,通过以上步骤进行编程,即可在Matlab中实现Edmonds-Karp算法来解决最大问题。 ### 回答3: Edmonds-Karp算法是一种用于解决最大问题的算法,它是基于Ford-Fulkerson算法的改进版本。该算法通过在残余网络中不断寻找增广路径来找到最大。 在Matlab中实现Edmonds-Karp算法,可以按以下步骤进行: 1. 创建一个图表示残余网络,图中的边包含它们的容量和量。可以使用Matlab中的图论相关函数(如graph函数)创建图。 2. 初始化每条边的量为0。 3. 在残余网络中寻找增广路径,可以使用广度优先搜索(BFS)算法。从源节点开始,通过检查当前节点的邻居节点来找到增广路径。如果在残余网络中找到一条增广路径,就可以通过调整路径上的边的量来增加总量。 4. 不断重复步骤3,直到在残余网络中找不到增广路径为止,即没有可以进一步增加总量的路径。 5. 返回最大。 在Matlab中实现Edmonds-Karp算法需要对图的表示和广度优先搜索算法有一定的了解。可以使用Matlab中的图论包(如Graph and Digraph)来操作图,并使用队列数据结构来实现BFS算法。 需要注意的是,由于Edmonds-Karp算法的复杂度较高,如果图的规模比较大,算法可能需要较长的运行时间。在实际应用中,可以考虑使用其他更高效的最大算法,如Dinic算法或Push-Relabel算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值