QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4205|回复: 0
打印 上一主题 下一主题

Python小白的数学建模课-图论的基本概念

[复制链接]
字体大小: 正常 放大

1178

主题

15

听众

1万

积分

  • TA的每日心情
    开心
    2023-7-31 10:17
  • 签到天数: 198 天

    [LV.7]常住居民III

    自我介绍
    数学中国浅夏
    跳转到指定楼层
    1#
    发表于 2021-10-30 21:36 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    Python小白的数学建模课-图论的基本概念
    8 J- B* P2 {" h+ Y; M" I$ C/ R- U+ u5 f# {' Q; d
    • 图论中所说的图,不是图形图像或地图,而是指由顶点和边所构成的图形结构。
    • 图论不仅与拓扑学、计算机数据结构和算法密切相关,而且正在成为机器学习的关键技术。
    • 本系列结合数学建模的应用需求,来介绍 NetworkX 图论与复杂网络工具包的基本功能和典型算法。) c! k: k5 ~  g7 t+ H
    , w( H$ y1 l) \* V: i( `& j* t
    1. 图论1.1 图论是什么  O( r0 W1 l! [4 X
    图论〔Graph Theory〕以图为研究对象,是离散数学的重要内容。图论不仅与拓扑学、计算机数据结构和算法密切相关,而且正在成为机器学习的关键技术。! Y0 Q8 F' N9 m, i8 z- B

    / v0 D; Q# v* v图论中所说的图,不是指图形图像(image)或地图(map),而是指由顶点(vertex)和连接顶点的边(edge)所构成的关系结构。3 O, M" Z$ q* N

    2 n- |( L7 ]; ~图提供了一种处理关系和交互等抽象概念的更好的方法,它还提供了直观的视觉方式来思考这些概念。
    ' u7 t2 I, f! O, I) _9 A
      o: l) p+ @$ Q' k0 X/ y' l1.2 NetworkX 工具包" ?9 f9 y! A# E7 w- @
    NetworkX 是基于 Python 语言的图论与复杂网络工具包,用于创建、操作和研究复杂网络的结构、动力学和功能。
    1 Q- @) X& o5 @9 A& N2 i6 C. i) w
    NetworkX 可以以标准和非标准的数据格式描述图与网络,生成图与网络,分析网络结构,构建网络模型,设计网络算法,绘制网络图形。7 I* {6 T% j1 [
    ' t, \+ n. I4 |+ `, e
    NetworkX 提供了图形的类、对象、图形生成器、网络生成器、绘图工具,内置了常用的图论和网络分析算法,可以进行图和网络的建模、分析和仿真。
    ( h2 s% Z% n* \; v! A
    - a* t& S* U& Z2 G. ANetworkX 的功能非常强大和庞杂,所涉及内容远远、远远地超出了数学建模的范围,甚至于很难进行系统的概括。本系列结合数学建模的应用需求,来介绍 NetworkX 图论与复杂网络工具包的基本功能和典型算法。
    ( }/ q# [7 }( o5 x5 M6 D
    & ~* F' _5 `. h4 x8 ?9 W0 E/ }/ o) r9 B4 S. z3 g7 c1 D
    2、图、顶点和边的创建与基本操作
    & T8 e, g% g/ i$ X2 u! M7 X0 q

    图由顶点和连接顶点的边构成,但与顶点的位置、边的曲直长短无关。

    Networkx 支持创建简单无向图、有向图和多重图;内置许多标准的图论算法,节点可为任意数据;支持任意的边值维度,功能丰富,简单易用。

    2.1 图的基本概念
    ( x. a# X' T; c$ G8 h- v& K图(Graph):图是由若干顶点和连接顶点的边所构成关系结构。% Y$ c0 o+ Q8 [1 E
    顶点(Node):图中的点称为顶点,也称节点。+ W  X+ G# c4 }+ i
    边(Edge):顶点之间的连线,称为边。9 W$ H1 M0 @+ Z4 |) m% S: c
    平行边(Parallel edge):起点相同、终点也相同的两条边称为平行边。4 J5 c) S2 t/ Y/ c/ F
    循环(Cycle):起点和终点重合的边称为循环。/ H9 A$ ^1 K' T9 x
    有向图(Digraph):图中的每条边都带有方向,称为有向图。* X7 b: j1 F" `& |
    无向图(Undirected graph):图中的每条边都没有方向,称为无向图。
    / y" X! J  ~/ W3 D3 A赋权图(Weighted graph):图中的每条边都有一个或多个对应的参数,称为赋权图。该参数称为这条边的权,权可以用来表示两点间的距离、时间、费用。/ [5 [0 N' H$ L( t2 u
    度(Degree):与顶点相连的边的数量,称为该顶点的度。
      h* u% B5 P' u) b% S
    - F. i$ t2 e* p6 d2.2 图、顶点和边的操作4 ?: I# l& a1 b' S0 e8 G
    Networkx很容易创建图、向图中添加顶点和边、从图中删除顶点和边,也可以查看、删除顶点和边的属性。
    5 z8 ~$ \7 t& b. l5 n. H0 [* u) T8 J. P& C' t, s" ]
    2.2.1 图的创建Graph() 类、DiGraph() 类、MultiGraph() 类和 MultiDiGraph() 类分别用来创建:无向图、有向图、多图和有向多图。定义和例程如下:
    " b; `" B# _. r: q& w6 H; I7 J# O6 e9 [) b1 f; W1 ^3 @
    class Graph(incoming_graph_data=None, **attr)
    $ A8 c, J8 ^/ n8 I: x  t1 L4 `* _import networkx as nx  # 导入 NetworkX 工具包# ?5 E% M8 X  f4 ?9 e3 ^

    4 M' ~1 A$ q3 i- n4 r# 创建 图
    0 N; S6 h8 @' n# y, o( Q  H5 F" ?G1 = nx.Graph()  # 创建:空的 无向图1 {- j; a! r  n6 `; v: [  e$ G1 W
    G2 = nx.DiGraph()  #创建:空的 有向图, ~4 H# p) }" [
    G3 = nx.MultiGraph()  #创建:空的 多图
    " z/ \5 p! E1 w2 o, D: dG4 = nx.MultiDiGraph()  #创建:空的 有向多图
    ( m6 p! E& ~/ U# N6 `+ i
    + {, U' t9 K% W  o0 G$ b
    " [2 W0 t) P' |1 T2.2.2 顶点的添加、删除和查看/ x$ |* @# n' ]# }; l! V

    图的每个顶点都有唯一的标签属性(label),可以用整数或字符类型表示,顶点还可以自定义任意属性。

    顶点的常用操作:添加顶点,删除顶点,定义顶点属性,查看顶点和顶点属性。定义和例程如下:

    # J& Y  H5 U4 o8 `+ m
    Graph.add_node(node_for_adding, **attr)  U) R2 t3 d+ f
    Graph.add_nodes_from(nodes_for_adding, **attr)
    ; g8 l! a( S( K$ u; l5 VGraph.remove_node(n)" q$ `1 q" w9 z% z; R8 N
    Graph.remove_nodes_from(nodes)! \% ]  Q  D1 m
    " ~/ d! Q* X0 `( l
    # 顶点(node)的操作
    # K8 D/ y8 @9 t; f) ^5 {: k7 k9 L# 向图中添加顶点
    7 k' I  \( X& \7 C0 iG1.add_node(1)  # 向 G1 添加顶点 18 Y4 {, f$ z9 |6 `0 ~$ A
    G1.add_node(1, name='n1', weight=1.0)  # 添加顶点 1,定义 name, weight 属性2 u3 \. O( v4 a1 z8 y
    G1.add_node(2, date='May-16') # 添加顶点 2,定义 time 属性
    & s% i0 N# H6 Q, ]7 L5 L( a6 d& R1 |G1.add_nodes_from([3, 0, 6], dist=1)  # 添加多个顶点,并定义属性5 \* u, _: w, A
    G1.add_nodes_from(range(10, 15))  # 向图 G1 添加顶点 10~147 [, E& E, X" P

    $ s1 L$ B+ ~, b, \# 查看顶点和顶点属性
    + ~6 X5 F0 e9 kprint(G1.nodes())  # 查看顶点列表
    # r' p; ~4 `; R3 l) }8 ~9 {# [1, 2, 3, 0, 6, 10, 11, 12, 13, 14]
    * i9 j2 t( b0 f$ U6 S; B. k3 bprint(G1._node)  # 查看顶点属性" l9 f. e  T: m: e- q/ W# u
    # {1: {'name': 'n1', 'weight': 1.0}, 2: {'date': 'May-16'}, 3: {'dist': 1}, 0: {'dist': 1}, 6: {'dist': 1}, 10: {}, 11: {}, 12: {}, 13: {}, 14: {}}* o) Y# _3 t3 R' T. v$ V- \1 p
    - w* T4 j& [/ E/ m7 Z& k6 @/ H
    # 从图中删除顶点
    ) }3 k/ |6 r  C% @$ `G1.remove_node(1)  # 删除顶点
    * H7 ^- |5 u) b. [G1.remove_nodes_from([1, 11, 13, 14])  # 通过顶点标签的 list 删除多个顶点1 e: j1 c1 W' e' ^, R8 O& X$ H
    print(G1.nodes())  # 查看顶点
    # G5 }3 y! Y* e$ S8 N. r$ E9 D# [2, 3, 0, 6, 10, 12]  # 顶点列表
    + A  H6 X7 X+ T/ F2.2.3 边的添加、删除和查看

    边是两个顶点之间的连接,在 NetworkX 中 边是由对应顶点的名字的元组组成 e=(node1,node2)。边可以设置权重、关系等属性。

    边的常用操作:添加边,删除边,定义边的属性,查看边和边的属性。向图中添加边时,如果边的顶点是图中不存在的,则自动向图中添加该顶点。

    Graph.add_edge(u_of_edge, v_of_edge, **attr): |  M/ V. E- ^2 v
    Graph.add_edges_from(ebunch_to_add, **attr)* q8 f7 f/ K: L" _/ i1 u+ G% I9 U
    Graph.add_weighted_edges_from(ebunch_to_add, weight=‘weight’, **attr)7 z$ [* a; u# U

    $ j7 ?7 |+ u- ~8 U5 Y# 边(edge)的操作
    % [# A( T2 _& s0 I# J# 向图中添加边
    $ ~$ H! e  O1 j% d0 ]- HG1.add_edge(1,5)  # 向 G1 添加边,并自动添加图中没有的顶点6 y. e5 P1 N4 \
    G1.add_edge(0,10, weight=2.7)  # 向 G1 添加边,并设置边的属性
    6 `0 c( y/ J$ N4 k/ B7 Q, O3 @G1.add_edges_from([(1,2,{'weight':0}), (2,3,{'color':'blue'})])  # 向图中添加边,并设置属性
    2 N7 V& z" M( a1 h9 X# UG1.add_edges_from([(3,6),(1,2),(6,7),(5,10),(0,1)])  # 向图中添加多条边
    $ ^7 C+ g7 g. E9 HG1.add_weighted_edges_from([(1,2,3.6),[6,12,0.5]])  # 向图中添加多条赋权边: (node1,node2,weight)
    0 T$ C% i1 s6 c9 eprint(G1.nodes())  # 查看顶点
    2 z3 \3 L0 V% H0 J, n4 T2 o2 p6 v# [2, 3, 0, 6, 10, 12, 1, 5, 7]  # 自动添加了图中没有的顶点
    ! t# V$ U, Z# P! g  d
    ! S+ m/ B& _) ^3 s5 F# 从图中删除边, Y' M& ]" E$ l3 Q
    G1.remove_edge(0,1)  # 从图中删除边 0-1
    : s' p3 `) `- u1 k0 W; U1 {1 MG1.remove_edges_from([(2,3),(1,5),(6,7)])  # 从图中删除多条边
    1 D; u; ?0 p/ d
    3 |- k3 e  Y4 P9 D# O/ e! \3 X# 查看 边和边的属性
    5 z6 J- z4 O8 ^% ~9 t; aprint(G1.edges)  # 查看所有的边
    - w* `6 y) d% W[(2, 1), (3, 6), (0, 10), (6, 12), (10, 5)]
    % k% h! N  s( k# ~4 q/ P; U& O0 X6 fprint(G1.get_edge_data(1,2))  # 查看指定边的属性
    & W) T+ b: P  e! s6 ?# {'weight': 3.6}
    + y; c# n" i# H: o! Xprint(G1[1][2])  # 查看指定边的属性. }" w4 x% ]7 s; }
    # {'weight': 3.6}
    1 p, z, u% z" _- d4 \% _print(G1.edges(data=True))  # 查看所有边的属性
    / ~- w7 w" Z& c6 n$ A+ t. D# [(2, 1, {'weight': 3.6}), (3, 6, {}), (0, 10, {'weight': 2.7}), (6, 12, {'weight': 0.5}), (10, 5, {})]3 \7 [) u: o- D  l$ j2 K
    ( L2 l; Q% |, x* T# m& C
    2.2.4 查看图、顶点和边的信息
    5 H- G7 B2 R, j
    , ~+ n+ W9 l4 l! b2 h' a" z, q' P# 查看图、顶点和边的信息
    ( w4 b3 T% L% b( xprint(G1.nodes)  # 返回所有的顶点 [node1,...]% p: h: |* u, W# s
    # [2, 3, 0, 6, 10, 12, 1, 5, 7]
    0 L2 J6 |: A6 A. \( f6 y+ h7 f( vprint(G1.edges)  # 返回所有的边 [(node1,node2),...]: ^5 A5 }, p: v3 r' X- Q
    # [(2, 1), (3, 6), (0, 10), (6, 12), (10, 5)]; q) i6 w  E. k# k9 g; A( o0 X& h
    print(G1.degree)  # 返回各顶点的度 [(node1,degree1),...]
    ( R) c5 ?) m9 \- f* |# [(2, 1), (3, 1), (0, 1), (6, 2), (10, 2), (12, 1), (1, 1), (5, 1), (7, 0)]- v5 |" T9 `. i0 {: g
    print(G1.number_of_nodes())  # 返回顶点的数量9 e: j* i. j0 J; Q6 ]5 y
    # 92 b2 |. x3 O  l: k
    print(G1.number_of_edges())  # 返回边的数量+ t* O. x- C0 l- z8 t% Q  u
    # 5* W" @) \- w  v& I' C. d* r) q
    print(G1[10])  # 返回与指定顶点相邻的所有顶点的属性
    ) x: w8 C" b7 |# {0: {'weight': 2.7}, 5: {}}. l* C: \4 L- B. b7 Z
    print(G1.adj[10])  # 返回与指定顶点相邻的所有顶点的属性
    / \' o5 x- S, S* f5 k# {0: {'weight': 2.7}, 5: {}}
    ) `( p- ~  s8 M5 l" E6 r2 l$ Jprint(G1[1][2])  # 返回指定边的属性2 Y6 H* Y  j) |, W9 Q1 M4 J
    # {'weight': 3.6}
    $ j( Q! s: K0 u% g! m6 D! mprint(G1.adj[1][2])  # 返回指定边的属性
    $ H, P6 S( {" f# Z' }$ o# {'weight': 3.6}
    0 [  ?4 @8 o& Q" N. w7 N6 Gprint(G1.degree(10))  # 返回指定顶点的度
    / N! R5 X/ ]" |$ S# 2& |# D! ]& V6 j+ S$ c6 ?% \
    ( J1 v6 \1 _) [. J  e- \  S: w
    print('nx.info:',nx.info(G1))  # 返回图的基本信息- a" {# ]  T6 w
    print('nx.degree:',nx.degree(G1))  # 返回图中各顶点的度. ]5 E# a; q( A; ?
    print('nx.density:',nx.degree_histogram(G1))  # 返回图中度的分布
    % N2 B& O' ]8 I+ T/ k2 Z5 wprint('nx.pagerank:',nx.pagerank(G1))  # 返回图中各顶点的频率分布
    ( c/ e/ p( U1 b4 W2 M0 V+ b6 ~/ f5 z8 ]/ f' I2 c

    ( [) \) i9 @$ r3 d8 m- B# c0 T9 K2 R1 A# M

    2 t$ g" k" G8 I* u+ i. C5 E
    # l, s* T+ ]& ]5 t; L5 ]2.3 图的属性和方法图的方法+ G* {) q; q2 Y+ a$ W. D
    ; d7 Q( [" p2 P& r7 w8 N9 |
    方法                                                说明
    8 \0 z6 `% D- y, D9 R" QG.has_node(n)                                当图 G 中包括顶点 n 时返回 True
    2 C  g: Y% z% R- ?* j- X! DG.has_edge(u, v)                        当图 G 中包括边 (u,v) 时返回 True* r, [2 K) Q0 [* M: o5 v( v
    G.number_of_nodes()                        返回 图 G 中的顶点的数量! b$ [& u+ z# D0 D! l& K" ]
    G.number_of_edges()                        返回 图 G 中的边的数量: [1 d/ a) q2 a2 C" E- [
    G.number_of_selfloops()                返回 图 G 中的自循环边的数量
    5 V1 z6 y4 R  w: u% j- i: JG.degree([nbunch, weight])                返回 图 G 中的全部顶点或指定顶点的度
    $ B- G: X. k  s! z- v0 `) u5 LG.selfloop_edges([data, default])        返回 图 G 中的全部的自循环边
    2 i. O3 N, T# J2 E' HG.subgraph([nodes])                        从图 G1中抽取顶点[nodes]及对应边构成的子图& ]5 ?, u* m. c& S! ]; m
    union(G1,G2)                                合并图 G1、G2
    $ p0 C( L3 y. d* \nx.info(G)                                        返回图的基本信息
    9 a+ o. p! y, f+ c9 E* Gnx.degree(G)                                返回图中各顶点的度
    & y! e4 w. a% x4 m8 V! k' r% gnx.degree_histogram(G)                返回图中度的分布
    ' `: @, t5 N: V, P! gnx.pagerank(G)                                返回图中各顶点的频率分布4 B. G3 E; H: H
    nx.add_star(G,[nodes],**attr)        向图 G 添加星形网络$ e) j# o& h9 h* G
    nx.add_path(G,[nodes],**attr)        向图 G 添加一条路径
    0 Q( z9 ]9 ?9 M7 ]6 hnx.add_cycle(G,[nodes],**attr)        向图 G 添加闭合路径
    * p9 U$ o+ S& O% |) z# O
    1 X8 c8 i* Y2 j" ?& ^8 @2 S8 Y( ]0 w4 x2 F" h8 ]
    例程:( B* g0 W+ U, i, N; U! y' d
    G1.clear() # 清空图G10 ?4 }2 S& H; @' M, Q" t
    nx.add_star(G1, [1, 2, 3, 4, 5], weight=1)  # 添加星形网络:以第一个顶点为中心
    . F3 O3 Z! x: r' y, f/ N# R. e# [(1, 2), (1, 3), (1, 4), (1, 5)]
    . J6 g# l: S5 t9 c* X% |5 j. _nx.add_path(G1, [5, 6, 8, 9, 10], weight=2)  # 添加路径:顺序连接 n个节点的 n-1条边
    " G/ i5 C( o7 i$ @+ L# [(5, 6), (6, 8), (8, 9), (9, 10)]
    3 t6 z1 \- J5 \nx.add_cycle(G1, [7, 8, 9, 10, 12], weight=3)  # 添加闭合回路:循环连接 n个节点的 n 条边' X( z3 [1 i+ c7 e
    # [(7, 8), (7, 12), (8, 9), (9, 10), (10, 12)]
    4 f% y# {% J5 ?! {1 p) R7 Gprint(G1.nodes)  # 返回所有的顶点 [node1,...]
    % \: i8 D+ G: e, Q) cnx.draw_networkx(G1)5 v/ a7 P" n. N2 O9 d
    plt.show()
    ; b  t/ d( j5 R, Y" ]3 |" x2 m  u7 t" U* U/ \
    G2 = G1.subgraph([1, 2, 3, 8, 9, 10])# r( O$ i8 W9 b
    G3 = G1.subgraph([4, 5, 6, 7])0 \0 y+ f8 `1 C; U  o! k
    G = nx.union(G2, G3)- D/ T, N+ ?3 o  _% h! A
    print(G.nodes)  # 返回所有的顶点 [node1,...]
    8 [4 V/ E0 D; L# [1, 2, 3, 8, 9, 10, 4, 5, 6, 7]
    8 C/ {0 Q, _3 u* I0 _# t8 k( `0 ?7 k) B8 o; J! ~+ b
    . w8 H# o( d# k% \% o# }4 j& A
    3、图的绘制与分析3.1 图的绘制
    ; F" P2 F* L6 E) F5 `" u1 R可视化是图论和网络问题中很重要的内容。NetworkX 在 Matplotlib、Graphviz 等图形工具包的基础上,提供了丰富的绘图功能。4 K& j, k2 I& Q( c4 Z" ~, X

    + a0 i& ?! v% i  _9 R- }本系列拟对图和网络的可视化作一个专题,在此只简单介绍基于 Matplotlib 的基本绘图函数。基本绘图函数使用字典提供的位置将节点放置在散点图上,或者使用布局函数计算位置。
    , [( R8 b6 d  z- R: n, v  ~+ e+ w4 B. t. G
    方法                                                                        说明
    , M, w/ {6 `4 p/ U& |2 |draw(G[,pos,ax])                                                基于 Matplotlib 绘制 图 G
    : t: h: M/ {/ g8 d6 \1 bdraw_networkx(G[, pos, arrows, with_labels])        基于 Matplotlib 绘制 图 G* r0 O& P# h; J+ W' f! r
    draw_networkx_nodes(G, pos[, nodelist, . . . ])        绘制图 G 的顶点
    ) I, Q' B+ {* Y) T/ Adraw_networkx_edges(G, pos[, edgelist, . . . ])        绘制图 G 的边% m6 i6 j2 s* o
    draw_networkx_labels(G, pos[, labels, . . . ])            绘制顶点的标签
    ( K0 N  ]& K# n: U  vdraw_networkx_edge_labels(G, pos[, . . . ])                绘制边的标签, x- B: m6 |$ F! n
    & ^- h2 J0 \( |0 Z5 C7 ]. U1 g) R% ]  Q
    " W4 W) j5 O2 g2 z& d7 S7 ?: i. k
    其中,nx.draw() 和 nx.draw_networkx() 是最基本的绘图函数,并可以通过自定义函数属性或其它绘图函数设置不同的绘图要求。
    4 \1 n$ v8 x# b% a( ~; i' P

    draw(G, pos=None, ax=None, **kwds)

    draw_networkx(G, pos=None, arrows=True, with_labels=True, **kwds)

    ) C9 b7 c( {8 j* ?) O
    常用的属性定义如下:
    5 B) I) _3 V8 A2 k  r  _' H+ r* ?8 \
    ‘node_size’:指定节点的尺寸大小,默认300
    ; M$ g3 V0 j5 ?5 M% p$ g‘node_color’:指定节点的颜色,默认红色7 v3 M2 [2 B2 f: K8 `
    ‘node_shape’:节点的形状,默认圆形
    0 _9 O* p; g' I, e% w'‘alpha’:透明度,默认1.0,不透明
    ( A' d2 ~  M1 \7 O( A‘width’:边的宽度,默认1.0& i# J' J* h) z7 ]
    ‘edge_color’:边的颜色,默认黑色+ D: X/ x( Z. s9 G% D! I' d6 m
    ‘style’:边的样式,可选 ‘solid’、‘dashed’、‘dotted’、‘dashdot’1 m8 t/ a2 v% u$ l5 L1 l* @
    ‘with_labels’:节点是否带标签,默认True
    1 \2 D, Q5 T; U& O‘font_size’:节点标签字体大小,默认12( ]! b% P2 H0 r' M5 I6 O2 {2 r
    ‘font_color’:节点标签字体颜色,默认黑色  o3 c+ N+ i, i0 |, n4 Q5 @

    + n6 f- z5 e( A+ F  E1 O" R$ w0 Z
    + a, Z) B# ?) M- t0 f. o1 N4 U' q3.2 图的分析NetwotkX 提供了图论函数对图的结构进行分析
    - C' j0 A) N4 I+ Q子图% K5 P0 G: [: D: a6 m, J& l; \
    • 子图是指顶点和边都分别是图 G 的顶点的子集和边的子集的图。
    • subgraph()方法,按顶点从图 G 中抽出子图。例程如前。
      ( E1 ~' J3 E' Q2 [% h" h
    连通子图
    . ^5 c" `$ i' k0 F6 o8 @7 ?8 N
    # w( D9 b; |! o0 ?) p! I/ R2 P
    • 如果图 G 中的任意两点间相互连通,则 G 是连通图。
    • [color=rgba(0, 0, 0, 0.749019607843137)]connected_components()方法,返回连通子图的集合。" m; p+ q7 Q/ ~5 E5 H# L
      [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}]
      / R3 a7 j3 _( Y! I. T+ i2 Q
    ) x) k; n! i. ]1 W
    6 J$ q' x9 d" d* L2 ~
    / s" Q* {" p( V% r( I

    ; W, P! z& a& g9 V
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-7-17 22:01 , Processed in 0.420621 second(s), 51 queries .

    回顶部