networkx求解最小费用最大流并可视化数据

代码


import networkx as nx
import matplotlib.pyplot as plt
G = nx.DiGraph()#有向图
G.add_edges_from([('s','v1',{'capacity': 8, 'weight': 2}),
                  ('s','v3',{'capacity': 7, 'weight': 8}),
                  ('v1','v3',{'capacity': 5, 'weight': 5}),
                  ('v1','v2',{'capacity': 9, 'weight': 2}),
                  ('v3','v4',{'capacity': 9, 'weight': 3}),
                  ('v2','v3',{'capacity': 2, 'weight': 1}),
                  ('v4','t',{'capacity': 10, 'weight': 7}),
                  ('v2','t',{'capacity': 5, 'weight': 6}),
                  ('v4','v2',{'capacity': 6, 'weight': 4})])#图构造

pos=nx.spring_layout(G)#力导向布局算法默认分配的位置
pos['t'][0]=1;pos['t'][1]=0
pos['s'][0]=-1;pos['s'][1]=0
pos['v1'][0]=-0.33;pos['v1'][1]=1
pos['v3'][0]=-0.33;pos['v3'][1]=-1
pos['v2'][0]=0.33;pos['v2'][1]=1
pos['v4'][0]=0.33;pos['v4'][1]=-1
#pos=nx.spring_layout(G,None,pos={'s': [-1,0],'t': [1,0]},fixed=['s','t'])#初始化时可选定一些节点的初始位置/固定节点

#显示graph
edge_label1 = nx.get_edge_attributes(G,'capacity')
edge_label2 = nx.get_edge_attributes(G,'weight')
edge_label={}
for i in edge_label1.keys():
    edge_label[i]=f'({edge_label1[i]:},{edge_label2[i]:})'
#处理边上显示的(容量,单位价格)

nx.draw_networkx_nodes(G,pos)
nx.draw_networkx_labels(G,pos)
nx.draw_networkx_edges(G,pos)
#nx.draw_networkx_edge_labels(G, pos,edge_label,font_size=15)#显示原图像


mincostFlow = nx.max_flow_min_cost(G, 's', 't')#最小费用最大流
mincost = nx.cost_of_flow(G, mincostFlow)#最小费用的值


for i in mincostFlow.keys():
    for j in mincostFlow[i].keys():
        edge_label[(i,j)]+=',F='+str(mincostFlow[i][j])
#取出每条边流量信息存入边显示值

nx.draw_networkx_edge_labels(G, pos,edge_label,font_size=12)#显示流量及原图
print(mincostFlow)#输出流信息
print(mincost)

plt.axis('on')
plt.xticks([])
plt.yticks([])
plt.show()

运行图
括号内是边权,F=最小费用最大流时的流量

分析

spring_layout后pos得到的是一个key为节点名,value为 [ x , y ] [x,y] [x,y] 的列表,xy表示在plt坐标轴上节点的位置,这样,经过修改实际上是可以手动调整位置的(不调整则layout生成一个力稳定的随机位置,有时候会比较偏,不过图规模较大时还是比较好用的)

edge_label12通过get_edge_attributes获得的是字典,它的key为 ( f r o m , t o ) (from,to) (from,to) 元组,代表每条边的出发点和目标,value为上面创造图时候的容量和价格。这样可以用字符串操作把它们组合起来,于是有了每条边上的 ( c a p a c i t y , w e i g h t ) (capacity,weight) (capacity,weight)

draw_networkx_edge_labels方法暂时没找到让label显示脱离边的办法,只能调整沿着边方向的位置,而不能沿垂直边方向迁移。需要满足edge_label的结构,即 ( f r o m , t o ) (from,to) (from,to)字典的元组,而value是可以自己设定的。

max_flow_min_cost即返回从s到t的最小费用最大流路径。返回一个字典,key是出发顶点,value是另一个字典 T o To To T o To To的key是一些顶点,表示从出发顶点抵达的顶点, T o To To的value是最小费用最大流时,本条边上的流量。


难点从编写网络流算法变成如何可视化了。。。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值