求最短路徑難道很多人沒有發現網上很多人給出的函數是對無權圖求的麼?默認邊的權值都爲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(<type'list'>, {1: [set([1, 2, 3, 4, 5, 6])]})
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(<function <lambda> at 0x0000000015FEE128>, {1: 0, 2: 1,3: 3, 4: 3, 5: inf, 6: inf}),
2: defaultdict(<function<lambda> at 0x0000000015A49518>, {1: 1, 2: 0, 3: 4, 4: 2, 5: inf, 6:inf}),
3: defaultdict(<function<lambda> at 0x0000000015A497B8>, {1: 3, 2: 4, 3: 0, 4: 4, 5: inf, 6:inf}),
4: defaultdict(<function <lambda>at 0x000000001EDB34A8>, {1: 3, 2: 2, 3: 4, 4: 0, 5: inf, 6:inf}),
5: defaultdict(<function<lambda> at 0x000000001EDB3DD8>, {1: inf, 2: inf, 3: inf, 4: inf, 5:0, 6: 6}),
6: defaultdict(<function<lambda> at 0x000000001EDB3E48>, {1: inf, 2: inf, 3: inf, 4: inf, 5:6, 6: 0})}
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(<function<lambda> at 0x000000001EDB3B38>, {1: 0, 2: 1, 3: 3, 4: 3, 5: inf, 6:inf}),
2: defaultdict(<function<lambda> at 0x000000001EDB3D68>, {1: 1, 2: 0, 3: 4, 4: 2, 5: inf, 6:inf}),
3: defaultdict(<function <lambda>at 0x0000000015FD3438>, {1: 3, 2: 4, 3: 0, 4: 4, 5: inf, 6:inf}),
4: defaultdict(<function<lambda> at 0x0000000015FD3668>, {1: 3, 2: 2, 3: 4, 4: 0, 5: inf, 6:inf}),
5: defaultdict(<function<lambda> at 0x0000000015E52C18>, {1: inf, 2: inf, 3: inf, 4: inf, 5:0, 6: 6}),
6: defaultdict(<function<lambda> at 0x0000000015E52828>, {1: inf, 2: inf, 3: inf, 4: inf, 5:6, 6: 0})})
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