networkx包初探

版权声明:本文为博主原创文章,转载时请附上原文链接。 https://blog.csdn.net/littlely_ll/article/details/81749960

networkx是python的一个包,它是用来复杂网络结构的创建、操作和学习。官网上给它设定的目标为:

  • tools for the study of the structure and dynamics of social, biological, and infrastructure networks,
  • a standard programming interface and graph implementation that is suitable for many applications,
  • a rapid development environment for collaborative, multidisciplinary projects,
    an interface to existing numerical algorithms and code written in C, C++, and FORTRAN,
  • the ability to painlessly slurp in large nonstandard data sets.

构建图

简单图的构建比较简单,首先载入包:

import networkx as nx

构建一个简单图:

nodes = [0,1,2,3,4]
edges = [(0,1),(0,2),(1,2),(1,3),(2,3),(0,4)]

nodes为一个图的顶点,而edges为顶点之间的边,其用一个列表元组表示。
构建一个无向图:

G = nx.Graph()
G.add_nodes_from(nodes)
G.add_edges_from(edges)

构建一个有向图:

DG = nx.DiGraph()
DG.add_nodes_from(nodes)
DG.add_edges_from(edges)

有向图和无向图构建时的行为相似,构建无向图时是nx.Graph, 而构建有向图时是nx.DiGraph,添加结点和边时用的同样的方法。
构建出的有向图和无向图可以绘出:

import matplotlib.pyplot as plt
#绘制无向图
nx.draw(G, with_labels=True, font_weight='bold')
plt.show()

#绘制有向图
nx.draw(DG, with_labels=True, font_weight='bold')
plt.show()

这里写图片描述

这里写图片描述

从中可以看出,构建有向图时,元组的第一个元素为起始点,也就是弧尾,第二个元素为结束点,也就是弧头。

图的遍历

深度优先遍历
深度优先遍历有两种方法,一个是dfs_edges,另一个是edge_dfs,两种方法有所不同,首先看代码
以有向图为例:

list(nx.dfs_edges(DG,0)) #1
list(nx.edge_dfs(DG,0)) #2

结果:
[(0, 1), (1, 2), (2, 3), (0, 4)] #1
[(0, 1), (1, 2), (2, 3), (1, 3), (0, 2), (0, 4)]#2

扫描二维码关注公众号,回复: 5641784 查看本文章

dfs_edgesedge_dfs都是深度遍历方法,其第一个参数为图,第二个参数为一个源结点,返回的都是一个生成器。对于dfs_edges来说,一旦它遍历了源结点所能到达的所有结点它就停止了,而edge_dfs是直到源结点遍历完所有它能到达的边才停止。对比着结果看上面两张图就明白了。另一个与dfs_edges相对应的是广度优先遍历bfs_edges

找到源结点的所有可达结点:
有两种方法,dfs_preorder_nodesdfs_postorder_nodes,第一个参数是构建的图,第二个参数为源结点, 它们返回的都是一个生成器

list(nx.dfs_preorder_nodes(DG,1))#1
list(nx.dfs_postorder_nodes(DG,1))#2

结果:
[1, 2, 3]#1
[3, 2, 1]#2

获取路径

获取两结点间所有简单路径
使用的方法为all_simple_paths,第一个参数为图,第二个和第三个参数分别是源结点和目标结点,第四个参数为截断长度cutoff,默认为None,返回的是一个生成器。

list(nx.all_simple_paths(DG,0,3)#1
list(nx.all_simple_paths(DG,0,3,cutoff=3)#2
list(nx.all_simple_paths(DG,0,3,cutoff=2)#3

[[0, 1, 2, 3], [0, 1, 3], [0, 2, 3]]#1
[[0, 1, 2, 3], [0, 1, 3], [0, 2, 3]]#2
[[0, 1, 3], [0, 2, 3]]#3
all_simple_paths默认返回所有从源结点到目标结点的路径,cutoff参数设置的截断长度不包括源结点

最短路径:
shortest_path(G[, source, target, weight])返回最短路径,如果没有设定sourcetarget,返回一个字典,得到的结果为path[source][target]=[list of nodes in path]

nx.shortest_path(DG)

{0: {0: [0], 1: [0, 1], 2: [0, 2], 3: [0, 1, 3], 4: [0, 4]},
1: {1: [1], 2: [1, 2], 3: [1, 3]},
2: {2: [2], 3: [2, 3]},
3: {3: [3]},
4: {4: [4]}}
一般使用时都是设定源结点和目标结点,所以返回一个最短路径列表:

nx.shortest_path(DG, 0,3)

[0, 1, 3]
DG有多个最短路径,看起来它只返回一个最短路径。
all_shortest_paths返回所有的最短路径,返回一个生成器,但要设定sourcetarget

list(nx.all_shortest_paths(DG, 0,3))

[[0, 1, 3], [0, 2, 3]]

has_path返回布尔值,即是否有从sourcetarget的路径:

nx.has_path(DG,0,3)

True

dijkstra最短路径
dijkstra_path(G, source, target, weight='weight')返回一个最短路径列表:

nx.dijkstra_path(DG, 0,3)

[0, 1, 3]
它也是返回一条路径。

dijkstra_path_length(G, source, target, weight='weight')返回最短路径长度,长度不包括源结点:

nx.dijkstra_path_length(DG, 0,3)

2

绘制图模型

前面介绍了一种绘制方法:

nx.draw(DG, with_labels=True, font_weight='bold')
plt.show()

带坐标的一种:

nx.draw_networkx(DG, with_labels=True, font_weight='bold')
plt.show()

这里写图片描述

按照圆形布局:

nx.draw_circular(DG, with_labels=True, font_weight='bold')

这里写图片描述

随机布局:

nx.draw_random(DG, with_labels=True, font_weight='bold')

这里写图片描述
还有一些其他的布局或自定义布局等。
先到这吧。

猜你喜欢

转载自blog.csdn.net/littlely_ll/article/details/81749960