求最短路径难道很多人没有发现网上很多人给出的函数是对无权图求的么?默认边的权值都为1,其实可以按照给定的权重求,文章后面有介绍
Algorithms
https://networkx.readthedocs.io/en/stable/reference/algorithms.html
大概介绍下,选择比较有用的介绍下
In [98]:
fromnetworkx.algorithms import approximation as apxa
In [1]:
importnetworkx as nx
def draw(g): #显示图
if 'plt' not in dir(): #可以查看很多东西,del 模块名 可以删除模块
importmatplotlib.pyplot as plt #可以发现plt只存在函数中,全局中并没有plt
pos=nx.spring_layout(G)
nx.draw(g,pos,arrows=True,with_labels=True,nodelist=G.nodes(),style='dashed',edge_color='b',width=2,\
node_color='y',alpha=0.5)
plt.show()
In [5]:
G=nx.Graph()
G.add_path([1,2,3,4,5,6])
draw(G)
连通性
In [8]:
nx.all_pairs_node_connectivity(G)
Out[8]:
{1: {2:1, 3: 1, 4: 1, 5: 1, 6: 1},
2: {1: 1, 3: 1, 4: 1, 5: 1, 6:1},
3: {1: 1, 2: 1, 4: 1, 5: 1, 6:1},
4: {1: 1, 2: 1, 3: 1, 5: 1, 6:1},
5: {1: 1, 2: 1, 3: 1, 4: 1, 6:1},
6: {1: 1, 2: 1, 3: 1, 4: 1, 5: 1}}
In [110]:
# local_node_connectivity(G, source, target,cutoff=None)
fromnetworkx.algorithms import approximation as approx
G4 =nx.icosahedral_graph()
approx.local_node_connectivity(G4, 0, 6)
Out[110]:
5
In [111]:
draw(G4)
K-components
In [12]:
# k_components(G[, min_density])#Returns theapproximate k-component structure of a graph G.
In [15]:
k_components= apxa.k_components(G)
k_components
Out[15]:
defaultdict(
In [16]:
draw(G)
Clique 团
Clustering
Estimatesthe average clustering coefficient of G.
dominating set
控制集
In [8]:
G=nx.Graph()
G.add_star([1,2,3,4,5])
In [9]:
# min_weighted_dominating_set(G[, weight])
apxa.min_weighted_dominating_set(G)
Out[9]:
{1}
In [10]:
apxa.min_edge_dominating_set(G)
Out[10]:
{(1, 2)}
Independent Set
In [12]:
apxa.maximum_independent_set(G)
#独立集或稳定集是一个图中的一组顶点,没有两个是相邻的。
Out[12]:
{2, 3, 4,5}
Matching
In [13]:
# Given a graph G = (V,E), a matching M in G is a setof pairwise non-adjacent edges;
# that is, no two edges share a common vertex.
In [14]:
apxa.min_maximal_matching(G)
Out[14]:
{(1, 2)}
vertex cover
点覆盖
In [ ]:
# min_weighted_vertex_cover(G[, weight])
In [15]:
apxa.min_weighted_vertex_cover(G)
Out[15]:
{1, 2}
Graphical degree sequence
Testsequences for graphiness.
In [16]:
#判断序列能否构成图
Minimum Spanning Tree
最小生成树
In [19]:
# minimum_spanning_tree(G[, weight])
draw(nx.minimum_spanning_tree(G))
In [20]:
# minimum_spanning_edges(G[, weight, data]) 最小生成树的边
cycle_basis
寻找图中的环
In [3]:
G=nx.Graph()
G.add_cycle([0,1,2,3]) # 0-1-2-3-0
draw(G)
In [5]:
G.add_cycle([4,5,6,7])
draw(G)
In [6]:
nx.cycle_basis(G,0)
Out[6]:
[[1, 2,3, 0], [5, 6, 7, 4]]
simple_cycles
Findsimple cycles (elementary circuits) of a directed graph.
In [8]:
G = nx.DiGraph([(0, 0), (0, 1), (0, 2), (1, 2), (2, 0), (2, 1), (2, 2)])
draw(G)
In [12]:
list(nx.simple_cycles(G))
Out[12]:
[[0, 2],[0, 1, 2], [0], [1, 2], [2]]
find_cycle
没有环回报错
In [14]:
nx.find_cycle(G, orientation='original')#orientation ('original' | 'reverse' |'ignore')
Out[14]:
[(0, 0)]
Distance Measures
1center(G[, e]) Return the center of the graph G. 2 diameter(G[, e]) Return thediameter of the graph G. 3 eccentricity(G[, v, sp]) Return the eccentricity ofnodes in G. 4 periphery(G[, e]) Return the periphery of the graph G. 5radius(G[, e]) Return the radius of the graph G.
Eulerian
欧拉图
In [16]:
# is_eulerian(G) Return True if G is an Eulerian graph, False otherwise.
# eulerian_circuit(G[, source]) Return the edges ofan Eulerian circuit in G.
Matching
In [17]:
# maximal_matching(G) Find a maximal cardinality matching in thegraph.
# max_weight_matching(G[, maxcardinality]) Compute a maximum-weighted matching of G.
Shortest Paths
适用于有向图和无向图
In [45]:
#创建一个用例图:
G=nx.Graph()
dic1 = [(1,2,{'weight':1}),(2,4,{'weight':2}),
(1,3,{'weight':3}),(3,4,{'weight':4}),
(1,4,{'weight':5}),(5,6,{'weight':6})]
G.add_edges_from(dic1)
draw(G)
shortest_path(G, source=None,target=None, weight=None)
forunweighted graphs
In [18]:
# weight (None or string, optional (default = None))– If None, every edge has weight/distance/cost 1.
# If a string, use this edge attribute as the edgeweight. Any edge attribute not present defaults to 1.
In [21]:
#当有多条最短路径时,只返回其中的一条
G=nx.path_graph(5)
draw(G)
In [9]:
nx.shortest_path(G,source=1,target=4)
Out[9]:
[1, 4]
In [18]:
G.clear()
In [28]:
G.add_weighted_edges_from([(0,1,1),(1,2,2),(0,2,0.5)])
nx.shortest_path(G,source=0,target=2)
Out[28]:
[0, 2]
In [25]:
draw(G)
In [19]:
G.add_weighted_edges_from([(0,1,1),(1,2,2),(0,2,15)])
nx.shortest_path(G,source=0,target=2,weight='123')
Out[19]:
[0, 2]
all_shortest_paths(G, source,target, weight=None)
forunweighted graphs
In [1]:
fromIPython.external import mathjax; mathjax.install_mathjax()
Downloading mathjax source from https://github.com/mathjax/MathJax/archive/2.4.0.tar.gz
Extracting to C:\Users\COOKIE\.ipython\nbextensions\mathjax
Out[1]:
0
shortest_path_length(G, source=None,target=None, weight=None)
forunweighted graphs
In [3]:
# Raises:
# NetworkXNoPath – If no path exists between sourceand target.
average_shortest_path_length(G,weight=None)
In [13]:
# nx.average_shortest_path_length(G) #要求连接图
g1=nx.Graph(G.subgraph([1,2,3,4]))
nx.average_shortest_path_length(g1)
#计算公式是:sum(s,t属于v)d(s,t)/(n*(n-1))
Out[13]:
1.1666666666666667
Simple Paths
all_simple_paths(G, source, target[,cutoff])
shortest_simple_paths(G, source,target[, ...])
Generateall simple paths in the graph G from source to target, starting from shortestones.
In [6]:
G = nx.cycle_graph(7)
paths = list(nx.shortest_simple_paths(G, 0, 3))
print(paths)
[[0, 1,2, 3], [0, 6, 5, 4, 3]]
has_path
In [8]:
nx.has_path(G, source=0, target=3)
Out[8]:
True
single_source_shortest_path(G,source, cutoff=None)
forunweighted graphs
In [16]:
nx.single_source_shortest_path(G,2)
Out[16]:
{0: [2,0],
1: [2, 1],
2: [2],
3: [2, 3],
4: [2, 4],
5: [2, 4, 5],
6: [2, 0, 6]}
In [38]:
G.edges(data=True)
Out[38]:
[(0, 1,{'weight': 1}), (0, 2, {'weight': 15}), (1, 2, {'weight': 3})]
single_source_shortest_path_length(G,source)
predecessor(G, source[, target,cutoff, ...])
forunweighted graphs
In [14]:
nx.predecessor(G,1)
Out[14]:
{1: [],2: [1], 3: [1], 4: [1]}
Shortest path algorithms for weighed graphs.
dijkstra_path(G, source, target[,weight])
In [16]:
nx.dijkstra_path(G,1,4) #五权重的是1-4
Out[16]:
[1, 2, 4]
dijkstra_path_length(G, source,target[, weight])
In [17]:
nx.dijkstra_path_length(G,1,4)
Out[17]:
3
single_source_dijkstra_path(G,source, cutoff=None, weight='weight')
In [20]:
p=nx.single_source_dijkstra_path(G,1)
In [22]:
p[4] #1-4的最短路径
Out[22]:
[1, 2, 4]
single_source_dijkstra_path_length(G,source)
all_pairs_dijkstra_path(G,cutoff=None, weight='weight')
In [26]:
p1=nx.all_pairs_dijkstra_path(G)
p1[1][4]
Out[26]:
[1, 2, 4]
all_pairs_dijkstra_path_length(G,cutoff=None, weight='weight')
single_source_dijkstra(G, source,target=None, cutoff=None, weight='weight')
In [28]:
length,path=nx.single_source_dijkstra(G,1,4) # shortest paths and lengths in a weighted graph G.
bidirectional_dijkstra(G, source, target,weight='weight')
Dijkstra’salgorithm for shortest paths using bidirectional(双向) search.
In [30]:
length,path=nx.bidirectional_dijkstra(G,1,4)
path
Out[30]:
[1, 2, 4]
In [35]:
length,path=nx.bidirectional_shortest_path(G,1,4) # for unweighted graph
length,path
Out[35]:
(1, 4)
bellman_ford(G, source, weight='weight')
Thealgorithm has a running time of O(mn) where n is the number of nodes and m isthe number of edges. It is slower than Dijkstra but can handle negative edgeweights.
In [36]:
pre,dist=nx.bellman_ford(G,1)
In [37]:
pre
Out[37]:
{1: None,2: 1, 3: 1, 4: 2}
In [38]:
dist
Out[38]:
{1: 0, 2:1, 3: 3, 4: 3}
In [39]:
#当有负权重的环时,报错NetworkXUnbounded
In [43]:
fromnose.tools import assert_raises
G1 = nx.cycle_graph(5, create_using = nx.DiGraph())
G1[1][2]['weight'] = -7
assert_raises(nx.NetworkXUnbounded, nx.bellman_ford, G1, 0)
negative_edge_cycle(G,weight='weight')
ReturnTrue if there exists a negative edge cycle anywhere in G.
In [44]:
nx.negative_edge_cycle(G1)
Out[44]:
True
johnson(G, weight='weight')
在权重图中用Johnson算法计算所有最短路径的权重
even forgraphs with negative weights.通过转换成正权图来使用迪杰斯特拉来计算最短路径 O(V^2 logV + V E)
In [46]:
nx.johnson(G)
Out[46]:
{1: {1:[1], 2: [1, 2], 3: [1, 3], 4: [1, 2, 4]},
2: {1: [2, 1], 2: [2], 3: [2, 1, 3], 4:[2, 4]},
3: {1: [3, 1], 2: [3, 1, 2], 3: [3], 4:[3, 4]},
4: {1: [4, 2, 1], 2: [4, 2], 3: [4, 3],4: [4]},
5: {5: [5], 6: [5, 6]},
6: {5: [6, 5], 6: [6]}}
In [67]:
G3=nx.DiGraph()
G3.add_weighted_edges_from([('0', '3', 3), ('0', '1', -5),\
('0', '2', 2), ('1', '2', 4), ('2', '3', 1)])
In [68]:
nx.johnson(G3) #负数也是越小越好
Out[68]:
{'0':{'0': ['0'],
'1': ['0', '1'],
'2': ['0', '1', '2'],
'3': ['0', '1', '2', '3']},
'1': {'1': ['1'], '2': ['1', '2'], '3':['1', '2', '3']},
'2': {'2': ['2'], '3': ['2','3']},
'3': {'3': ['3']}}
In [79]:
# nx.dijkstra_path(G,0,2) 报错的
In [76]:
nx.draw(G3,with_labels=True,alpha=0.5)
importmatplotlib.pyplot as plt
plt.show()
Floyd’s algorithm is appropriate for finding shortestpaths in dense graphs or graphs with negative weights when Dijkstra’s algorithmfails.
Thisalgorithm can still fail if there are negative cycles. It has running timeO(n^3) with running space of O(n^2).
Dense Graphs
In [81]:
nx.floyd_warshall(G) #返回距离
Out[81]:
{1:defaultdict(
2: defaultdict(
3: defaultdict(
4: defaultdict(
5: defaultdict(
6: defaultdict(
floyd_warshall_numpy(G,nodelist=None, weight='weight')
In [83]:
#返回一个最短距离矩阵
nx.floyd_warshall_numpy(G)
Out[83]:
matrix([[ 0., 1., 3., 3., inf, inf],
[ 1., 0., 4., 2., inf, inf],
[ 3., 4., 0., 4., inf, inf],
[ 3., 2., 4., 0., inf, inf],
[ inf, inf, inf, inf, 0., 6.],
[ inf, inf, inf, inf, 6., 0.]])
floyd_warshall_predecessor_and_distance(G,weight='weight')
In [87]:
nx.floyd_warshall_predecessor_and_distance(G, weight='weight')
Out[87]:
({1: {2:1, 3: 1, 4: 2},
2: {1: 2, 3: 1, 4: 2},
3: {1: 3, 2: 1, 4: 3},
4: {1: 2, 2: 4, 3: 4},
5: {6: 5},
6: {5: 6}},
{1: defaultdict(
2: defaultdict(
3: defaultdict(
4: defaultdict(
5: defaultdict(
6: defaultdict(
In [28]:
float('inf')
Out[28]:
inf
A* Algorithm
forweighted graph
astar_path(G, source, target,heuristic=None, weight='weight')
In [89]:
nx.astar_path(G,1,4)
Out[89]:
[1, 2, 4]
In [90]:
nx.astar_path_length(G,1,4)
Out[90]:
3
以上是最短距离算法,下面是遍历算法
Depth First Search
In [93]:
# dfs_edges(G[, source]) Produce edges in a depth-first-search(DFS).
# dfs_tree(G, source) Return oriented tree constructed from adepth-first-search from source.
# dfs_predecessors(G[, source]) Return dictionary ofpredecessors in depth-first-search from source.
# dfs_successors(G[, source]) Return dictionary of successors indepth-first-search from source.
# dfs_preorder_nodes(G[, source]) Produce nodes in a depth-first-searchpre-ordering starting from source.
# dfs_postorder_nodes(G[, source]) Produce nodes in a depth-first-searchpost-ordering starting from source.
# dfs_labeled_edges(G[, source]) Produce edges in a depth-first-search (DFS)labeled by type.
# edge_dfs(G[, source, orientation])
Breadth First Search
In [96]:
# bfs_edges(G, source[, reverse]) Produce edges in a breadth-first-searchstarting at source.
# bfs_tree(G, source[, reverse]) Return an oriented tree constructed from ofa breadth-first-search starting at
# source.
# bfs_predecessors(G, source) Return dictionary of predecessors inbreadth-first-search from source.
# bfs_successors(G, source) Return dictionary ofsuccessors in breadth-first-search from source.
Tree
https://networkx.readthedocs.io/en/stable/reference/algorithms.tree.html