Networkx常用算法和求最短路徑介紹

 求最短路徑難道很多人沒有發現網上很多人給出的函數是對無權圖求的麼?默認邊的權值都爲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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章