python实现:最大流pushrelabel

0.测试数据

1.PushRelabel

'''MaxflowGraph.py'''
class MFGraph(object):
    
    def __init__(self):    
        self.vertexnum = 0
        self.edgenum = 0
        
        self.origin = None
        self.destn = None

        self.VertexSet = {} #key:vertex's name; value:a list with height and excess
        self.EdgeSet = {}   #key:edge; value:a list with edge's residual capacity and flow
        self.EdgeSet_f = {} #key:edge which is in the residual network; value: residual capacity 
        self.Adjacents_f = {} 

        self.ExcessSet = []

    def generate_graph(self,v1,v2,capacity):

        self.VertexSet.setdefault(v1, [0, 0])
        self.VertexSet.setdefault(v2, [0, 0])

        self.EdgeSet.setdefault((v1,v2),[0, capacity])
        
        self.EdgeSet_f.setdefault((v1,v2), capacity)
        self.EdgeSet_f.setdefault((v2,v1), 0)

        if not v1 in self.Adjacents_f.keys():
            self.Adjacents_f[v1] = [v2]
        else:
            self.Adjacents_f[v1].append(v2)
            
        if not v2 in self.Adjacents_f.keys():
            self.Adjacents_f[v2] = [v1]
        else:
            self.Adjacents_f[v2].append(v1)

'''Maxflow_pushrelabel.py'''
import string
from  MaxflowGraph import *

def maxflow():
    G = initial_graph()
    create_preflow(G)

    while G.ExcessSet:
        #determine whether applicable push operation
        excess_u = G.ExcessSet.pop()
        
        while G.VertexSet[excess_u][1]>0:
            ispush = 0
            for u_adj in G.Adjacents_f[excess_u]: 
                if (G.EdgeSet_f[(excess_u,u_adj)] > 0) \
                    and (G.VertexSet[excess_u][0] == G.VertexSet[u_adj][0]+1):     
                    push(G,excess_u,u_adj)
                    ispush = 1

            if ispush == 0:
                relabel(G,excess_u)
    
    #print(G.EdgeSet)
    #print(G.VertexSet[G.origin])
    print(G.VertexSet[G.destn][1])

def push(G,excess_u,u_adj):
    push_flow = min(G.VertexSet[excess_u][1], G.EdgeSet_f[(excess_u,u_adj)]) 
    
    if (excess_u, u_adj) in G.EdgeSet.keys():
        G.EdgeSet[excess_u, u_adj][0] += push_flow #e.f += push_flow
    else:
        G.EdgeSet[u_adj,excess_u][0] -= push_flow #e.f -= push_flow

    #f->residual network
    G.EdgeSet_f[(excess_u, u_adj)] -=push_flow  
    G.EdgeSet_f[(u_adj, excess_u)] +=push_flow
    
    G.VertexSet[excess_u][1] -= push_flow #u.excess -= push_flow
    G.VertexSet[u_adj][1] += push_flow #adj.excess += push_flow
    
    if (u_adj!=G.origin)and(u_adj!=G.destn)and(not u_adj in G.ExcessSet):
        G.ExcessSet.append(u_adj)
    
def relabel(G,excess_u):
    #for all adj, h(u)<= h(adj)
    index = 0
    temp_v = G.Adjacents_f[excess_u][index]
    while G.EdgeSet_f[(excess_u, temp_v)] == 0:
        index += 1
        temp_v = G.Adjacents_f[excess_u][index]
    temp_h = G.VertexSet[temp_v][0]

    for u_adj in G.Adjacents_f[excess_u]:
        if (G.EdgeSet_f[(excess_u, u_adj)]>0) and (G.VertexSet[u_adj][0]<temp_h):
            temp_v = u_adj
            temp_h = G.VertexSet[u_adj][0]

    G.VertexSet[excess_u][0] = temp_h+1


def create_preflow(G):
    #initialize height function
    G.VertexSet[G.origin][0] = G.vertexnum #set origin's height 
    for adj in G.Adjacents_f[G.origin]:
        if (G.origin, adj) in G.EdgeSet.keys():
            e_capacity = G.EdgeSet[(G.origin, adj)][1]

            G.EdgeSet[(G.origin, adj)][0] = e_capacity  #e.flow = e.capacity
            G.VertexSet[adj][1] = e_capacity  #adj.excess = e.capacity
            
            if adj != G.destn:
                G.ExcessSet.append(adj)

            G.VertexSet[G.origin][1] -= e_capacity

            #f->residual network
            G.EdgeSet_f[(G.origin, adj)] = 0
            G.EdgeSet_f[(adj, G.origin)] = e_capacity
        
        
def initial_graph():
    Graph = MFGraph()

    with open('test-3.txt','r') as f:
        Graph.vertexnum = int(f.readline().strip())
        Graph.edgenum = int(f.readline().strip())

        for i,line in enumerate(f.readlines()):
            if i == Graph.edgenum:
                Graph.origin, Graph.destn = line.strip().split()
            else:
                v1,v2,c = line.strip().split()
                Graph.generate_graph(str(v1),str(v2),int(c))
    
    return Graph 


if  __name__ == "__main__":
   maxflow()  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值