OSDN Git Service

BirthmarkSpi -> BirthmarkService
[stigmata/stigmata.git] / src / main / java / jp / sourceforge / stigmata / birthmarks / comparators / LogicalAndBirthmarkComparator.java
1 package jp.sourceforge.stigmata.birthmarks.comparators;
2
3 import java.util.HashSet;
4 import java.util.Set;
5
6 import jp.sourceforge.stigmata.Birthmark;
7 import jp.sourceforge.stigmata.BirthmarkContext;
8 import jp.sourceforge.stigmata.BirthmarkElement;
9 import jp.sourceforge.stigmata.spi.BirthmarkService;
10
11 /**
12  * this comparator calculate following formula.
13  * let f(p) and f(q) be given birthmarks, then
14  * similarity of those birthmarks are defined by |f(p) and f(q)|/|f(p) or f(q)|.
15  * 
16  * @author Haruaki TAMADA
17  */
18 public class LogicalAndBirthmarkComparator extends AbstractBirthmarkComparator{
19     public LogicalAndBirthmarkComparator(BirthmarkService spi){
20         super(spi);
21     }
22
23     @Override
24     public double compare(Birthmark b1, Birthmark b2, BirthmarkContext context){
25         if(!b1.getType().equals(b2.getType())){
26             return Double.NaN;
27         }
28
29         BirthmarkElement[] element1 = b1.getElements();
30         BirthmarkElement[] element2 = b2.getElements();
31         Set<BirthmarkElement> set1 = new HashSet<BirthmarkElement>();
32         for(int i = 0; i < element1.length; i++) set1.add(element1[i]);
33         Set<BirthmarkElement> set2 = new HashSet<BirthmarkElement>();
34         for(int i = 0; i < element2.length; i++) set2.add(element2[i]);
35
36         Set<BirthmarkElement> set = new HashSet<BirthmarkElement>();
37         for(BirthmarkElement elem: set1){
38             if(set2.contains(elem)) set.add(elem);
39         }
40         for(BirthmarkElement elem: set2){
41             if(set1.contains(elem)) set.add(elem);
42         }
43
44         int len = set1.size() + set2.size();
45         int frac = set.size() * 2;
46
47         double similarity = (double)frac / (double)len;
48         if(len == 0 && frac == 0){
49             similarity = 1d;
50         }
51         return similarity;
52     }
53
54     @Override
55     public int getCompareCount(Birthmark b1, Birthmark b2){
56         return b1.getElementCount() + b2.getElementCount();
57     }
58 }