python學習(32)---networkx


一、networkx介紹

NetworkX提供圖形(或網絡)的數據結構以及圖形算法,生成器和繪圖工具。

函數,方法和變量名是lower_case_underscore(小寫,下划線表示單詞之間的空格)。

 

二、基礎

1、導入模塊

import networkx as nx

2、圖/網絡

圖的類型

  • Graph:無多重邊無向圖。忽略兩個節點之間的多個邊,允許節點自身成環。
  • DiGraph:無多重邊有向圖
  • MultiGraph:有多重邊無向圖,允許在成對的節點之間存在多個無向邊。
  • MultiDIGraph:有多重邊有向圖

所有圖類均允許任何哈希對象作為節點。可哈希對象包括字符串,元組,整數等。如權重和標簽之類的任意邊屬性都可以與邊相關聯。

   G = nx.Graph()#創建空的網絡圖
   G = nx.DiGraph()
   G = nx.MultiGraph()
   G = nx.MultiDiGraph()

圖的創建:(三種方式)

  1. 圖生成器,如例如binomial_graph和powerlaw_graph
  2. 從文本源中加載數據,如nx.read_adjlist
  3. 自主創建空圖並添加點和邊

 

3、節點和邊

  • 節點:整數 / 字符串 / 描述節點的數據結構
  • 邊:關鍵字/值對【可使用除'weight'以外的任何關鍵字來命名屬性,可通過此關鍵字查詢邊】

(1)添加:

#添加點
G.add_node('a')#添加點a
G.add_node(1,1)#用坐標來添加點
G.add_nodes_from([2, 3]) #添加一列表的節點

##或者 添加一系列迭代器
H = nx.path_graph(10)
G.add_nodes_from(H)
G.add_node(math.cos) # any hashable can be a node

#添加邊
G.add_edge('x','y')#添加邊,起點為x,終點為y,默認邊值為1
G.add_edge(1,3,weight=0.9)
#添加邊,起點為1,終點為2,權重值為0.9
G.add_edge('y','x',function=math.cos) #Edge attributes can be anything
G.add_edges_from([(1, 2), (1, 3)])
G.add_weight_edges_from([('x','y',1.0)])#第三個輸入量為權值
#也可以
list = [[('a','b',5.0),('b','c',3.0),('a','c',1.0)]
G.add_weight_edges_from([(list)])
 

(2) 刪除:

  g.remove_node()
  g.remove_nodes_from()
  g.remove_edge()
  g.remove_edges_from()
  g.remove_edge( 1,2);   #刪除node1和node2之間的edge,自此node1和node2不再為相鄰的node
  g.remove_edges_from(edges_list)
##刪除所有的點和邊
G.clear()

##刪除邊的屬性
del g[1][2][‘name‘]

(3)查看:

G.number_of_nodes()
#8,節點數量
G.number_of_edges()
#3,邊數量
 #獲取一個Graph對象中的node數組或者edge數組
  g.nodes();
  g.edges();
 
 #查看邊的數據
g[1][2]  #方式1,查看邊(1,2)的屬性,如可以有權重,關系,顏色等,輸出結果為{'weight':1}
g.get_edge_data(1,2) #方式2,輸出結果為{‘weight‘: 0.125, ‘relationship‘: ‘renew‘, ‘color‘: ‘blue‘}
 
         
# 查看鄰居
g.neighbors(1);   #獲取與node為1相鄰的node是節點,是一個迭代器

#查看邊是否存在
g.has_edge(1,2)
 

 

 輸出結果:

2
3
4

(4)更新:

通過邊來更新邊的屬性,由兩種方式,一種是使用update函數,一種是通過屬性賦值來實現:

g[1][2][‘weight‘] = 4.7
g.edge[1][2][‘weight‘] = 4
g[1][2].update({"weight": 4.7})
g.edges[1, 2].update({"weight": 4.7})   

 

4、圖形的顯示

需要導入matplotlib
import matplotlib.pyplot as plt

nx.draw(G)
#nx.draw_networkx(G)

plt.show()

#若想讓圖形更精美
nx.draw(G,pos = nx.random_layout(G),node_color = 'b',edge_color = 'r',with_labels = True,font_size =18,node_size =20)

pos 指的是布局 主要有spring_layout , random_layout,circle_layout,shell_layout。node_color指節點顏色,有rbykw ,同理edge_color.
with_labels指節點是否顯示名字,size表示大小,font_color表示字的顏色。

5、基本操作

import networkx as nx

oo = float('inf')

# 創建無向圖
G = nx.Graph()
G.add_node(1) # 添加節點1
G.add_edge(2,3) # 添加節點2,3並鏈接23節點
print(G.nodes, G.edges, G.number_of_nodes(), G.number_of_edges())

# 創建有向圖
G = nx.DiGraph() 
G.add_edge(2, 3)
G.add_edge(3, 2)
G.to_undirected()  # 轉換成無向圖
print(G.edges)

# 加權圖
G = nx.DiGraph()
G.add_weighted_edges_from([(0,1,3.0), (1,2,7.5)]) # 給01邊加權3, 12邊加權7.5
print(G.get_edge_data(1,2))  # 獲得12邊的屬性

G.add_weighted_edges_from([(2,3,5)], weight='color')
print(G.edges.data())

G.node[1]['size'] = 10
print(G.nodes.data())


import matplotlib.pyplot as plt

g_data = [(1, 2, 6), (1, 3, 1), (1, 4, 5),
          (2, 3, 5),  (2, 5, 3),
          (3, 4, 5), (3, 5, 6), (3, 6, 4), (4, 6, 2),
          (5, 6, 6)]

# 最小生成樹
g = nx.Graph()
g.add_weighted_edges_from(g_data)
tree = nx.minimum_spanning_tree(g, algorithm='prim')
print(tree.edges(data=True))

# 最短路徑
G = nx.path_graph(5)  # 0-1-2-3-4鏈
print(nx.dijkstra_path(G, 0, 4))

# 所有節點之間的最短路徑
G = nx.Graph()
G.add_weighted_edges_from(g_data)
gen = nx.all_pairs_shortest_path(G)
print(dict(gen))

# 各點之間可達性
G = nx.Graph()
G.add_weighted_edges_from(g_data)
print(nx.communicability(G))

# 獲得圖中非連通點的列表
G = nx.Graph()
G.add_edge(1,2)
G.add_node(3)
print(list(nx.isolates(G)))

# 遍歷
G = nx.Graph()
G.add_weighted_edges_from(g_data)
d_gen = nx.dfs_edges(G,1)  #  按邊深度搜索, 1為起點
b_gen = nx.bfs_edges(G,1)
print(list(d_gen), list(b_gen))
print(nx.dfs_tree(G,1).nodes())  # 按點深搜


from networkx.algorithms.flow import shortest_augmenting_path
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_edge('x','a', capacity=3.0)
G.add_edge('x','b', capacity=1.0)
G.add_edge('a','c', capacity=3.0)
G.add_edge('b','c', capacity=5.0)
G.add_edge('b','d', capacity=4.0)
G.add_edge('d','e', capacity=2.0)
G.add_edge('c','y', capacity=2.0)
G.add_edge('e','y', capacity=3.0)

# 將參數畫到圖上
pos = nx.spring_layout(G)
capacity = nx.get_edge_attributes(G, 'capacity')
# nx.draw_networkx_nodes(G, pos)
# nx.draw_networkx_edges(G, pos)
# nx.draw_networkx_labels(G, pos)
# nx.draw_networkx_edge_labels(G,pos,capacity)

# 最大流
flow_value, flow_dict = nx.maximum_flow(G,'x', 'y', flow_func=shortest_augmenting_path)
print(flow_value, flow_dict)
# plt.show()


# 最小成本流
G = nx.DiGraph()
G.add_node('a', demand = -5)
G.add_node('d', demand = 5)
G.add_edge('a', 'b', weight = 3, capacity = 4)
G.add_edge('a', 'c', weight = 6, capacity = 10)
G.add_edge('b', 'd', weight = 1, capacity = 9)
G.add_edge('c', 'd', weight = 2, capacity = 5)
flow_cost, flow_dict = nx.capacity_scaling(G)
print(flow_cost, flow_dict)

# 歐拉回路  一個無向圖G,一條路徑經過圖G的每一條邊,且僅經過一次,這條路徑稱為歐拉路徑.如果起點和終點同一點,則為歐拉回路
# 無向圖:每個頂點的度數都是偶數則存在歐拉回路
# 有向圖:每個頂點的入度都等於出度則存在歐拉回路
DG = nx.DiGraph({0: [3], 1: [2], 2: [3], 3: [0, 1]})
G = nx.Graph({0: [1,2], 1: [0,2], 2: [0,1,3,4], 3: [2,4], 4:[2,3]})
print(nx.is_eulerian(DG))
print(nx.is_eulerian(G))
print(list(nx.eulerian_circuit(DG)))
print(list(nx.eulerian_circuit(G)))

# 最小點割集
node_cut = nx.minimum_node_cut(G, flow_func=shortest_augmenting_path)
print(node_cut)

# 對於帶權無向圖邊切割,得到最小切割權之和,以及兩個分離區域
G = nx.Graph()
G.add_edge('x','a', weight=3)
G.add_edge('x','b', weight=1)
G.add_edge('a','c', weight=3)
G.add_edge('b','c', weight=5)
G.add_edge('b','d', weight=4)
G.add_edge('d','e', weight=2)
G.add_edge('c','y', weight=2)
G.add_edge('e','y', weight=3)

cut_value, partition = nx.stoer_wagner(G)
print(cut_value, partition)

# 最大權重匹配 匈牙利、KM算法
G = nx.Graph()
G.add_weighted_edges_from([('A', 'a', 3), ('A', 'c', 4), ('B', 'a', 2), ('B', 'b', 1), ('B', 'c', 3), ('C', 'c', 5)])
print(nx.max_weight_matching(G))

# 拓撲排序
G = nx.DiGraph()
G.add_edge('x','a', weight=3)
G.add_edge('a','c', weight=3)
G.add_edge('b','c', weight=5)
G.add_edge('b','d', weight=4)
G.add_edge('d','e', weight=2)
G.add_edge('c','y', weight=2)
G.add_edge('e','y', weight=3)
print(list(nx.topological_sort(G)))

# 最小成本最大流
G = nx.DiGraph()
G.add_edge('a', 'b', weight = 3, capacity = 4)
G.add_edge('a', 'c', weight = 6, capacity = 10)
G.add_edge('b', 'd', weight = 1, capacity = 9)
G.add_edge('c', 'd', weight = 2, capacity = 5)
print(nx.max_flow_min_cost(G, 'a', 'd'))


#復雜網絡生成
# ER隨機圖   # 隨機生成20個節點,節點間的連接概率都是0.2
# ER = nx.random_graphs.erdos_renyi_graph(20, 0.2)
# pos = nx.shell_layout(ER)
# nx.draw(ER, pos, with_labels=False,edge_color='b', alpha=0.3, node_size=30)
# plt.show()

# WS小世界網絡  生成一個含有n個節點、每個節點有k個鄰居、以概率p隨機化重連邊的WS小世界網絡。
WS = nx.random_graphs.watts_strogatz_graph(20, 4, 0.3)
pos = nx.circular_layout(WS)
nx.draw(WS, pos, with_labels=False, node_size=30, edge_color='b', alpha=0.3)
plt.show()


# BA無標度網絡 生成一個含有n個節點、每次加入m條邊的BA無標度網絡
# BA = nx.random_graphs.barabasi_albert_graph(10,2)
# pos = nx.spring_layout(BA)
# nx.draw(BA, pos, with_labels=False, node_size=30, edge_color='b', alpha=0.3)
# plt.show()

# 擴展BA無標度網絡  節點數,添加新邊數,兩點間添加邊的概率,邊重連的概率
# ExBA = nx.random_graphs.extended_barabasi_albert_graph(200, 4, 0.4, 0.2)
# pos = nx.spring_layout(ExBA)
# nx.draw(ExBA, pos, with_labels=False, node_size=30, edge_color='b', alpha=0.3)
# plt.show()

 

參考文獻:

networkx整理

Tutorial

Python3畫圖系列——NetworkX初探(案例)

Python包 - networkx

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM