当前位置: 首页 > news >正文

【匹配】Hirschberg

Hirschberg

文章目录

  • Hirschberg
    • 1. 算法介绍
    • 2. 公式及原理
    • 3. 伪代码

1. 算法介绍

  • 背景与目标
    Hirschberg 算法由 Dan Hirschberg 于1975年提出,是对 Needleman–Wunsch 全局比对的内存优化,通过分治策略将空间复杂度从 O ( m n ) O(mn) O(mn) 降到 O ( min ⁡ ( m , n ) ) O(\min(m,n)) O(min(m,n)),但仍保持 O ( m n ) O(mn) O(mn) 的时间复杂度。

    核心目标:在内存受限的情况下,仍能获得两条序列的最优全局比对结果。

  • 应用场景

    • 在大规模或内存受限环境(如嵌入式设备)中做序列全局比对
    • 对长序列(数万甚至数十万长度)进行比对而不爆内存
    • 作为组合更复杂比对算法的空间优化子例程
  • 核心思路

    1. 线性空间动态规划——用两行滚动数组计算 Needleman–Wunsch 得分向量;
    2. 分治分割——将序列 A A A 在中点处分成左右两段,分别对左半段与 B B B 做“正向” DP,对右半段与 B B B 做“反向” DP;
    3. 寻找最优分割点——在 B B B 上找到使前后两段得分和最大的分割索引;
    4. 递归对齐——分治地对两对子序列递归调用 Hirschberg,还原最终全局对齐。

2. 公式及原理

2.1 线性空间 DP
对长度为 m m m 的序列 A A A 和长度为 n n n 的序列 B B B,标准 NW 填表需要维护 ( m + 1 ) × ( n + 1 ) (m+1)\times(n+1) (m+1)×(n+1) 矩阵。Hirschberg 只保留当前行和上一行:

score curr [ j ] = max ⁡ ⁣ { score prev [ j − 1 ] + s ( a i , b j ) , score prev [ j ] − d , score curr [ j − 1 ] − d . \text{score}_{\text{curr}}[j] = \max\!\begin{cases} \text{score}_{\text{prev}}[j-1] + s(a_i, b_j),\\ \text{score}_{\text{prev}}[j] - d,\\ \text{score}_{\text{curr}}[j-1] - d. \end{cases} scorecurr[j]=max scoreprev[j1]+s(ai,bj),scoreprev[j]d,scorecurr[j1]d.

这样每次只用 O ( n ) O(n) O(n) 空间计算出一行得分向量。

2.2 分治分割
A A A 分为两半 A L = A [ 1.. ⌊ m / 2 ⌋ ] A_{\text{L}}=A[1..\lfloor m/2\rfloor] AL=A[1..m/2⌋] A R = A [ ⌊ m / 2 ⌋ + 1.. m ] A_{\text{R}}=A[\lfloor m/2\rfloor+1..m] AR=A[⌊m/2+1..m]

  • 正向得分:对 A L A_{\text{L}} AL B B B 用线性空间 DP,得到得分向量 F [ j ] F[j] F[j](代表对齐到 B [ 1.. j ] B[1..j] B[1..j] 的最优得分)。
  • 反向得分:对反转后的 A R A_{\text{R}} AR 和反转后的 B B B 做同样 DP,得到向量 G [ j ] G[j] G[j](对应对齐到尾部 B [ j + 1.. n ] B[j+1..n] B[j+1..n])。
  • 合并:在所有划分点 j ∈ [ 0.. n ] j\in[0..n] j[0..n] 上计算 F [ j ] + G [ n − j ] F[j]+G[n-j] F[j]+G[nj],取最大者 j ∗ j^* j 作为最佳分割。

2.3 递归重构
按分割索引将问题分为两对子序列 ( A L , B [ 1.. j ∗ ] ) (A_{\text{L}}, B[1..j^*]) (AL,B[1..j]) ( A R , B [ j ∗ + 1.. n ] ) (A_{\text{R}}, B[j^*+1..n]) (AR,B[j+1..n]),递归调用 Hirschberg;当子问题中某条序列长度为 0 或 1 时,退化回标准 Needleman–Wunsch 或简单对齐,完成回溯。


3. 伪代码

# 输入
#   A[1..m], B[1..n]
#   s(a,b): 匹配得分函数
#   d: 线性 gap penalty
# 输出
#   aligned_A, aligned_Bfunction Hirschberg(A, B):m ← length(A); n ← length(B)# 基本情况:若一条序列长度 ≤ 1,用标准 NW 直接对齐if m == 0:return repeat('-', n), Bif n == 0:return A, repeat('-', m)if m == 1 or n == 1:return NeedlemanWunsch(A, B, s, d)# 1) 分割 Amid ← ⌊m/2⌋A_L ← A[1..mid];   A_R ← A[mid+1..m]# 2) 正向 DP:A_L vs B → F[0..n]F ← NW_ScoreVector(A_L, B, s, d)# 3) 反向 DP:reverse(A_R) vs reverse(B) → G[0..n]G_rev ← NW_ScoreVector(reverse(A_R), reverse(B), s, d)G ← reverse(G_rev)# 4) 找到最佳分割点 j*best_j, _ ← argmax_{j=0..n} (F[j] + G[j])# 5) 递归对齐左右两段(A1, B1) ← Hirschberg(A_L,   B[1..best_j])(A2, B2) ← Hirschberg(A_R,   B[best_j+1..n])return (A1 ∥ A2), (B1 ∥ B2)# 辅助:计算 DP 得分向量(只返回最后一行)
function NW_ScoreVector(X, Y, s, d):n ← length(Y)prev[0..n] ← [0, -d, -2d, …, -n·d]for i in 1..length(X):curr[0] ← -i·dfor j in 1..n:match  ← prev[j-1] + s(X[i], Y[j])delete ← prev[j]   - dinsert ← curr[j-1] - dcurr[j] ← max(match, delete, insert)prev ← currreturn prev
  • 时间复杂度 O ( m × n ) O(m \times n) O(m×n)
  • 空间复杂度 O ( n ) O(n) O(n)(额外递归栈 O ( log ⁡ m ) O(\log m) O(logm),总 O ( n + log ⁡ m ) O(n + \log m) O(n+logm)

相关文章:

  • ​小店推客系统开发SEO全攻略:从技术架构到流量裂变,打造私域增长引擎
  • 代码随想录算法训练营第三十八天打卡
  • 文章记单词 | 第86篇(六级)
  • Guided Filtering相关记录
  • EC800X_DP-DTU-Q600R 系列开发板介绍
  • Gen5 应用实例
  • 主打「反激进」的一汽丰田,靠稳扎稳打的技术实现突围
  • 梁文锋署名,DeepSeek-V3新论文揭秘:低成本大模型训练如何突破算力瓶颈?
  • 【omnet++】omnet++6.0.3中调用python
  • 主流数据库排查与优化速查手册
  • [Unity]AstarPathfindingProject动态烘焙场景
  • 播放进度条小组件
  • C#学习教程(附电子书资料)
  • 413 Payload Too Large 问题定位
  • 【Win32 API】 lstrcpynA()
  • 直接从图片生成 html
  • [Lc] 5.16 One question a day周总结
  • 道路运输企业管理人员考试真题练习
  • 线程和进程
  • CSPM-3级考试成绩已出!附查询流程
  • 广西鹿寨一水文站“倒刺扶手”存安全隐患,官方通报处理情况
  • 首映|《星际宝贝史迪奇》真人电影,不变的“欧哈纳”
  • 孙卫东会见巴基斯坦驻华大使:支持巴印两国实现全面持久停火
  • 新能源汽车,告别混乱创新
  • 2025年上海科技节5月17日启动,56家重点实验室和大科学设施将向公众开放
  • 挖掘机4月销量同比增17.6%,出口增幅创近两年新高