图与最短路径的生信入门 - SpiralKernel/bioinfo-wiki-migrated GitHub Wiki

图与最短路径的生信入门

更新:2026-10-26;状态:可用;验证范围:2026-10-26核对原始与官方资料;本页Python微型计算已执行;人工数据不代表专业软件或真实研究性能。

图由节点和边构成,适合表达“谁与谁连接”,例如工作流依赖、序列片段连接、单细胞近邻和相互作用网络。最短路径则需要先定义“短”:边数少、总权重小或生物代价低并不是同一任务。读完应能建立邻接表、手动执行BFS,并判断算法适用条件。

前置是列表、字典和队列,参见算法输入输出复杂度与数据结构。本页只实现无权图的广度优先搜索,不把“几条边”解释成真实遗传距离。

先把节点和边说清楚

对象 节点 边 不能忽略的条件
工作流 任务 必须先完成 有向、应无环
de Bruijn图 一种表示中为(k−1)-mer k-mer连接 重复、覆盖度、分叉
细胞近邻图 细胞 高维邻近关系 距离、k、批次、权重
蛋白网络 蛋白 实验或计算关联 证据类型与置信度

有向边A→B不自动意味着B→A;无向图邻接表通常需要双向记录。无边节点也属于输入,不能因没有邻居就在分析前静默丢弃。路径的意义由建图规则决定,网络布局图上画得近不等于图距离短。

BFS为什么找到最少边路径

从起点s开始,先访问距离0的节点,再通过队列依次展开距离1、2等各层。节点第一次入队时就记录距离并标记已发现;否则带环图会反复入队。假设每条边代价都是1,首次发现节点时不存在尚未处理的更短路径,因而得到最少边数。

邻接表实现访问每个可达节点和相应边一次,时间O(V+E),额外存储O(V)。它不会访问不可达节点。带非负不同权重时应考虑Dijkstra;允许负边时需别的算法与负环检查。参考MIT算法课程的图与最短路径部分。

跟着队列走一遍

设A连向B和C,B连向D,C也连向D,D连回A,还有独立Z。队列先为[A];展开A后变[B,C];展开B发现D,队列[C,D];展开C不会再加入D。最终A=0、B=C=1、D=2,Z不可达。D的前驱可能随同层访问顺序改变,但最短距离仍为2。

本页例子在项目根目录的Python中运行;标准库例子无需安装包,含NumPy/SciPy的例子先按R包Python包与可复现环境建立项目环境。Windows命令使用python,macOS/Linux可使用python3;代码块可复制进该环境的Python交互会话,或保存为项目根目录下的临时脚本再用该环境解释器运行;不要保存到examples目录或任意外部目录后假定项目导入路径仍相同。除特别说明外,只向屏幕输出,不写文件。

from collections import deque
graph = {'A':['B','C'], 'B':['D'], 'C':['D'], 'D':['A'], 'Z':[]}
distance, parent, queue = {'A':0}, {'A':None}, deque(['A'])
while queue:
    node = queue.popleft()
    for neighbor in graph[node]:
        if neighbor not in distance:
            distance[neighbor] = distance[node] + 1
            parent[neighbor] = node
            queue.append(neighbor)
print('distances', sorted(distance.items()))
print('unreachable', sorted(set(graph) - set(distance)))
assert distance['D'] == 2 and 'Z' not in distance

输出A0、B1、C1、D2以及不可达Z;程序正常结束,说明已发现标记阻止了环的无限展开。可沿parent从D回到A恢复一条路径,再反转。真实图若允许邻接表只列起点,应先补全所有被引用节点;这里显式列全了。

两个常见误用

第一,把无权BFS用于带权距离。若A→B权10、A→C权1、C→B权1,最少边路径A→B成本10,总权重最小路径却为A→C→B成本2。第二,把图连通当成生物因果。细胞近邻受特征选择、降维和参数影响;蛋白网络的一条路径也不证明调控链。

工作流还需要拓扑排序:输出满足所有依赖顺序的节点序列,有环时不存在合法拓扑序。拓扑排序、最短路径和遍历回答不同问题,不能因都使用队列而互换。

排错与自测

症状 检查 处理
队列越来越大 是否首次入队即标记 使用visited或distance
缺少孤立节点 是否只从边生成节点 单独维护完整节点集合
最短距离与手算不符 方向、权重、起点定义 先在三节点反例上核对
工作流无法排序 是否存在依赖环 输出环涉及的任务再修依赖

问:D不可达时应给距离0吗? 答:不应。0表示起点,未知或无穷距离必须另标。问:同一节点有两条最短路径,BFS错了吗? 答:没有;若要所有最短路径,需要保存多个前驱或额外统计,而非把一条parent当作全部答案。向专业场景延伸见单细胞降维邻居图与聚类原理。

接着读什么

算法输入输出复杂度与数据结构 → 单细胞降维邻居图与聚类原理 → R包Python包与可复现环境 → 基础算法可复现练习 → 方法与算法系统学习指南。学习顺序与练习入口见方法与算法系统学习指南。

运行本页的完整小例

先下载项目并进入含README与examples的根目录,环境准备见方法与算法系统学习指南。用项目环境的Python运行以下命令(macOS/Linux路径示例;Windows用.venv\Scripts\python.exe):

.venv/bin/python examples/methods_foundations_demo.py --case bfs --output examples/output/methods-bfs

输出summary.json保存本页计算与检查结果。目录非空时拒绝覆盖,再练习请更换--output目录;页面内短代码只打印结果。标准库case也可用系统Python直接运行。

公式里的矩阵、下标或对数不熟时,可回查读懂方法公式的最小数学基础。