1 package jp.sourceforge.stigmata.birthmarks.osb;
3 import jp.sourceforge.stigmata.Birthmark;
4 import jp.sourceforge.stigmata.BirthmarkContext;
5 import jp.sourceforge.stigmata.BirthmarkElement;
6 import jp.sourceforge.stigmata.birthmarks.comparators.AbstractBirthmarkComparator;
7 import jp.sourceforge.stigmata.birthmarks.osb.hungarian.CostMatrix;
8 import jp.sourceforge.stigmata.birthmarks.osb.hungarian.HungarianMethod;
9 import jp.sourceforge.stigmata.spi.BirthmarkService;
13 * @author Fumiya Iwama
14 * @author Ryouta Obatake
15 * @author Akinori Kataoka
16 * @author Takayuki Kitano
18 public class OperandStackBehaviorsBirthmarkComparator extends AbstractBirthmarkComparator{
19 public OperandStackBehaviorsBirthmarkComparator(BirthmarkService spi){
24 public double compare(Birthmark b1, Birthmark b2, BirthmarkContext context){
25 BirthmarkElement[] elementsA = b1.getElements();
26 BirthmarkElement[] elementsB = b2.getElements();
28 //両方0だったら(片方でも0だったら、return0)
29 if(elementsA.length != 0 && elementsA.length != 0){
30 double[][] sim = createMatrix(elementsA,elementsB);
31 // matchには、類似度の合計値が最大となる値が入る
32 double match = calculateMatch(sim);
33 // BehaviorSetのBehaviorの数のうち、大きい方を max に代入
34 int max = Math.max(elementsA.length, elementsB.length);
36 return match / max;//Similarityを返す
43 public double compare(BirthmarkElement element1, BirthmarkElement element2){
44 if(element1 instanceof OperandStackBehaviorsBirthmarkElement &&
45 element2 instanceof OperandStackBehaviorsBirthmarkElement){
46 return ((OperandStackBehaviorsBirthmarkElement)element1).getSimilarity(
47 (OperandStackBehaviorsBirthmarkElement)element2
50 throw new IllegalArgumentException("only OperandStackBehaviorBirthmarkElement");
53 protected double[][] createMatrix(BirthmarkElement[] elementsA, BirthmarkElement[] elementsB){
54 double[][] matrix = new double[elementsA.length][elementsB.length];//simは実数だからdouble
55 for(int i = 0; i < elementsA.length; i++){
56 for(int j = 0; j < elementsB.length; j++){
57 OperandStackBehaviorsBirthmarkElement osb1 = (OperandStackBehaviorsBirthmarkElement)elementsA[i];
58 OperandStackBehaviorsBirthmarkElement osb2 = (OperandStackBehaviorsBirthmarkElement)elementsB[j];
59 matrix[i][j] = osb1.getSimilarity(osb2);
67 * @param matrixArray Birthmarkの要素間の類似度をまとめた2次元配列.
68 * @return 類似度の和が最大となるよう組み合わせた値.
70 protected double calculateMatch(double[][] matrixArray){
71 CostMatrix matrix = new CostMatrix(matrixArray, true);
72 HungarianMethod method = new HungarianMethod(matrix);
74 return method.solve();