perl聚类

  1. @12@vip.com#20120307/1
  2. BCDBCDBD
  3. +
  4. AAAAAAAA
  5. @18@vip.com#20120307/1
  6. BBDACCDA
  7. +
  8. AAAAAAAA
  9. @13@vip.com#20120307/1
  10. BCDBCDAA
  11. +
  12. AAAAAAAA
  13. @14@vip.com#20120307/1
  14. BCDAAABC
  15. +
  16. AAAAAAAA
  17. @15@vip.com#20120307/1
  18. BCDCCABC
  19. +
  20. AAAAAAAA
  21. @16@vip.com#20120307/1
  22. BCDBBABC
  23. +
  24. AAAAAAAA
  25. @12@vip.com#20120307/1
  26. BBDABBDA
  27. +
  28. AAAAAAAA
  29. ...
我想对上面的数据进行一个聚类,每四行是一段,假设每段第二行前三个字符相同,且后五个字符差异度(对应位置不同,比如BC和BB差异度为1,BC和AB差异度为2)相近的归为一段、类,(计算出所有的差异度,选取差异度最大的那段为第一凝聚点,再在第一凝聚点距离D(D=2d)之外寻找第二凝聚点,依此类推,直到遍历所有为止)

每类之间空行隔开,生成下面这样的结果:

  1. BBD BBD BBDACCDA BBDABBDA
  2. BCD BCD BCDBCDBD BCDBCDAA
  3. BCD BCD BCDAAABC BCDBBABC
  4. BCD BCD BCDAAABC BCDCCABC

————————————————————————————————————————————

    比如:
1、BCDAAABC 2、BCDBBABC 3、BCDCCABC 4、BCDBCDBD 5、BCDBCDAA

五个字符串,1和2的差异度是2;1和3的差异度是2;1和4的差异度是4;1和5的差异度是5;2和3的差异度是2;2和4的差异度是3;2和5的差异度是4;3和4的差异度是3;3和5的差异度是4;4和5的差异度是2;
那么:
   1 2 3 4 5
1 0 2 2 4 5
   0 2 3 4
      0 3 4
         0 2
            0

那么2的频率是最多的,所有差异度为2的归为一类,所以1、2;1、3;4、5;归为一类;所有的都有归类了,就结束。如果还没有结束,再选下一个,也就是4,所有差异度为4的归为一类。。直到所有的归为一类。。。

—————————————————————————————————————————————————
 
 1 #!/usr/bin/perl
 2 my ( $A, $B ) = ( 3, 5 );
 3 my ( @A, %G );
 4 
 5 while (<>) {
 6     chomp( my $L = <> );
 7     push @A, $L; <>, <>;
 8 }
 9 
10 for my $i ( 0 .. $#A - 1 ) {
11     for my $j ( $i + 1 .. $#A ) {
12         next if substr( $A[$i], 0, $A ) ne substr( $A[$j], 0, $A );
13         my $dif;
14         substr( $A[$i], $_, 1 ) ne substr( $A[$j], $_, 1 ) and $dif++
15           for $A .. $A + $B - 1;
16         push @{ $G{$dif} }, [ $i, $j ];
17     }
18 }
19 
20 for my $v ( sort { @$b <=> @$a } values %G ) {
21     for my $ij (@$v) {
22         my @H = map substr( $A[$_], 0, $A ), @$ij;
23         print join( "\t", @H, @A[@$ij] ), $/;
24     }
25     print $/;
26 }

 

posted on 2013-12-13 10:40  三川  阅读(473)  评论(0编辑  收藏  举报