数学建模社区-数学中国
标题: Python小白的数学建模课-图论的基本概念 [打印本页]
作者: 1047521767 时间: 2021-10-30 21:36
标题: Python小白的数学建模课-图论的基本概念
Python小白的数学建模课-图论的基本概念
3 ^9 D) D- y# O4 A0 J2 u( G7 D" ?" [; N0 R2 S) T
- 图论中所说的图,不是图形图像或地图,而是指由顶点和边所构成的图形结构。
- 图论不仅与拓扑学、计算机数据结构和算法密切相关,而且正在成为机器学习的关键技术。
- 本系列结合数学建模的应用需求,来介绍 NetworkX 图论与复杂网络工具包的基本功能和典型算法。% T: v5 y( |: j* J4 c
' R$ `! [8 d/ w6 j# m2 b
1. 图论1.1 图论是什么3 L- N" Z! `4 E" c H) E6 O
图论〔Graph Theory〕以图为研究对象,是离散数学的重要内容。图论不仅与拓扑学、计算机数据结构和算法密切相关,而且正在成为机器学习的关键技术。! g3 e1 k2 R2 i) }4 @1 |9 \- m' X5 E
! n* d o" e' J图论中所说的图,不是指图形图像(image)或地图(map),而是指由顶点(vertex)和连接顶点的边(edge)所构成的关系结构。' u3 ~. J# v* X( h5 t' D/ F
' z8 y# j9 }2 C% N8 l) O# }2 x) S* ?
图提供了一种处理关系和交互等抽象概念的更好的方法,它还提供了直观的视觉方式来思考这些概念。
1 ~ s. b: _: w' d+ R- j; h5 v6 S: \. _ k1 t
1.2 NetworkX 工具包
% ^% g2 T& r5 V( z* `7 M# NNetworkX 是基于 Python 语言的图论与复杂网络工具包,用于创建、操作和研究复杂网络的结构、动力学和功能。8 w: v% x c) B
1 O S4 `, u, W3 r0 h8 W
NetworkX 可以以标准和非标准的数据格式描述图与网络,生成图与网络,分析网络结构,构建网络模型,设计网络算法,绘制网络图形。1 I6 j& ?$ J/ }# p& o, ~% U
0 ?; U6 X" m9 z3 J+ O
NetworkX 提供了图形的类、对象、图形生成器、网络生成器、绘图工具,内置了常用的图论和网络分析算法,可以进行图和网络的建模、分析和仿真。+ D! ^8 Y8 F% A! ]
: s6 h, g ~5 O9 K; jNetworkX 的功能非常强大和庞杂,所涉及内容远远、远远地超出了数学建模的范围,甚至于很难进行系统的概括。本系列结合数学建模的应用需求,来介绍 NetworkX 图论与复杂网络工具包的基本功能和典型算法。7 K# p; [! d$ a5 T
% I. F5 c- e7 S; H) F
7 D* r' V8 ~& o3 `. S, p2 h
2、图、顶点和边的创建与基本操作; h4 `9 n( K) j4 u, y/ c
图由顶点和连接顶点的边构成,但与顶点的位置、边的曲直长短无关。
Networkx 支持创建简单无向图、有向图和多重图;内置许多标准的图论算法,节点可为任意数据;支持任意的边值维度,功能丰富,简单易用。
2.1 图的基本概念! g+ v, D$ n# l; i& r
图(Graph):图是由若干顶点和连接顶点的边所构成关系结构。
! A: P9 @" t& R顶点(Node):图中的点称为顶点,也称节点。
; v; w p; W+ t. Z: |) w边(Edge):顶点之间的连线,称为边。
9 N7 |. K* a% S5 ^6 H平行边(Parallel edge):起点相同、终点也相同的两条边称为平行边。
2 m% f" ?9 K* l Z& h1 H循环(Cycle):起点和终点重合的边称为循环。
- M# M( ^" ?- \+ V. E+ t$ L( t有向图(Digraph):图中的每条边都带有方向,称为有向图。
8 v! t% R) @* d. k无向图(Undirected graph):图中的每条边都没有方向,称为无向图。
. t0 \9 C$ V/ q; D) n1 Q7 s赋权图(Weighted graph):图中的每条边都有一个或多个对应的参数,称为赋权图。该参数称为这条边的权,权可以用来表示两点间的距离、时间、费用。
$ A4 c+ b: @3 M3 Y4 [ E# ?$ \3 S度(Degree):与顶点相连的边的数量,称为该顶点的度。2 m4 E8 z! F# v! R/ r+ S ^2 a- z% l
+ `2 N( ~8 v/ D: F* J
2.2 图、顶点和边的操作
4 S9 i; K5 P7 m: v9 X! r' n7 J% s9 fNetworkx很容易创建图、向图中添加顶点和边、从图中删除顶点和边,也可以查看、删除顶点和边的属性。
p7 l6 I: O' V4 H+ [, J$ w, J7 U0 t* g! x8 U2 M
2.2.1 图的创建Graph() 类、DiGraph() 类、MultiGraph() 类和 MultiDiGraph() 类分别用来创建:无向图、有向图、多图和有向多图。定义和例程如下:
: y+ R+ J8 t4 T& f- ]& k
+ U0 \! F; j4 aclass Graph(incoming_graph_data=None, **attr)
Q' ^' I* }6 {* [2 D5 H4 E; bimport networkx as nx # 导入 NetworkX 工具包4 @! H1 U h f/ S+ H
' \) g2 o" x+ g" E5 G
# 创建 图 `, V7 J t z
G1 = nx.Graph() # 创建:空的 无向图+ {0 M4 v' ^3 n! ^. |
G2 = nx.DiGraph() #创建:空的 有向图, P0 M1 t! f3 u1 @
G3 = nx.MultiGraph() #创建:空的 多图9 a( w$ X$ l2 A8 j
G4 = nx.MultiDiGraph() #创建:空的 有向多图; y5 w. r7 D+ W7 I. {& @0 z
) I3 e6 P/ p8 L) r; W# H
% a% Q4 w& x! e* h8 D( E1 h9 U& V x( v2.2.2 顶点的添加、删除和查看6 N. u6 z" ^6 y2 v6 }
图的每个顶点都有唯一的标签属性(label),可以用整数或字符类型表示,顶点还可以自定义任意属性。
顶点的常用操作:添加顶点,删除顶点,定义顶点属性,查看顶点和顶点属性。定义和例程如下:
( l& b" _, l4 p# RGraph.add_node(node_for_adding, **attr)
0 x3 g# V& P4 M* R6 F2 e9 ZGraph.add_nodes_from(nodes_for_adding, **attr)3 C5 e8 J( f) e5 L
Graph.remove_node(n)
* y3 C# T# ~) @9 S2 zGraph.remove_nodes_from(nodes)
7 U7 J5 ?( U* t* D& ]/ a
( l2 l5 ^ a/ A! I2 r U/ [4 ~& ^# 顶点(node)的操作$ R$ E1 t& z, K! Z: q C1 e0 {
# 向图中添加顶点' W6 l! D7 l: P) k5 H( d8 ~9 \% S
G1.add_node(1) # 向 G1 添加顶点 19 q& j, g" L+ s8 |3 e+ }9 I
G1.add_node(1, name='n1', weight=1.0) # 添加顶点 1,定义 name, weight 属性
& y! @$ {4 a/ L! ~) m/ c# G+ VG1.add_node(2, date='May-16') # 添加顶点 2,定义 time 属性
( @$ k' I2 `; d# |5 gG1.add_nodes_from([3, 0, 6], dist=1) # 添加多个顶点,并定义属性
; [: u) t+ U# |; j, kG1.add_nodes_from(range(10, 15)) # 向图 G1 添加顶点 10~14
. F6 r; C! j h. C
& w# _& F/ c- S# 查看顶点和顶点属性
- }$ a9 q9 R* V, g( Eprint(G1.nodes()) # 查看顶点列表4 G& E t5 q7 m& i+ z
# [1, 2, 3, 0, 6, 10, 11, 12, 13, 14]
+ ~4 H5 c- p, R$ D1 I' h! bprint(G1._node) # 查看顶点属性
" w q/ f( J5 o N; l# {1: {'name': 'n1', 'weight': 1.0}, 2: {'date': 'May-16'}, 3: {'dist': 1}, 0: {'dist': 1}, 6: {'dist': 1}, 10: {}, 11: {}, 12: {}, 13: {}, 14: {}}
' s# h. V: Z* F, r+ P; {8 _$ q8 ^2 ]# G" M
# 从图中删除顶点
8 e- e1 a* L# @! Y8 l2 l1 b/ WG1.remove_node(1) # 删除顶点" } X7 }; ~8 }8 C
G1.remove_nodes_from([1, 11, 13, 14]) # 通过顶点标签的 list 删除多个顶点
- S: D& d9 V1 e. A* S1 x Vprint(G1.nodes()) # 查看顶点
2 y9 s) g2 m. a% ^! o0 f. H# [2, 3, 0, 6, 10, 12] # 顶点列表+ l) J- T- x4 ]
2.2.3 边的添加、删除和查看边是两个顶点之间的连接,在 NetworkX 中 边是由对应顶点的名字的元组组成 e=(node1,node2)。边可以设置权重、关系等属性。
边的常用操作:添加边,删除边,定义边的属性,查看边和边的属性。向图中添加边时,如果边的顶点是图中不存在的,则自动向图中添加该顶点。
Graph.add_edge(u_of_edge, v_of_edge, **attr)" S$ ~1 t' s, R. N# ^% M' W" i
Graph.add_edges_from(ebunch_to_add, **attr)
; e4 v" \" j+ K( J, A; r: Z: H3 {Graph.add_weighted_edges_from(ebunch_to_add, weight=‘weight’, **attr)" y" ]; R& \. d) j$ L7 H( j
- A* E# M/ d2 f: @* J* V
# 边(edge)的操作5 F8 H& a. ?2 x
# 向图中添加边
) C d- b# A+ `3 {+ C+ yG1.add_edge(1,5) # 向 G1 添加边,并自动添加图中没有的顶点
* \- P8 D1 X8 V: rG1.add_edge(0,10, weight=2.7) # 向 G1 添加边,并设置边的属性& Q' w9 e7 A8 z9 ?5 t
G1.add_edges_from([(1,2,{'weight':0}), (2,3,{'color':'blue'})]) # 向图中添加边,并设置属性
8 n5 H- g4 O% q* SG1.add_edges_from([(3,6),(1,2),(6,7),(5,10),(0,1)]) # 向图中添加多条边
" L4 Y, o" ]% V9 i2 `% Y2 _4 VG1.add_weighted_edges_from([(1,2,3.6),[6,12,0.5]]) # 向图中添加多条赋权边: (node1,node2,weight)# ^! A7 s. C8 ~# ^
print(G1.nodes()) # 查看顶点4 C/ t3 d2 C @( ^
# [2, 3, 0, 6, 10, 12, 1, 5, 7] # 自动添加了图中没有的顶点; U9 r! ^9 H5 B% i1 n4 e8 [1 `
$ @2 O8 r) p) W3 l: L/ C# 从图中删除边
* g+ A3 l/ a2 d! EG1.remove_edge(0,1) # 从图中删除边 0-1
$ I1 m$ T, E) e. AG1.remove_edges_from([(2,3),(1,5),(6,7)]) # 从图中删除多条边
3 i. m/ L m( b; W s4 W% ~! a% h* _5 W9 o
# 查看 边和边的属性
, }3 K- A( ]- n" Pprint(G1.edges) # 查看所有的边* B5 c' R: U1 z) N9 ?( Z0 Q( W
[(2, 1), (3, 6), (0, 10), (6, 12), (10, 5)]
2 s ]5 E7 A# j+ ^" O' rprint(G1.get_edge_data(1,2)) # 查看指定边的属性
" i( A$ o: v8 P0 d# {'weight': 3.6}
0 H2 D5 O1 @; r% a2 Eprint(G1[1][2]) # 查看指定边的属性! r8 R5 |! n8 P9 i* M% z2 P
# {'weight': 3.6}8 T% S6 k) N x- S4 T1 ?
print(G1.edges(data=True)) # 查看所有边的属性/ c: A0 } e n' m) H0 Y
# [(2, 1, {'weight': 3.6}), (3, 6, {}), (0, 10, {'weight': 2.7}), (6, 12, {'weight': 0.5}), (10, 5, {})]& a/ Y6 F5 z4 R& X) u
( g+ J- x7 L2 F5 Q' Y+ }0 t( `
2.2.4 查看图、顶点和边的信息
7 J4 o6 R+ ^- v% f) T6 Y& D/ y; i6 S v7 n7 }$ L
# 查看图、顶点和边的信息
/ n6 h9 Q* u1 H" m" v) o4 r. cprint(G1.nodes) # 返回所有的顶点 [node1,...], d" g/ g% |) l% y( m& H" q# S" P
# [2, 3, 0, 6, 10, 12, 1, 5, 7]' N7 C ]. l! @5 H" n
print(G1.edges) # 返回所有的边 [(node1,node2),...]6 O5 Y& E# ^, f h' w; P% Y6 ]6 H8 Y0 z
# [(2, 1), (3, 6), (0, 10), (6, 12), (10, 5)]
1 X: M' d9 f; t* P& G, t) f1 ?" ]print(G1.degree) # 返回各顶点的度 [(node1,degree1),...]
5 O# O, K' A" e# [(2, 1), (3, 1), (0, 1), (6, 2), (10, 2), (12, 1), (1, 1), (5, 1), (7, 0)]
$ Y8 l/ L5 [- i5 A1 Sprint(G1.number_of_nodes()) # 返回顶点的数量, Y' t3 _8 g* _% T1 z! n6 N
# 9
8 K2 d6 j8 {+ ]6 o- e, u: A( Sprint(G1.number_of_edges()) # 返回边的数量* i5 J8 x7 [9 d4 G$ H. ^/ Z
# 54 G3 V8 D- V9 x2 H% l
print(G1[10]) # 返回与指定顶点相邻的所有顶点的属性
: S* j2 N1 m+ N0 G8 U# {0: {'weight': 2.7}, 5: {}}* z9 H; X2 V" d) a
print(G1.adj[10]) # 返回与指定顶点相邻的所有顶点的属性
. c0 }1 n# T9 s# {0: {'weight': 2.7}, 5: {}}, K; F; ]- l2 ^% Z9 Z+ w
print(G1[1][2]) # 返回指定边的属性
- j1 l6 {$ I3 w1 w! b* p; E6 }# {'weight': 3.6}
4 x& s' T, [+ a8 r7 |* m! Zprint(G1.adj[1][2]) # 返回指定边的属性
' }7 S6 J( J% ]0 [5 J7 x$ q# {'weight': 3.6}
/ `% p! J9 `. v6 `; u# Hprint(G1.degree(10)) # 返回指定顶点的度
4 m$ J" ]" ?9 U6 ^+ X1 w# 2
( B0 V3 y3 U9 v* e& B
: O9 ^: A$ @# U; S0 x) E) Lprint('nx.info:',nx.info(G1)) # 返回图的基本信息1 ]7 z" i- s8 P R! A
print('nx.degree:',nx.degree(G1)) # 返回图中各顶点的度# q, ^! g7 f q: y& F
print('nx.density:',nx.degree_histogram(G1)) # 返回图中度的分布: n2 z. ?) t8 [6 ?" S: n# J. S, N
print('nx.pagerank:',nx.pagerank(G1)) # 返回图中各顶点的频率分布; g; L# r0 b+ ?# _
, r) Q! N1 T8 W1 ]4 v+ S8 C& P# G0 ]9 Z; g! ^: c) p
; x9 e9 O3 Y) a# F# t/ i9 G
) @' c9 S$ U" T* c1 ~
' ?, |, A7 s7 F! j; i( b% W) b. v2.3 图的属性和方法图的方法
/ T5 q6 G9 S: {* V/ q, |" Q0 U- b5 z
方法 说明
9 N9 X( X. p k( N' k7 dG.has_node(n) 当图 G 中包括顶点 n 时返回 True( u! _. e( G$ q; ]9 E, C8 x4 d
G.has_edge(u, v) 当图 G 中包括边 (u,v) 时返回 True: g# ~( K, W& z+ h2 y. ]" V
G.number_of_nodes() 返回 图 G 中的顶点的数量
& C! h- R5 r% {. t. w) hG.number_of_edges() 返回 图 G 中的边的数量 v6 Q* Z4 D K. p0 x
G.number_of_selfloops() 返回 图 G 中的自循环边的数量4 l5 _6 {% B. S( [9 ~
G.degree([nbunch, weight]) 返回 图 G 中的全部顶点或指定顶点的度
7 z8 X. y+ O2 e( o! bG.selfloop_edges([data, default]) 返回 图 G 中的全部的自循环边1 I) M0 r2 |2 R- G4 L& u
G.subgraph([nodes]) 从图 G1中抽取顶点[nodes]及对应边构成的子图8 U, R- }0 {1 V5 C
union(G1,G2) 合并图 G1、G2, ^' H: V& _: b2 K. |; l' C
nx.info(G) 返回图的基本信息- S; q, v* P5 a$ z
nx.degree(G) 返回图中各顶点的度
. J6 t' v/ a3 z1 U' e/ C# Dnx.degree_histogram(G) 返回图中度的分布+ ^, u8 ~/ g% S/ o: }2 g; l
nx.pagerank(G) 返回图中各顶点的频率分布6 f2 c+ ]0 \/ L9 s5 g5 l7 d! a
nx.add_star(G,[nodes],**attr) 向图 G 添加星形网络
; E' {. ?7 U; {* L( ^; F+ vnx.add_path(G,[nodes],**attr) 向图 G 添加一条路径
7 ]; S3 f# X: ?6 Rnx.add_cycle(G,[nodes],**attr) 向图 G 添加闭合路径
3 K+ `4 N/ b& m! v7 x' i4 K1 ^' }2 Q; j, {: z6 k5 Y% b* R; H* V
% T% v/ O8 Q! n* O1 _
例程:
9 Y7 I$ m ^. j7 i& {' V/ U, v1 K% gG1.clear() # 清空图G1! J3 r# d) H g$ A. H1 V1 ~* G; L
nx.add_star(G1, [1, 2, 3, 4, 5], weight=1) # 添加星形网络:以第一个顶点为中心8 Y1 }# L) O$ c1 k9 n, Q! [4 j% k2 R
# [(1, 2), (1, 3), (1, 4), (1, 5)] ~* v) w. q& I6 ?9 {1 r
nx.add_path(G1, [5, 6, 8, 9, 10], weight=2) # 添加路径:顺序连接 n个节点的 n-1条边
3 H4 j% s7 U8 h* i# [(5, 6), (6, 8), (8, 9), (9, 10)]6 G& q9 \( @* \, _! t/ ?9 G; ^
nx.add_cycle(G1, [7, 8, 9, 10, 12], weight=3) # 添加闭合回路:循环连接 n个节点的 n 条边/ {: y; x2 ` l. m! I
# [(7, 8), (7, 12), (8, 9), (9, 10), (10, 12)]% v; c& R. ]: S4 i, W
print(G1.nodes) # 返回所有的顶点 [node1,...]# s7 x, G, o, [) w/ @+ j/ ^
nx.draw_networkx(G1)1 W7 j/ E2 T C& `. A
plt.show()
1 K. x# Y/ N3 ?( c6 a6 m
1 E7 g I( A+ g8 C% p3 c- l9 R! `G2 = G1.subgraph([1, 2, 3, 8, 9, 10])
0 w$ w) w6 b4 F1 lG3 = G1.subgraph([4, 5, 6, 7])7 I* J0 G2 q' l/ d* n
G = nx.union(G2, G3)
8 S+ U$ r. x# @) kprint(G.nodes) # 返回所有的顶点 [node1,...]
" d% @, w1 G& |/ ]9 \0 v# [1, 2, 3, 8, 9, 10, 4, 5, 6, 7]
; Q, P/ e+ X% b7 l9 A# B
. A& v! O$ ~- R/ }" z9 X* M% T7 Y& K6 H3 q* r' `
3、图的绘制与分析3.1 图的绘制
; e+ g) Z: b8 ]* L ~可视化是图论和网络问题中很重要的内容。NetworkX 在 Matplotlib、Graphviz 等图形工具包的基础上,提供了丰富的绘图功能。
~3 m, j5 z) q. t; I8 e$ O: s& [; o. D2 z4 ?1 f% o$ n: F
本系列拟对图和网络的可视化作一个专题,在此只简单介绍基于 Matplotlib 的基本绘图函数。基本绘图函数使用字典提供的位置将节点放置在散点图上,或者使用布局函数计算位置。% \2 E4 d1 y8 R: Z ?
( |5 a1 H* j* N
方法 说明% A0 @% K$ l/ p! L
draw(G[,pos,ax]) 基于 Matplotlib 绘制 图 G
6 J$ l. t9 A8 ?8 s8 W; g8 Fdraw_networkx(G[, pos, arrows, with_labels]) 基于 Matplotlib 绘制 图 G
. y" ^* f; {* \8 F! C/ A S; q; H1 _draw_networkx_nodes(G, pos[, nodelist, . . . ]) 绘制图 G 的顶点! H7 H& a9 ?# L/ @! X
draw_networkx_edges(G, pos[, edgelist, . . . ]) 绘制图 G 的边
4 N7 |5 U2 h" U9 bdraw_networkx_labels(G, pos[, labels, . . . ]) 绘制顶点的标签
. o# @* L$ X" P6 q) l+ J% t& e% ]draw_networkx_edge_labels(G, pos[, . . . ]) 绘制边的标签
% e+ j/ j& y' L* O! S" P( U0 b% F: b) k6 B
8 A l- f4 f& ~! j+ I1 T) y其中,nx.draw() 和 nx.draw_networkx() 是最基本的绘图函数,并可以通过自定义函数属性或其它绘图函数设置不同的绘图要求。
- A7 H! J8 \; I2 ^! c/ P) f5 }draw(G, pos=None, ax=None, **kwds)
draw_networkx(G, pos=None, arrows=True, with_labels=True, **kwds)
/ S; {6 I# X; Q4 ]" m7 j! h3 n9 G) o) h. w常用的属性定义如下:
e, \0 T6 j/ t& w6 W
7 i' x0 Q) K I- p n2 [‘node_size’:指定节点的尺寸大小,默认300
2 N4 y1 n3 q6 k5 J- W6 @' i‘node_color’:指定节点的颜色,默认红色/ |) E' l$ b' J. u! u9 F5 m
‘node_shape’:节点的形状,默认圆形+ a1 a7 s2 ^9 E& L1 U9 N
'‘alpha’:透明度,默认1.0,不透明
! @5 n! D8 b" f# ]7 ]‘width’:边的宽度,默认1.0
6 n e7 J" _) e/ U |" W# i‘edge_color’:边的颜色,默认黑色8 `2 ?: L; ?; Y9 q
‘style’:边的样式,可选 ‘solid’、‘dashed’、‘dotted’、‘dashdot’
A& v6 f0 B$ G* ~6 \‘with_labels’:节点是否带标签,默认True
1 C% X) b' ^9 I. B6 k) d8 I‘font_size’:节点标签字体大小,默认12
; n" ?2 Q2 W9 M7 b: m& i‘font_color’:节点标签字体颜色,默认黑色& L9 e5 c" y7 B% h# ?$ B
1 b$ F) G( h* {0 ]

+ I! {; a1 Q) x' W3.2 图的分析NetwotkX 提供了图论函数对图的结构进行分析
h: ^; x7 j3 \- n5 M P, _子图8 v( _, W, b; D
- 子图是指顶点和边都分别是图 G 的顶点的子集和边的子集的图。
- subgraph()方法,按顶点从图 G 中抽出子图。例程如前。3 Y8 A2 h# I6 b* c# g3 w, j
连通子图8 i7 k; d2 h6 N% r
e; R) ` m6 H: ]% Z
- 如果图 G 中的任意两点间相互连通,则 G 是连通图。
- [color=rgba(0, 0, 0, 0.749019607843137)]connected_components()方法,返回连通子图的集合。- [% Y* H" R, N
[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}]. E! H- V v a* r6 `( V% t
+ ?) d* X9 \+ _
. E# O; x2 c2 b' w, S7 c, j( h' G4 I% \ q4 \$ T! X9 B0 B
" k' i6 J# U) v0 N! j
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) |
Powered by Discuz! X2.5 |