COMP5313 Week 3 NetworkX 新手入门

#COMP5313/week3 # COMP5313 Week 3:NetworkX 新手入门笔记

适用对象:刚开始学 Python / 刚开始接触 NetworkX 的同学
对应内容:Week 3 - Python and NetworkX (COMP5313/COMP4313)


1. 这份实验在学什么?

这份实验的核心目标是:

学会用 Python 里的 NetworkX 库来表示和操作“图(Graph)/ 网络(Network)”。

在复杂网络课程里,很多对象都可以抽象成“节点 + 边”的结构:

  • 社交网络:人是节点,关系是边
  • 道路网络:城市是节点,道路是边
  • 网页网络:网页是节点,链接是边
  • 通信网络:设备是节点,连接是边

所以,这一周实际上是在学:

  1. 怎么建一个图
  2. 怎么加节点和边
  3. 怎么查看图的结构
  4. 怎么计算一些图的基本性质

2. 什么是 Graph?

一个图(Graph)最基本由两部分组成:

2.1 Nodes(节点)

节点就是图里的“点”。

例如: - 一个人 - 一个城市 - 一个网页 - 一台电脑

2.2 Edges(边)

边就是两个节点之间的连接关系。

例如: - 两个人认识 - 两个城市之间有路 - 两个网页之间有链接 - 两台设备之间有通信

所以:

Graph = Nodes + Edges

这是这份 notebook 最核心的概念。


3. 第一段最重要的代码

import networkx as nx
g = nx.Graph()

3.1 import networkx as nx

意思是:

  • 导入 networkx 这个 Python 库
  • 给它取一个简写名字 nx

所以后面你会一直看到 nx.Graph()nx.path_graph() 这种写法。

3.2 g = nx.Graph()

意思是:

  • 创建一个空的图(graph)
  • 把它存到变量 g

你可以把 g 想成一个空的网络容器,后面所有节点和边都往里面加。


4. 怎么加节点(Nodes)

4.1 加一个节点

g.add_node(1)

意思是:

往图 g 里加一个节点,这个节点的名字是 1

注意: 节点不一定只能是数字,也可以是字符串:

g.add_node("Alice")

4.2 加多个节点

g.add_nodes_from([2, 3])

意思是:

从列表 [2, 3] 中把多个节点一次性加入图 g

这是批量添加节点的常见写法。


4.3 查看当前所有节点

g.nodes

可能会输出:

NodeView((1, 2, 3))

意思就是:

当前图里有 1、2、3 这几个节点


4.4 从另一个图中导入节点

h = nx.path_graph(10)
g.add_nodes_from(h)

这里有两个知识点:

h = nx.path_graph(10)

这会自动创建一个“路径图”:

0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9

也就是 10 个节点按顺序连成一条线。

g.add_nodes_from(h)

意思是:

把图 h 里的节点加到图 g

要注意: 这一步主要是在加入节点本身,不一定等于把边也一起完整搬过来。


4.5 删除节点

g.remove_node(2)

意思是:

把节点 2 从图中删除

如果这个节点和其他边有连接,相关边也会一起消失。


5. 怎么加边(Edges)

5.1 加一条边

g.add_edge(1, 2)

意思是:

在节点 1 和节点 2 之间连一条边

你可以理解成:

1 --- 2

如果这是无向图(nx.Graph() 默认是无向图),那么: - (1, 2)(2, 1) 是同一条边


5.2 一次加多条边

g.add_edges_from([(1, 2), (2, 3), (3, 4)])

意思是:

  • 1 和 2 连一条边
  • 2 和 3 连一条边
  • 3 和 4 连一条边

这和批量加节点的思路一样。


5.3 查看所有边

g.edges

可能输出:

EdgeView([(1, 2), (2, 3)])

意思是:

当前图中有这些连接关系


6. 你一定要会看的几个基本函数

6.1 节点总数

g.number_of_nodes()

返回图里有多少个节点。

文档中也提到:

g.order()

和上面这个意思一样。


6.2 边总数

g.number_of_edges()

返回图里有多少条边。

文档里也提到:

g.size()

也是类似作用。


6.3 查看某个节点的邻居

list(g.neighbors(1))

意思是:

找出所有和节点 1 直接相连的节点

例如:

g.add_edge(1, 2)
g.add_edge(1, 3)

那么:

list(g.neighbors(1))

结果就是:

[2, 3]

6.4 查看某个节点的度数

g.degree(1)

“度数(degree)”的意思就是:

这个节点连接了多少条边

如果 1 连着 2、3、4, 那么 g.degree(1) 就等于 3。


7. 路径图 path_graph(10) 到底是什么?

这个在 notebook 里很常见,所以单独讲一下。

h = nx.path_graph(10)

意思是创建这样一个图:

0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9

特点: - 一共有 10 个节点 - 每个节点只和前后相邻节点相连 - 两端的节点度数是 1 - 中间节点度数通常是 2

它是教学中最常见的简单例子之一。


8. 这份 notebook 的学习路线

根据文档结构,这份实验大致分成下面几部分:

Exercise 1: Graphs in Python

这是基础中的基础,主要在学: - 创建图 - 添加节点 - 添加边 - 删除节点 - 查看节点和边 - 查看邻居和度数

Exercise 2: Graph Properties

开始分析图的性质,例如: - 节点度数 - 路径 - 连通性 - 网络结构特征

Exercise 3: Graph Operations

开始学习对图做操作,例如: - 组合图 - 取子图 - 遍历和变换

Exercise 4: Graph Advanced Properties

更高级的复杂网络分析内容。


9. 给新手的最小可运行例子

如果你刚学,我建议你先单独跑下面这段代码:

import networkx as nx

g = nx.Graph()

g.add_node(1)
g.add_nodes_from([2, 3, 4])

g.add_edge(1, 2)
g.add_edge(1, 3)
g.add_edge(3, 4)

print("nodes:", g.nodes)
print("edges:", g.edges)
print("neighbors of 1:", list(g.neighbors(1)))
print("degree of 1:", g.degree(1))
print("number of nodes:", g.number_of_nodes())
print("number of edges:", g.number_of_edges())

这段代码会帮你同时理解: - 什么是图 - 什么是节点 - 什么是边 - 什么是邻居 - 什么是度数


10. 你现在最需要记住的 6 个命令

import networkx as nx
g = nx.Graph()
g.add_node(1)
g.add_nodes_from([2, 3])
g.add_edge(1, 2)
list(g.neighbors(1))

如果你把这几个都搞懂了,这周实验就已经入门了。


11. 一句最通俗的话理解 NetworkX

你可以把 NetworkX 理解成:

一个专门帮你在 Python 里画关系、存关系、查关系、分析关系的工具。

你不是在学一个很玄的东西, 你其实是在学:

  • 怎么把“谁和谁有关系”这件事写成代码
  • 再让 Python 帮你分析这个关系结构

12. 下一步建议

如果你接下来继续学,我建议按这个顺序:

  1. 先彻底理解 Graph / node / edge
  2. 再理解 neighborsdegree
  3. 再看图的性质(Exercise 2)
  4. 最后再碰高级性质和复杂操作

不要一下子想把整份 notebook 全吃掉。先把最前面的基础操作练熟,后面会顺很多。


13. Tutorial Tasks 参考答案

下面是这份 Week 3 notebook 里几个 To Do 的参考完成方式。我按“你刚学”的角度写,尽量简单直接。


Task 1:Create the graph presented in the figure

图中的节点是:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9

图中的边是:

(0,1), (1,2), (1,3), (2,3), (3,4), (4,5), (5,6), (6,7), (7,8), (8,9)

你可以这样创建:

g = nx.Graph()
g.add_nodes_from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
g.add_edges_from([(0,1), (1,2), (1,3), (2,3), (3,4), (4,5), (5,6), (6,7), (7,8), (8,9)])

如果老师要求“用代码检查这个图是不是和图上一样”,除了直接看 nodesedges,也可以结合后面 Exercise 3 学到的函数来测试。

最基础的检查可以写:

print(g.number_of_nodes(), g.number_of_edges())
print(dict(g.degree()))

这样可以快速确认: - 节点数是不是 10 - 边数是不是 10 - 每个节点的 degree 是否和图一致

如果想进一步用 Exercise 3 的图操作函数 来验证,可以抽出图左半部分做检查:

g2 = nx.subgraph(g, [0,1,2,3,4])
print(g2.edges())

这一步的意思是:

从你构造好的图 g 中,取出节点 0,1,2,3,4 对应的子图,看它的边是不是和原图左半部分一致。

理论上应该得到:

[(0,1), (1,2), (1,3), (2,3), (3,4)]

如果你想图形化地检查,也可以:

nx.draw(g, with_labels=True)
nx.draw(g2, with_labels=True)

这里用到的函数

  • nx.Graph():创建空图
  • add_nodes_from():批量加入节点
  • add_edges_from():批量加入边
  • g.number_of_nodes():查看节点总数
  • g.number_of_edges():查看边总数
  • g.degree():查看每个节点的度数
  • nx.subgraph():从原图中取子图(Exercise 3)
  • g2.edges():查看子图中的边
  • nx.draw():把图画出来

Task 2:Report the degree of every vertex

每个节点的 degree(度数)如下:

for node in g.nodes():
print(node, g.degree(node))

输出结果应为:

0 1
1 3
2 2
3 3
4 2
5 2
6 2
7 2
8 2
9 1

解释

  • 节点 0 只连着 1,所以度数是 1
  • 节点 1 连着 0、2、3,所以度数是 3
  • 节点 3 连着 1、2、4,所以度数也是 3
  • 节点 9 只连着 8,所以度数是 1

Task 3:Compute the average degree

平均度数公式是:

average_degree = sum(dict(g.degree()).values()) / g.number_of_nodes()
print(average_degree)

结果是:

2.0

为什么是 2?

因为: - 图里一共有 10 个节点 - 一共有 10 条边 - 无向图的平均度数公式是:

平均度数 = 2 × 边数 / 节点数
= 2 × 10 / 10
= 2

Task 4:Draw the graph resulting from the subgraph code

给定代码:

bunch = [0,1,2,3,4]
g2 = nx.subgraph(g, bunch)

这里的 nx.subgraph() 就是 Exercise 3: Graph Operations 里最重要的函数之一。

这表示:

从原图 g 中,只保留节点 0,1,2,3,4,并保留它们之间原本存在的边。

所以 g2 的边会是:

(0,1), (1,2), (1,3), (2,3), (3,4)

你可以这样画:

nx.draw(g2, with_labels=True)

这个子图长得像: - 0 连着 1 - 1、2、3 形成一个三角的一部分 - 23 也相连 - 3 再连到 4

也就是说,它是原图左上半部分的截取。


Task 5:List one algorithm from NetworkX

你可以写一个最常见、也最容易理解的算法:

nx.betweenness_centrality(G)

作用

它用来计算 betweenness centrality(中介中心性)

意思

中介中心性衡量的是:

一个节点在多少条“最短路径”上充当中间人。

如果一个节点经常出现在别的节点之间的最短路径上,说明它在网络里很重要,像“桥梁”一样。

你也可以这样写答案

One algorithm provided by NetworkX is nx.betweenness_centrality(G), which computes the betweenness centrality of each node in a graph.

如果你想换一个更简单的,也可以写: - nx.degree_centrality(G):度中心性 - nx.clustering(G):聚类系数 - nx.shortest_path(G, source, target):最短路径


14. 建议你在 notebook 中可以直接填写的代码

如果你是为了交 tutorial,我建议直接填这版:

Task 1

g = nx.Graph()
g.add_nodes_from([0,1,2,3,4,5,6,7,8,9])
g.add_edges_from([(0,1), (1,2), (1,3), (2,3), (3,4), (4,5), (5,6), (6,7), (7,8), (8,9)])
print(g.nodes())
print(g.edges())

Task 2

for node in g.nodes():
print(node, g.degree(node))

Task 3

average_degree = sum(dict(g.degree()).values()) / g.number_of_nodes()
print(average_degree)

Task 4

bunch = [0,1,2,3,4]
g2 = nx.subgraph(g, bunch)
nx.draw(g2, with_labels=True)

Task 5

nx.betweenness_centrality(g)

你在文字说明里可以写:

nx.betweenness_centrality(g) computes the betweenness centrality of the nodes in the graph.


15. 总结

这份 Week 3 tutorial 本质上是在教你:

  • 用 Python 建立图结构
  • 用 NetworkX 操作图
  • 用节点和边表示现实世界中的关系网络

如果你是刚入门,最重要的不是一下看懂全部理论, 而是先会:

  • 创建图
  • 加节点
  • 加边
  • 看邻居
  • 看度数

只要这几个会了,你就已经进门了。