首页 > 代码库 > 最优子序列双射算法(optimal subsequence bijection OSB)

最优子序列双射算法(optimal subsequence bijection OSB)

introduction 

     最近在做关于骨架匹配的东西,在骨架匹配中很重要的一点就是将相同类型的骨架点匹配在一起:

                                                               

      如上图所示,骨架匹配的关键就是将图中 1 2 3 ....      A  B  C  D ...         a  b  c  d ...等这些点按同类型聚合起来,马头对应马头,马尾对应马尾。注意到,在上面一排第一个骨架图中有一个异常点“9”,它与另外两个骨架图中的任意一个节点都不对应。

     我们将问题简化一下,将骨架节点简化成实数序列,考虑如下两个序列:a={1 2 3 5}   b={1 2 3 4 5} ,现在让你将两个序列匹配起来,你给的结果是什么?注意到b序列中存在一个异常点"4",a中没有任何一个数字与它对应,我想正常人给出的匹配结果应当是:(1 1) (2 2) (3 3) (5 5),b序列中的4被跳过。实际上所谓的匹配最终得到的结果两个匹配的序列之间的“距离”达到最小,而跳过某一序列的一个元素无疑会增加量序列之间的距离,于是OSB算法为跳过的元素会增加额外的“距离”,或者说额外的“惩罚”,这里的距离指的是两个序列之间的相似程度,这个相似程度根据需求不同而不同,如果是纯的实数序列,那两个数之差的绝对值即可认为是两元素的距离,所有元素距离只和认为是序列距离,在其他情况下可能会有更多的距离表示。

     本文将介绍一种叫做"最优子序列双射"的算法专门处理这种存在异常点的序列的匹配问题,在数据挖掘等领域使用十分广泛。

     首先我们考虑下什么叫所谓的匹配,匹配好坏的度量是什么?当a={1 2 3 5}  和 b={1 2 3 4 5}做匹配的时候,最终的匹配结果应当是两个序列对应元素很相似,也就是得到的序列“距离”最短,这里的距离只是相似度的度量,并非欧氏空间中的距离。所有最优匹配也就是实现序列距离最近的匹配。下面介绍OSB算法如何实现最短距离的匹配。

     首先假设有两个序列  a={a1 a2 ... am}    b={b1 b2 ... bn}   注意到两个序列不等长,定义两个元素之间的距离为d,在原文献中距离d没有特别的规定,这里不妨认为实数abs(ai-bj)为两元素的距离,表示为d(ai-bj),最优子序列双射(OSB)算法的实现是在一个无环有向图中寻找最短距离实现的,有向图的节点为序列对(ai,bj),对 a={a1 a2 ... am}    b={b1 b2 ... bn}两个序列而言,有向图的节点就有m*n个,节点(ai,bj)与节点(ak-bl)之间的边长(权值)为:

                                                           

式子中的C就是上文提到的跳过某个元素的额外距离或者额外惩罚,可以看到,在有向图中寻找最短路径的话,只要往右下的方向一个个过去,带有C的一项就为0,一旦横竖两个方向有跳过某个元素,路径长度就会产生C的整数倍的额外距离。那C的具体值怎么算呢,文献中给出了一个式子:  

                                                 

 

下面以一个简单到无耻的例子展示OSB算法:

计算得C=(1+6^(1/2))/3   三分之一加上根号六      大约一点多不到2    

a={1 2 4}    b={1 4}

有向图的所有节点为:(1 1)   (1 4)  (2 1)  (2 4)  (4 1)   (4 4)

有向图中找最短路径:

最短路径为(1 1)到(4 4 )那条,于是匹配结果为 1对1  4对4     中间的2被跳过