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

运行图
networkx求解最小费用最大流并可视化数据_第1张图片

分析

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是最小费用最大流时,本条边上的流量。


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

你可能感兴趣的:(networkx,图论,可视化,python)