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为 (from,to)(from,to)(from,to) 元组,代表每条边的出发点和目标,value为上面创造图时候的容量和价格。这样可以用字符串操作把它们组合起来,于是有了每条边上的 (capacity,weight)(capacity,weight)(capacity,weight)

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

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


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

### 关于最小生成树算法的可视化展示或工具 对于希望理解最小生成树(Minimum Spanning Tree, MST)算法的工作原理及其应用的人来说,存在多种在线资源和软件工具可以提供帮助。这些工具不仅限于理论解释,还提供了交互式的动画效果来辅助学习者更直观地了解MST算法。 #### 1. 可视化网站 一些专门设计用于教学目的的网页能够动态演示Prim's Algorithm以及Kruskal’s Algorithm这两种常见的构建最小生成树的方法。例如,在[VisuAlgo](https://visualgo.net/en/mst),用户可以通过调整节点之间的权重来自定义图结构,观察不同情况下哪种边会被选入最终形成的最小生成树中[^4]。 #### 2. Python库Matplotlib与NetworkX组合使用 利用Python编程语言中的`matplotlib`绘图库配合`networkx`网络分析包,开发者可以创建自定义图形实现对各种最短路径问题求解过程的可视化表示。下面是一个简单的例子: ```python import matplotlib.pyplot as plt import networkx as nx # 创建无向加权图 G = nx.Graph() edges = [('A', 'B', 7), ('A', 'D', 5), ('B', 'C', 8), ('B', 'D', 9), ('B', 'E', 7), ('C', 'E', 5), ('D', 'E', 15), ('D', 'F', 6), ('E', 'F', 8), ('E', 'G', 9), ('F', 'G', 11)] for edge in edges: G.add_edge(edge[0], edge[1], weight=edge[2]) pos = nx.spring_layout(G) nx.draw_networkx_nodes(G, pos, node_size=700) nx.draw_networkx_edges(G, pos, edgelist=G.edges(), width=6) labels = nx.get_edge_attributes(G,'weight') nx.draw_networkx_labels(G,pos,font_size=20,font_family="sans-serif") nx.draw_networkx_edge_labels(G, pos, edge_labels=labels) plt.show() mst = nx.minimum_spanning_tree(G) print(sorted(mst.edges(data=True))) ``` 这段代码首先建立了一个具有特定权重分布的简单连通图,接着计算该图对应的最小生成树,将其打印出来以便进一步处理或显示。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值