数学建模社区-数学中国
标题: Python小白的数学建模课-图论的基本概念 [打印本页]
作者: 1047521767 时间: 2021-10-30 21:36
标题: Python小白的数学建模课-图论的基本概念
Python小白的数学建模课-图论的基本概念8 b0 r$ e: g6 `" N/ F k
- o [$ |4 D+ |/ i6 Z+ i
- 图论中所说的图,不是图形图像或地图,而是指由顶点和边所构成的图形结构。
- 图论不仅与拓扑学、计算机数据结构和算法密切相关,而且正在成为机器学习的关键技术。
- 本系列结合数学建模的应用需求,来介绍 NetworkX 图论与复杂网络工具包的基本功能和典型算法。& V6 C6 B& ]: ~3 I9 B9 w
0 D% |2 Q. _3 {$ o0 Y6 g; ~6 e- E
1. 图论1.1 图论是什么
; f' \9 z$ Y( O1 X- D3 d- Y图论〔Graph Theory〕以图为研究对象,是离散数学的重要内容。图论不仅与拓扑学、计算机数据结构和算法密切相关,而且正在成为机器学习的关键技术。+ Q$ u0 _' B3 C) q
$ {- D3 [* s$ x1 T) n$ w
图论中所说的图,不是指图形图像(image)或地图(map),而是指由顶点(vertex)和连接顶点的边(edge)所构成的关系结构。
# z) T& Y, ~& m7 ]2 s/ I* t/ P+ ] K, D, i8 D+ ]
图提供了一种处理关系和交互等抽象概念的更好的方法,它还提供了直观的视觉方式来思考这些概念。: _1 Q, f/ b' S6 u- Y. U4 E8 D
+ O! x5 v5 X7 O+ W* L1.2 NetworkX 工具包$ b& R \. A7 q& F" m- Z) b
NetworkX 是基于 Python 语言的图论与复杂网络工具包,用于创建、操作和研究复杂网络的结构、动力学和功能。
) s5 c' B Z( y3 ]$ Z$ _: B1 J: r; R5 ^
NetworkX 可以以标准和非标准的数据格式描述图与网络,生成图与网络,分析网络结构,构建网络模型,设计网络算法,绘制网络图形。3 e N# a& E" v: \$ g
/ D. o) G' p- G' oNetworkX 提供了图形的类、对象、图形生成器、网络生成器、绘图工具,内置了常用的图论和网络分析算法,可以进行图和网络的建模、分析和仿真。
- b1 K6 [5 H: F8 x2 @; ^0 Q
+ s0 X4 s9 W0 s* g v/ w' DNetworkX 的功能非常强大和庞杂,所涉及内容远远、远远地超出了数学建模的范围,甚至于很难进行系统的概括。本系列结合数学建模的应用需求,来介绍 NetworkX 图论与复杂网络工具包的基本功能和典型算法。( o0 U, ]5 p: X
" H+ }# M* _2 N7 O9 [

0 t( ~( W! t R9 M/ D: t2、图、顶点和边的创建与基本操作# A. e( F/ t' H2 |8 ] e
图由顶点和连接顶点的边构成,但与顶点的位置、边的曲直长短无关。
Networkx 支持创建简单无向图、有向图和多重图;内置许多标准的图论算法,节点可为任意数据;支持任意的边值维度,功能丰富,简单易用。
2.1 图的基本概念
7 d; f( ]8 O5 W- Z% v2 c& {9 E% W; h图(Graph):图是由若干顶点和连接顶点的边所构成关系结构。
2 N, k5 D) }1 I8 S顶点(Node):图中的点称为顶点,也称节点。
( v( _- Z3 _! k4 h4 g1 t2 w边(Edge):顶点之间的连线,称为边。
) S5 _7 o n4 H! H1 R( v% t, A平行边(Parallel edge):起点相同、终点也相同的两条边称为平行边。
6 |' n$ Z6 p: c: w1 a d循环(Cycle):起点和终点重合的边称为循环。6 @8 m2 c. u9 i# r2 P& x$ v5 d
有向图(Digraph):图中的每条边都带有方向,称为有向图。: {) k/ s' ], Y
无向图(Undirected graph):图中的每条边都没有方向,称为无向图。$ `4 ^' Y& |! j" S. c$ ]
赋权图(Weighted graph):图中的每条边都有一个或多个对应的参数,称为赋权图。该参数称为这条边的权,权可以用来表示两点间的距离、时间、费用。 d. I, h% g$ H, b. q, J9 `
度(Degree):与顶点相连的边的数量,称为该顶点的度。$ J0 z K: l5 w' @6 b7 Q2 T
; g) |( Y5 Z/ [# r2.2 图、顶点和边的操作
3 r. ^* N1 e) UNetworkx很容易创建图、向图中添加顶点和边、从图中删除顶点和边,也可以查看、删除顶点和边的属性。
! X8 h' i' E6 @4 z7 b5 h) s+ n0 C
0 x' u. X) g; {$ P2.2.1 图的创建Graph() 类、DiGraph() 类、MultiGraph() 类和 MultiDiGraph() 类分别用来创建:无向图、有向图、多图和有向多图。定义和例程如下:/ M" I5 ?" }, E- K0 S0 X- F
, y' o, A. C) k
class Graph(incoming_graph_data=None, **attr)* O9 h: w; _! F
import networkx as nx # 导入 NetworkX 工具包. L- A/ S5 Y0 ]% e
# I7 i- q) M/ q7 d! J3 b
# 创建 图
' ], a1 K' k8 \4 B3 \G1 = nx.Graph() # 创建:空的 无向图1 K5 y2 d p Y& P* B3 c
G2 = nx.DiGraph() #创建:空的 有向图2 D5 k) [' k) {) F# {
G3 = nx.MultiGraph() #创建:空的 多图) g( Y" h/ \3 R* S7 u' O0 {
G4 = nx.MultiDiGraph() #创建:空的 有向多图! p X. l, v( ~5 w+ [
: f1 a9 F! B7 Z! [* \2 r9 C$ |
5 A/ ~! V" ^. m# N! ^1 q+ R2.2.2 顶点的添加、删除和查看
0 Z& R& Z" e6 ^( z% [; t2 k图的每个顶点都有唯一的标签属性(label),可以用整数或字符类型表示,顶点还可以自定义任意属性。
顶点的常用操作:添加顶点,删除顶点,定义顶点属性,查看顶点和顶点属性。定义和例程如下:
0 K; i0 I' s0 E& f" S9 |
Graph.add_node(node_for_adding, **attr)
) H" g4 E, u- O! C; c* TGraph.add_nodes_from(nodes_for_adding, **attr) g b! Q! j7 Q) d
Graph.remove_node(n)5 E7 c2 c' o m- K; ^
Graph.remove_nodes_from(nodes)1 s9 q, M$ Z6 R( L0 S- M1 u
+ X& M" r2 u. h# 顶点(node)的操作
3 x/ H1 Z% u7 S5 d' R7 H2 o# 向图中添加顶点5 i/ p0 p l' A4 n& W7 V9 T& w
G1.add_node(1) # 向 G1 添加顶点 12 B1 z- f8 c! q. ]( ~+ P4 K3 [
G1.add_node(1, name='n1', weight=1.0) # 添加顶点 1,定义 name, weight 属性
1 i- Y* }9 J8 h8 `! Z' ?: jG1.add_node(2, date='May-16') # 添加顶点 2,定义 time 属性 a& h8 a; K. b/ i( |
G1.add_nodes_from([3, 0, 6], dist=1) # 添加多个顶点,并定义属性
" `) o8 P3 t$ Z7 N. ]8 j ?G1.add_nodes_from(range(10, 15)) # 向图 G1 添加顶点 10~14
# i: q9 c& ~. m( |9 t! Z
: b# `$ [8 ~* L0 |5 j/ G# 查看顶点和顶点属性/ H/ ~/ p h" j
print(G1.nodes()) # 查看顶点列表
3 v, s$ b, U" _! r1 `2 v# [1, 2, 3, 0, 6, 10, 11, 12, 13, 14]/ O; L, p1 M2 A" c# E7 Y: m- Y% }
print(G1._node) # 查看顶点属性3 V' ~1 D$ c; J' [
# {1: {'name': 'n1', 'weight': 1.0}, 2: {'date': 'May-16'}, 3: {'dist': 1}, 0: {'dist': 1}, 6: {'dist': 1}, 10: {}, 11: {}, 12: {}, 13: {}, 14: {}}( Q8 n+ d; |+ Q: {- x6 f
1 ?: d, @7 C& Q O5 x# 从图中删除顶点
( T& t7 D9 V8 p9 b1 cG1.remove_node(1) # 删除顶点
# e6 y/ u7 W4 J) j+ }/ jG1.remove_nodes_from([1, 11, 13, 14]) # 通过顶点标签的 list 删除多个顶点
. m, `) s- e5 J* A, p: s8 h( Iprint(G1.nodes()) # 查看顶点
% [* j' v4 Y! Y. p% Z8 ^# [2, 3, 0, 6, 10, 12] # 顶点列表# }0 F9 Y5 u" M
2.2.3 边的添加、删除和查看边是两个顶点之间的连接,在 NetworkX 中 边是由对应顶点的名字的元组组成 e=(node1,node2)。边可以设置权重、关系等属性。
边的常用操作:添加边,删除边,定义边的属性,查看边和边的属性。向图中添加边时,如果边的顶点是图中不存在的,则自动向图中添加该顶点。
Graph.add_edge(u_of_edge, v_of_edge, **attr)
: H3 j- r- g. g0 l7 w( C% T( hGraph.add_edges_from(ebunch_to_add, **attr)& b7 l0 i2 X" W! s& D; L* e
Graph.add_weighted_edges_from(ebunch_to_add, weight=‘weight’, **attr); _ G4 ^- G# K) O- w" C' V8 [
9 m& C8 X/ t y0 T" B4 G- U
# 边(edge)的操作5 N5 f* q5 F- _% Z" I9 j. f% r/ @
# 向图中添加边/ O& A/ x4 [3 k, P: l% t H0 e9 t
G1.add_edge(1,5) # 向 G1 添加边,并自动添加图中没有的顶点; ~) I4 m& i2 A; D
G1.add_edge(0,10, weight=2.7) # 向 G1 添加边,并设置边的属性
# {3 c# I4 s8 QG1.add_edges_from([(1,2,{'weight':0}), (2,3,{'color':'blue'})]) # 向图中添加边,并设置属性3 a0 s k: J& ` R' j2 f
G1.add_edges_from([(3,6),(1,2),(6,7),(5,10),(0,1)]) # 向图中添加多条边
% z# c- x* O9 f* J8 k. g' tG1.add_weighted_edges_from([(1,2,3.6),[6,12,0.5]]) # 向图中添加多条赋权边: (node1,node2,weight)
$ J: L/ h' M7 O2 u$ Mprint(G1.nodes()) # 查看顶点
; v, h: g! e$ F5 P* n# [2, 3, 0, 6, 10, 12, 1, 5, 7] # 自动添加了图中没有的顶点 Q2 x2 L" o+ w5 \: B' Y$ K0 g W; w
6 p4 l4 f3 D: a- `* R# 从图中删除边
3 Z# Q; ?! M5 H6 d5 A/ ]) e) OG1.remove_edge(0,1) # 从图中删除边 0-1* `. D- U. |- _1 R' X4 I- h
G1.remove_edges_from([(2,3),(1,5),(6,7)]) # 从图中删除多条边
+ i6 g" @. C3 U! h3 N" U8 W% ]3 ~+ _6 I' q( |. Z( x0 {( j
# 查看 边和边的属性
p% Q& r( s1 U8 b3 ^6 A2 V Gprint(G1.edges) # 查看所有的边
2 e$ |1 [9 i8 i7 D: n* {[(2, 1), (3, 6), (0, 10), (6, 12), (10, 5)]
8 ]# ^, E( M, F; `; X. Dprint(G1.get_edge_data(1,2)) # 查看指定边的属性, \5 q/ O" i- s. P4 M0 y
# {'weight': 3.6}
8 L9 x8 O L) y, Y, j+ M7 Oprint(G1[1][2]) # 查看指定边的属性4 r! c$ f" p2 }% S9 T: N
# {'weight': 3.6}, D/ h5 H* |& F9 Z; ^7 B) B! h/ _ o
print(G1.edges(data=True)) # 查看所有边的属性9 A& O: z& X4 ]2 l
# [(2, 1, {'weight': 3.6}), (3, 6, {}), (0, 10, {'weight': 2.7}), (6, 12, {'weight': 0.5}), (10, 5, {})]5 j# q$ ]" c( G% n$ S$ {- k
' v3 ~1 }+ X+ F4 N# a0 k3 R x2.2.4 查看图、顶点和边的信息
: X* |- }8 @; [, ?0 Z; ^% J6 a4 U$ a( P. z( N* J
# 查看图、顶点和边的信息; _; y0 w4 G" G4 X5 {
print(G1.nodes) # 返回所有的顶点 [node1,...]. {4 D! K: m4 P* L
# [2, 3, 0, 6, 10, 12, 1, 5, 7]: a4 t9 r% R. f; [( R! l
print(G1.edges) # 返回所有的边 [(node1,node2),...]9 \" d" j. e) t, c
# [(2, 1), (3, 6), (0, 10), (6, 12), (10, 5)]' V- @, D/ k" \ | U% N
print(G1.degree) # 返回各顶点的度 [(node1,degree1),...]
/ ~5 ^8 @+ }* c* |1 }) Q& Z- t# [(2, 1), (3, 1), (0, 1), (6, 2), (10, 2), (12, 1), (1, 1), (5, 1), (7, 0)]
; m8 n1 c) O* O# e9 {2 q9 eprint(G1.number_of_nodes()) # 返回顶点的数量
7 ^: r0 N1 A6 I5 d3 }* u- U# 94 ~+ ^2 |1 B6 j4 K' F
print(G1.number_of_edges()) # 返回边的数量
2 c' R4 G. I: H y6 s- q# 5
2 N( M; e" G' ~. k/ d4 cprint(G1[10]) # 返回与指定顶点相邻的所有顶点的属性1 Z! E; |: g, i% l1 t
# {0: {'weight': 2.7}, 5: {}}# o& r ?! H# Y
print(G1.adj[10]) # 返回与指定顶点相邻的所有顶点的属性
6 F: @9 ]5 D2 p. _$ _# {0: {'weight': 2.7}, 5: {}}5 v" T: a, `3 L
print(G1[1][2]) # 返回指定边的属性
0 q( A& N$ q0 X# L* f" }# {'weight': 3.6}
* p( y# {* k0 @! R. e, p; jprint(G1.adj[1][2]) # 返回指定边的属性0 w; k5 ~5 y$ w* B/ z% X$ c ]
# {'weight': 3.6}' v% p4 N6 Z2 x0 z3 p' `; A! x* P* @6 F
print(G1.degree(10)) # 返回指定顶点的度
% H- g6 v% b, @/ X" }# 2
2 K! ?1 y! h" N7 C% W n& c# C
' H8 o2 r4 x, u0 b4 Q' _- xprint('nx.info:',nx.info(G1)) # 返回图的基本信息
/ @/ f/ T; ^5 A, F/ ~print('nx.degree:',nx.degree(G1)) # 返回图中各顶点的度
, f; _7 I7 u3 o' t Y* Vprint('nx.density:',nx.degree_histogram(G1)) # 返回图中度的分布
! l! \! E6 i* cprint('nx.pagerank:',nx.pagerank(G1)) # 返回图中各顶点的频率分布) g3 ^2 @) l4 w7 k8 O6 q
- Y+ ^" ^( u- [2 i; U, v
5 t4 _- M; A/ v" C5 {4 Y9 {; n$ C. i
9 ^9 Q1 ]) |6 R7 O! N' o
9 T% V! ?: h* V# }6 w7 s9 i( F! ~
+ ^! E/ Y& K. L6 S7 a P2.3 图的属性和方法图的方法
* S& O, e9 i; R0 V; N ^7 K4 H! }' Q' r* h
方法 说明1 X' d7 k, b9 Q. j6 V8 \
G.has_node(n) 当图 G 中包括顶点 n 时返回 True
$ a" J! {/ d C& Q2 }7 v( _G.has_edge(u, v) 当图 G 中包括边 (u,v) 时返回 True, b2 n4 D2 n* A4 D, O( Y
G.number_of_nodes() 返回 图 G 中的顶点的数量
% K- m4 D) [& C2 O! R3 `2 nG.number_of_edges() 返回 图 G 中的边的数量: @" S# A4 f" @" q; u0 {
G.number_of_selfloops() 返回 图 G 中的自循环边的数量
y$ ~) W* z) Z8 O& i) v3 kG.degree([nbunch, weight]) 返回 图 G 中的全部顶点或指定顶点的度5 }9 R$ ]0 _& @% ^5 Y( \
G.selfloop_edges([data, default]) 返回 图 G 中的全部的自循环边
; \1 Z0 }$ r3 f4 e) q i# Q( qG.subgraph([nodes]) 从图 G1中抽取顶点[nodes]及对应边构成的子图, n! N% R- X4 a3 e& d g' r f V
union(G1,G2) 合并图 G1、G2
% _7 E, o' G1 O% C' L; ^) gnx.info(G) 返回图的基本信息
$ G7 X0 J, r1 anx.degree(G) 返回图中各顶点的度/ `1 {/ @) Q! V0 i8 A/ L3 y
nx.degree_histogram(G) 返回图中度的分布( M: ~, p# N8 ?& W% M+ L
nx.pagerank(G) 返回图中各顶点的频率分布* |$ H* \- | B7 s9 d
nx.add_star(G,[nodes],**attr) 向图 G 添加星形网络 `; V, `. S! p6 o" a
nx.add_path(G,[nodes],**attr) 向图 G 添加一条路径
u `$ L( @; U- Ynx.add_cycle(G,[nodes],**attr) 向图 G 添加闭合路径( S/ w/ ? U1 S' t
( G! {8 D7 u0 l% ]6 P; z1 k
8 `/ a! e3 Y0 J! L0 Q! y例程:
: M( V4 k- s( T( lG1.clear() # 清空图G1
& {* Y% t0 z; y" Cnx.add_star(G1, [1, 2, 3, 4, 5], weight=1) # 添加星形网络:以第一个顶点为中心
4 L, Q" @$ ?. T9 Y8 u/ D+ H# [(1, 2), (1, 3), (1, 4), (1, 5)]
; d2 L# H: r; Z' D' Q1 I- B# |nx.add_path(G1, [5, 6, 8, 9, 10], weight=2) # 添加路径:顺序连接 n个节点的 n-1条边
+ |7 J9 F# H# b7 i# [(5, 6), (6, 8), (8, 9), (9, 10)]
9 h; x* _$ |/ g% K- B7 Lnx.add_cycle(G1, [7, 8, 9, 10, 12], weight=3) # 添加闭合回路:循环连接 n个节点的 n 条边* Y; t! O" A1 J: F h
# [(7, 8), (7, 12), (8, 9), (9, 10), (10, 12)]
+ T4 M" D9 n8 p4 n* Jprint(G1.nodes) # 返回所有的顶点 [node1,...]
* H& [& [5 F9 y7 q6 r4 _nx.draw_networkx(G1)9 Y3 u1 a7 O) s& I
plt.show()
" V% l+ N0 i9 i6 c6 I4 R1 B# L0 _. R
G2 = G1.subgraph([1, 2, 3, 8, 9, 10])
$ e% z( t: j/ m P7 @. T: }' ^G3 = G1.subgraph([4, 5, 6, 7])% |. ]9 B5 e) a
G = nx.union(G2, G3)
* J# B+ M0 J" _print(G.nodes) # 返回所有的顶点 [node1,...]' L' U4 A% c6 d6 X# s5 ^3 d4 _- ~
# [1, 2, 3, 8, 9, 10, 4, 5, 6, 7]
" ]0 F+ l7 @0 r9 k: O" y9 I) W/ f! \) m$ z
: E3 c, O7 Q5 s0 c2 w( p5 N
3、图的绘制与分析3.1 图的绘制% W n* n0 H, g& v# I1 O
可视化是图论和网络问题中很重要的内容。NetworkX 在 Matplotlib、Graphviz 等图形工具包的基础上,提供了丰富的绘图功能。
) D+ `, w4 w. i! e
4 `$ o1 U8 x' ^6 }; Y2 j: T) S- w9 M本系列拟对图和网络的可视化作一个专题,在此只简单介绍基于 Matplotlib 的基本绘图函数。基本绘图函数使用字典提供的位置将节点放置在散点图上,或者使用布局函数计算位置。5 W+ C8 }) Z4 s# k
* l \+ ^3 ?6 H) R
方法 说明
+ K1 `# t* c% {# s& O# M: U8 C( Pdraw(G[,pos,ax]) 基于 Matplotlib 绘制 图 G5 T! D) U A/ m8 Y# f2 q
draw_networkx(G[, pos, arrows, with_labels]) 基于 Matplotlib 绘制 图 G
, h5 {8 R6 v) ]/ xdraw_networkx_nodes(G, pos[, nodelist, . . . ]) 绘制图 G 的顶点4 h9 t% C2 \" C4 g& g C' x
draw_networkx_edges(G, pos[, edgelist, . . . ]) 绘制图 G 的边
$ q; Y: Z4 X+ Z. E; ^* Rdraw_networkx_labels(G, pos[, labels, . . . ]) 绘制顶点的标签5 K% ?' F2 ]1 l) B+ t& ?5 r7 D
draw_networkx_edge_labels(G, pos[, . . . ]) 绘制边的标签; `; y: X( T \: v- ~4 O
" e6 w! f; l& \$ d& R" c) a" ?# K
8 S4 t. ^) b4 B2 ]其中,nx.draw() 和 nx.draw_networkx() 是最基本的绘图函数,并可以通过自定义函数属性或其它绘图函数设置不同的绘图要求。* S6 U$ i& j' ~! l
draw(G, pos=None, ax=None, **kwds)
draw_networkx(G, pos=None, arrows=True, with_labels=True, **kwds)
1 {# \3 u! O7 x0 v2 v0 Z常用的属性定义如下:. T% W; d4 j& ?! }' a
/ h9 c9 N. m0 D: G9 F‘node_size’:指定节点的尺寸大小,默认300: O& q, Y# T7 i) P2 Y
‘node_color’:指定节点的颜色,默认红色- |& M0 V" _- ]6 t9 l) y$ M3 K
‘node_shape’:节点的形状,默认圆形6 a% r: `; j& }, b7 X3 }. ^
'‘alpha’:透明度,默认1.0,不透明
1 `7 c! g4 {5 x' S‘width’:边的宽度,默认1.0
' @: Z& J8 W; P! ?- A$ S‘edge_color’:边的颜色,默认黑色
$ c/ j' S; J1 }7 w c2 y: j+ p‘style’:边的样式,可选 ‘solid’、‘dashed’、‘dotted’、‘dashdot’$ \1 r! d8 ]9 i+ z7 ]8 F* C' q) |
‘with_labels’:节点是否带标签,默认True/ A9 ?* S5 J% b3 G
‘font_size’:节点标签字体大小,默认12 u7 E! t2 U1 U9 D' O
‘font_color’:节点标签字体颜色,默认黑色
. Z2 D; F3 J5 \- A
' I2 x- u0 g6 _, ~ \" a
2 N2 t( Q/ S$ J' Z1 v1 e3.2 图的分析NetwotkX 提供了图论函数对图的结构进行分析, A3 e8 c6 ~- V% I% \% {: v
子图
. F; Q9 l, }( p# K2 ^1 k- 子图是指顶点和边都分别是图 G 的顶点的子集和边的子集的图。
- subgraph()方法,按顶点从图 G 中抽出子图。例程如前。3 ~/ R+ H% J/ J9 g+ B% n
连通子图( w1 ]9 A# |" v5 D# j
4 E0 E7 q1 d% s( {- 如果图 G 中的任意两点间相互连通,则 G 是连通图。
- [color=rgba(0, 0, 0, 0.749019607843137)]connected_components()方法,返回连通子图的集合。! o7 l2 x4 M- ^2 z1 x. X
[color=rgba(0, 0, 0, 0.749019607843137)]G = nx.path_graph(4)[color=rgba(0, 0, 0, 0.749019607843137)]nx.add_path(G, [7, 8, 9])[color=rgba(0, 0, 0, 0.749019607843137)]# 连通子图[color=rgba(0, 0, 0, 0.749019607843137)]listCC = [len(c) for c in sorted(nx.connected_components(G), key=len, reverse=True)][color=rgba(0, 0, 0, 0.749019607843137)]maxCC = max(nx.connected_components(G), key=len)[color=rgba(0, 0, 0, 0.749019607843137)]print('Connected components:{}'.format(listCC)) # 所有连通子图[color=rgba(0, 0, 0, 0.749019607843137)]# Connected components:[4, 3][color=rgba(0, 0, 0, 0.749019607843137)]print('Largest connected components:{}'.format(maxCC)) # 最大连通子图[color=rgba(0, 0, 0, 0.749019607843137)]# Largest connected components:{0, 1, 2, 3}[color=rgba(0, 0, 0, 0.749019607843137)]强连通如果有向图 G 中的任意两点间相互连通,则称 G 是强连通图。strongly_connected_components()方法,返回所有强连通子图的列表。# 强连通G = nx.path_graph(4, create_using=nx.DiGraph())nx.add_path(G, [3, 8, 1])# 找出所有的强连通子图con = nx.strongly_connected_components(G)print(type(con),list(con))# <class 'generator'> [{8, 1, 2, 3}, {0}]弱连通如果一个有向图 G 的基图是连通图,则有向图 G 是弱连通图。weakly_connected_components()方法,返回所有弱连通子图的列表。# 弱连通G = nx.path_graph(4, create_using=nx.DiGraph()) #默认生成节点 0,1,2,3 和有向边 0->1,1->2,2->3nx.add_path(G, [7, 8, 3]) #生成有向边:7->8->3con = nx.weakly_connected_components(G)print(type(con),list(con))# <class 'generator'> [{0, 1, 2, 3, 7, 8}], s: s( j' s5 t; R. \5 J2 K. |
9 ^, Q- F& o0 j# ^1 ?
5 c, W1 U8 c( O r. [+ J7 _
" x/ V- X+ U! Y
+ o! b+ p& ^6 _; G& _
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) |
Powered by Discuz! X2.5 |