在上一篇文章中,我们介绍了Kendall tao 距离,并且引入了逆序对的概念.文章的最后还留了一个问题,即已经知道了逆序对为什么还不能直接求两个排列的相似度
大家有没有想过一个问题,逆序对是针对一个排列来说的,而我们要求的是两个排列的相似度,那么用哪个排列来确定逆序对呢? 比如有如下两个序列A和B:
A: a c d e
B: d e c a
是用A还是B来确定逆序对呢? 答案既不是A也不是B,那是谁呢?继续往下看:
建立映射
这里稍微有点烧脑,我尽量用简洁的文字说明白.
对于两个排列,我们总是可以通过改变其中一个排列的元素位置来得到另一个排列.也就是说,可以把其中一个排列看成基准排列,而另外一个是在基准排列的基础上进行位置的调整.还是以上面的A,B为例. 如果我们把A看成基准排列,那么通过改变元素的位置就可以得到B,反之亦然.
那怎么把A表示成基准排列呢? 给A的每个元素按顺序分配一个编号,比如0,1,2,.. ,理论上你可以用其他的编号方式,但是为了计算机处理方便,我们采用0,1,2,..这种方式. 大家可以想一下为什么?
因为像排列这样的顺序数据,我们在计算机中大都采用数组来存储.数组的的索引正好是0,1,2,..这些值
那么我们通过下面的映射关系来把A表示成基准排列
| 元素 | 编号 |
|---|---|
| a | 0 |
| c | 1 |
| d | 2 |
| e | 3 |
根据上面的分析我们知道,0不光代表a对应的编号,还表示存放在0号位置,1不光代表c的编号,还表示存放到了1号位置,依次类推.我们就是通过这种映射关系来将A表示成了基准排列.
注意 元素不能有重复项
因为A和B拥有相同的元素,根据基准排列的映射关系,我们可以把B表示成如下表格
| 元素 | 编号 |
|---|---|
| d | 2 |
| e | 3 |
| c | 1 |
| a | 0 |
我们知道编号不仅可以代表元素本身,也代表了元素的位置.当我们由A变到B时,不仅意味着元素从a,c,d,e调整为d,e,c,a,也意味着元素位置从0,1,2,3调整为2,3,1,0. 而从0,1,2,3调整为2,3,1,0,不可避免地产生了多个逆序对,产生多少个逆序对呢?我们可以通过计算2,3,1,0的逆序对来得到.
此时让我们回顾一下上面的过程:
- 两个排列的相似度问题,可以理解为从一个排列转化为另一个排列的问题,第一个排列称为基准排列
- 通过基准排列的映射关系得到另一个排列的编号序列.编号序列本身也代表元素的位置.
- 位置的变化会产生逆序对,通过计算B对应的编号序列的逆序对最终我们可以得到距离
讲到这里我们可以回到文章刚开始的问题了,应该基于哪个排列来得到逆序对呢?答案就是B对应的编号序列.
从上面的分析我们也可以知道,不管两个排列具体存储的是什么数据类型,我们实际上可以通过编号(一般都是数组索引)来代表这些元素计算相似度.理解这一点会给我们程序处理带来极大便利.