每天早高峰,你站在地铁线路图前,看到的是站点与轨道编织成的一张网。这张图刻意省略了地理距离——五棵松和海淀黄庄之间实际隔了几公里并不重要,重要的是“它们是不是相邻的两站”。计算机科学家把这种“只关心谁和谁相连”的抽象方式,叫做图(Graph)。 图由两个基本零件组成:像地铁站点一样的节点,和像轨道一样的边。如果把微信好友、分子原子、城市路口都放进这个模型里,你会惊喜地发现:它们全都是“站点+轨道”的变装。而这正是当下大热的图神经网络(GNN)的第一块地基——机器要读懂关系型数据,先要会表示这张“网”。 这篇文章会用地铁系统的语言,带你认识图神经网络大门前的所有基础概念:节点、边、邻接矩阵、度、图的类型与属性。学完以后,你再看社交推荐、分子预测、路径规划这些AI应用,会多出一双“看穿结构”的眼睛。
图数据是推荐系统、社交分析、分子发现与路径规划的共同底座。掌握图的概念,等于拿到进入GNN世界的首张通行证——对AI从业者而言,这是处理关系型数据必备的基础能力。
可视化演示
展示图的节点边结构、有向无向边类型,以及邻接矩阵的数学表示,直观理解图数据的组织方式。
本节配有交互动效(进入视口后自动加载,约 3KB)。
图结构与边类型 节点表示实体对象,边表示实体间的关系,图能自然表达社交网络等复杂数据 无向边没有方向性,有向边具有方向,边可带权重表示关系强度 节点的度数表示连接的边数,有向图分为入度和出度 G = (V, E) 图由节点集合V和边集合E构成。
图的定义
每天早高峰,你站在地铁线路图前,看到的是站点与轨道编织成的网。这张图刻意省略了地理距离——五棵松和海淀黄庄之间实际隔了几公里并不重要,重要的是“它们是相邻的两站”。计算机科学家把这种“只关心谁和谁相连”的抽象方式,称为图。图的迷人之处,正在于它敢于丢弃次要信息,只保留关系本身。
顺着这个思路,图用两个集合描述世界。第一个集合装下所有研究对象,叫顶点集,记作V,地铁图中就是每一个站点;第二个集合装下所有连接关系,叫边集,记作E,站与站之间的轨道就是一条条边。把这两个集合打包进一个括号,就得到了一张完整的图。
举一个具体的例子。假设一张迷你地铁图只有A、B、C三个站,A与B、B与C之间通着轨道,那么 \( V=\{A,B,C\} \),\( E=\{(A,B),(B,C)\} \)。城市再大,图的骨架也不过是这两份清单。AI处理图数据时,第一步就是把对象与关系整理成计算机能读的结构。
1. 顶点集 V:图中所有节点的集合,地铁图里就是全部站点的名录。
2. 边集 E:所有“谁连谁”的关系,每条边连接两个顶点。
3. 元组打包:用圆括号把顶点集和边集合成一个整体,得到图。
下次等地铁时再看线路图,你会发现自己已经拥有了“图视角”:任何复杂系统,都可以先问一句——对象是什么?连接是什么?把这两个问题回答清楚,你就画出了一张图的骨架。
\displaystyle G = (V, E)节点与边
走进任何一座地铁站,你第一眼看到的是站名和换乘标识。同一个站,多条线路交汇,就像一个人同时是程序员、长跑爱好者、猫奴——这些“标签”是节点自带的特征。而站与站之间的轨道,可能长3公里也可能长15公里,可能在地上也可能在地下——这些属性是边的特征。节点与边,就是图世界的“原子”与“化学键”。
有了节点和边,第一个要回答的问题是“这个节点有多重要”。地铁调度员会告诉你:看它连着几条轨道。一个站直接连通的轨道数,就是它的度。度越大的站,越是网络中的枢纽。在三环线上,某个换乘站连着四五条线路,度就高;一个偏僻的终点站只有一条线路,度就是1。
为了把“度”说精确,我们引入邻居的概念:与某个节点直接相连的其他节点,叫它的邻居。节点v的度,等于它有多少个邻居。
1. 邻居集合 N(v):先找出所有与v直接相连的节点。
2. 集合大小:竖线 |·| 表示“这个集合里有多少个元素”。
3. 度即邻居数:把两步合在一起,度就是邻居的数量。
在无向图里,一条边为两端的节点各贡献1度,所以所有节点的度加起来等于边数的两倍——这个规律后面还会用到。度越大的节点,在地铁网里是换乘枢纽,在社交网络里就是“社牛”;在分子里,度大的原子往往是活泼的化学中心。读懂度,就迈出了理解图结构的第一步。
邻接矩阵
地铁调度中心不会把整面墙都挂上线路图,而是用一张巨大的表格管理“哪站通哪站”。这张表的最上面一行和最左边一列,依次列出全部站点;如果第i站和第j站之间通着轨道,就在第i行第j列的交叉格子里打一个勾。这张“打勾表”,就是邻接矩阵。
邻接矩阵是图在计算机里的“身份证”。它的规则简单到不能再简单:有边记1,无边记0。第i行第j列的元素,记录的是“第i个节点与第j个节点是否相连”。
1. 矩阵定位:\(A_{ij}\) 表示第 i 行第 j 列的格子,对应节点 \(v_i\) 与 \(v_j\)。
2. 判定条件:检查 \(v_i\) 和 \(v_j\) 之间是否存在一条边。
3. 分情况取值:存在边取1,否则取0,这就是完整的规则。
邻接矩阵有一个明显的坏处:空间复杂度。n个节点就需要 \(n \times n\) 个格子。5个站只要25格,1000个站就是100万个格。真实社交网络动辄数亿用户,矩阵会膨胀到天文数字。于是有了邻接表——只记录“有边的邻居”,像手机通讯录只存打过电话的人,稀疏图里又省空间又方便找邻居。邻接矩阵忠实但笨重,邻接表轻巧但查询稍慢,两者各有各的舞台。
图的类型
地铁隧道大多是双向的,但有些换乘通道只允许单向通行。如果轨道只允许从A站开向B站,不允许从B站开向A站,这就成了有向图。微博里你关注了大V,大V不一定关注你——这就是有向边;微信加好友必须双方同意,这就是无向图的“双向互通”。
现实世界中的图,很少只有“通”和“不通”两种状态。高速路按里程收费,导航按预计时间规划路线——这种每条边都带着一个数字的图,叫带权图。那串数字叫权重,可以是距离、时间、票价。另外还有连通图:从任意一个站出发,沿着轨道总能抵达任意另一个站,这说明整个网络是一体的;否则图会分裂成几个互不相通的板块。
不同类型图中,度的统计方式也不同。但无论怎么统计,无向图都遵守一条优美的规律:
1. 求所有度之和:把图中每个节点的度累加起来。
2. 每条边贡献两次:一条边有两个端点,各被计入1度。
3. 合并恒等式:两步合起来,就是握手引理。
有向、带权、连通,这三个标签决定了图数据如何建模。社交推荐常用无向好友图,排行榜用有向关注图,路径规划用带权有向图。选定图的类型,就像选定地铁制式——是双轨还是单轨,要不要计费,是否全城成网,都直接影响后续的一切算法设计。
图的属性
从西直门到东直门,你可以坐2号线直达,也可以换乘4号线再转13号线——每一种走法都是一条路径。路径就是由边首尾相接组成的一条链,它回答了“怎么从A到B”的问题。在一张图里,路径可能有很多条,有的短、有的长、有的绕路。
路径的长度怎么算?在普通地铁图里,长度是“经过了几段轨道”;在带权图里,长度是“经过的轨道的时间或里程之和”。导航软件报出的“预计45分钟”,本质上就是一条带权路径的总权重。
1. 路径 P:一条从起点到终点的节点序列,相邻节点间都有边。
2. 边权重求和:对路径上的每条边取权重并累加。
3. 无权图特例:每条边权重视为1,长度就是边数。
路径走成一个圈,起点和终点重合,就成了环。地铁10号线就是一个环,列车绕着圈跑。环的存在让图变得更有趣:它意味着“循环依赖”,也意味着消息可以在图里反复流转。如果一张图分裂成几个互不相连的部分,每个部分内部连通、彼此隔绝,这些部分就叫连通分量——像同一座城市里两家地铁公司各跑各的、从不换乘。理解了路径、环与连通分量,你就掌握了图的结构骨架。GNN正是沿着路径传递消息,借助环形成深层表达,再在连通分量间做归纳。
图的应用
地铁图是图,但“站点+轨道”这个模型一旦抽象出来,仿佛获得了变形能力——换上不同的解释,就成了完全不同的领域。微信好友关系里,用户是节点,好友关系是边。推荐算法想推荐新朋友,就先看看“朋友的朋友”里有没有你认识的人,这正是图最朴素也最有效的应用。
药物研发中,分子被建模成分子结构图:原子是节点,化学键是边。传统程序靠人工设计分子特征,费时费力;GNN直接从图结构上学习,预测某个化合物有没有毒性、能不能溶解,帮助科学家在数以百万计的候选分子中快速筛选。这是图在科研领域最激动人心的舞台之一。
交通网络就更直观了:路口是节点,道路是边,红绿灯等待时间和里程是权重。外卖平台的骑手路线、地图导航的推荐方案,都是在带权图上寻找最短路径。可以说,推荐系统、金融风控、知识图谱、交通调度,全都建立在图的基础之上——图给了AI一双看清“联系”的眼睛。
回到地铁场景:你每天看的线路图,就是图神经网络的第一课。掌握了节点、边、邻接矩阵、度、图的类型与属性,你已经拿到了进入GNN世界的第一把钥匙。下一步,就是让神经网络学会“阅读”这张网上的信息流动。
AI 应用场景
社交好友推荐
阶段:数据表示与特征提取
解决的问题:传统协同过滤只看“用户-商品”打分矩阵,难以利用用户之间的社交关系。把用户建模为节点、好友关系建模为无向边,图结构天然携带“朋友的朋友”等高阶信息,推荐更精准。
具体案例:某社交App构建全员无向好友图,统计每个用户的二跳邻居(朋友的朋友)出现频次,按共同好友数排序生成“你可能认识的人”。对比传统协同过滤,推荐点击率提升约20%。
分子性质预测
阶段:模型输入构建
解决的问题:分子性质预测传统依赖手工专家特征,信息损失大。将分子表示为图——原子是节点,化学键是边,GNN直接在结构上学习,无需人工设计指纹特征。
具体案例:某药企用GNN预测化合物毒性与溶解度,将SMILES字符串转为分子图结构,在MoleculeNet公开数据集上AUC达到0.85以上,显著快于传统QSAR方法。
物流路径规划
阶段:推理与决策
解决的问题:配送路线优化传统靠人工经验,无法实时应对拥堵。把路网建模为带权有向图,权重=预估通行时间,再用图搜索算法求解最短路径。
具体案例:某外卖平台维护实时路网图,高峰期动态更新道路权重,骑手平均配送时长降低12%,超时率下降近三分之一。
Python 演示
class Graph: """无向图: 用邻接矩阵表示""" def __init__(self, num_nodes): self.num_nodes = num_nodes self.adj_matrix = [[0] * num_nodes for _ in range(num_nodes)] def add_edge(self, u, v): self.adj_matrix[u][v] = 1 self.adj_matrix[v][u] = 1 def degree(self, v): return sum(self.adj_matrix[v]) def neighbors(self, v): return [i for i in range(self.num_nodes) if self.adj_matrix[v][i] == 1] def print_matrix(self): for row in self.adj_matrix: print(' '.join(str(x) for x in row)) if __name__ == '__main__': # 5个地铁站: 0=A 1=B 2=C 3=D 4=E g = Graph(5) edges = [(0, 1), (0, 2), (1, 2), (2, 3), (3, 4)] for u, v in edges: g.add_edge(u, v) print('邻接矩阵:') g.print_matrix() print('C站(索引2)的度:', g.degree(2)) print('C站的邻居:', g.neighbors(2))
self.adj_matrix = [[0] * num_nodes for _ in range(num_nodes)]用列表推导式创建 n×n 的全0矩阵。注意不能写成[[0]*n]*n,否则每行是同一个列表的引用,改一行全部行都会变。self.adj_matrix[u][v] = 1在 u 行 v 列打上“有边”标记。self.adj_matrix[v][u] = 1无向图对称性:v 到 u 也必须标记。return sum(self.adj_matrix[v])求第 v 行的和,1 的个数就是该节点的度。return [i for i in range(self.num_nodes) if self.adj_matrix[v][i] == 1]扫描 v 行,值为 1 的列索引就是邻居。g = Graph(5)创建5节点图,模拟A-E五个地铁站。for u, v in edges: g.add_edge(u, v)逐条铺设边,构建迷你地铁网。
常见误区
误区一听到“图”,就想到照片、插画、Excel折线图,以为“图神经网络”就是处理图像的神经网络。
正解此“图”非彼“图”。在数据结构中,图是“节点+边”的关系网络。地铁线路图、微信好友关系、分子结构都是图;而照片是像素矩阵,属于图像。图神经网络处理的是关系网络,不是像素。
为何常见:中文“图”一词多义,加上“图神经网络”与“图像识别”两个领域中文名相近,初学者极易混淆。
误区既然树是图的一种,那么所有图都像树一样有根节点、有层次结构、没有环。
正解树是无环连通图的一个特例,但一般图可以有环、可以有孤立节点、可以不连通。地铁10号线是环,微博互关形成的循环也是环——它们都是图,但都不是树。
为何常见:大多数学习者先接触二叉树,“分层”的印象根深蒂固,容易把树的限制错当成图的性质。
误区学完邻接矩阵后,觉得这种表示简单又直观,认为所有图都应该用矩阵来存。
正解矩阵占 \(O(V^2)\) 空间,稀疏图(边很少)浪费巨大。十亿用户的社交网络根本存不下。邻接表只记录有边的邻居,稀疏图下既省内存,遍历邻居也更快。两种表示要看图的稀疏程度来选择。
为何常见:课堂上的小例子只有5个节点,矩阵看着整齐又美观,掩盖了数据规模爆炸时的问题。
误区数度的时候,觉得一条无向边被两个端点各算一次是多算了,认为总度应该等于边数。
正解无向图中一条边确实为两个端点各贡献1度,所以总度等于 \(2|E|\)。这不是多算,而是握手引理的本质:每个度代表一次“端点关联”。A-B一条边,A的度加1,B的度也加1,总共加2。
为何常见:有向图里入度和等于边数,先学有向图再学无向图时,容易把两种统计方式搞混。
误区把有向图的度也简单数成“邻居个数”,忽略边的方向。
正解有向图的边有方向。入度=指向自己的边数,出度=自己指出的边数。微博里你关注别人是出度,别人关注你是入度。入度和=出度和=边数,这是有向图独有的规律。
为何常见:无向图“度=邻居数”太简洁经典,学到有向图时思维没有切换,把方向信息丢掉了。
面试题
Q1. 图 \(G=(V, E)\) 中的 V 表示什么?
- A.边的集合
- B.顶点的集合← 正确答案
- C.邻居的集合
- D.矩阵的集合
答案:B。图由顶点集 V 和边集 E 组成,V 是全部节点的集合,E 是全部边的集合。地铁图中站点是 V,轨道是 E。A 描述的是 E,C、D 与定义无关。
Q2. 无向图中节点 v 的度等于什么?
- A.全图节点数
- B.邻居节点数← 正确答案
- C.边的总数
- D.矩阵对角线元素
答案:B。无向图中度定义为邻居节点的个数,即与 v 直接相连的节点数。地铁站连着几个站,度就是几。C 是整张图的边数,与单个节点的度无关。
Q3. 一个无向图有10个节点,每个节点的度都是3,则图中边的总数是多少?
- A.等于10条边
- B.等于15条边← 正确答案
- C.等于20条边
- D.等于30条边
答案:B。由握手引理,所有节点度之和等于 \(2|E|\)。这里度之和为 \(10 \times 3 = 30\),所以 \(2|E|=30\),解得 \(|E|=15\)。30 是度之和,不是边数。
Q4. 邻接矩阵中 \(A[i][j]=1\) 表示什么?
- A.i到j没有连线
- B.i和j之间有条边← 正确答案
- C.i的度数等于j
- D.i是j的邻居
答案:B。邻接矩阵规则是有边记1、无边记0,\(A[i][j]=1\) 说明第 i 个节点和第 j 个节点之间存在一条边。A 说反了,C、D 是度的概念而非矩阵元素含义。
Q5. 有向图节点 v 的入度为2、出度为3,以下说法正确的有?
- A.总度数等于5← 正确答案
- B.总度为入度加出度← 正确答案
- C.邻居数一定是5
- D.出度大于入度← 正确答案
答案:ABD。有向图节点总度=入度+出度=2+3=5,A、B 正确;出度3大于入度2,D 正确。C 错误——有向图中邻居分前驱和后继,不能简单说邻居一共5个。
Q6. 关于邻接矩阵,下列说法正确的有?
- A.无向图的矩阵对称← 正确答案
- B.空间复杂度较大← 正确答案
- C.稀疏图更省空间
- D.对角线一定为0
答案:AB。无向图边无方向,所以 \(A[i][j]=A[j][i]\),矩阵对称,A 正确;矩阵占 \(O(V^2)\) 空间,B 正确。稀疏图用邻接表更省空间,C 错误;对角线在存在自环时才非0,不能说一定为0,D 错误。
Q7. 有向图中所有节点的入度之和等于什么?
- A.节点总数总和
- B.边的总数目← 正确答案
- C.出度和的一半
- D.节点数的两倍
答案:B。有向图中每条边恰好贡献1个入度和1个出度,所以所有入度之和=所有出度之和=边数。类比单向通道:每条单行道只有一个入口和一个出口,入口总数等于道路总数。
Q8. 以下哪些属于图的应用场景?
- A.社交网络推荐← 正确答案
- B.分子结构建模← 正确答案
- C.导航路径规划← 正确答案
- D.数组快速排序
答案:ABC。社交网络用好友关系图做推荐,分子用原子-键图建模性质,导航用路网图规划路径,三者都是图的典型应用。快速排序是数组上的算法,与图结构无关。
Q9. 一个有向图的邻接矩阵中,非零元素的个数等于什么?
- A.节点总数个数
- B.边的总数个数← 正确答案
- C.两倍边的个数
- D.度数之和大小
答案:B。有向图每条边对应矩阵中的一个非零元素(只记一次方向)。而无向图因对称性,每条边会出现在两个对称位置,所以非零元素是边数的两倍。此题考的是有向图与无向图在矩阵表示上的关键区别。
Q10. 在带权图中,一条路径的长度是指什么?
- A.经过的边权重和← 正确答案
- B.经过的节点数量
- C.起点到终点距离
- D.经过的边数量
答案:A。带权图中路径长度=路径上所有边的权重之和,如导航中的预计时间总和。B 是节点数,D 是无权图的长度,C 的“直线距离”忽略了实际路径,均不正确。