// Path: src/treecmp/metric/TripletMetric.java
// public class TripletMetric extends BaseMetric implements Metric {
//     private TripletMetric2 tt2;
//   public TripletMetric(){
//       super();
//       tt2 = new TripletMetric2();
//   }
// 
//     public double getDistance(Tree t1, Tree t2, int... indexes) {
// 
//         if (TreeCmpUtils.isBinary(t1, true) && TreeCmpUtils.isBinary(t2, true)) {
//             return getDistForBinary(t1, t2);
//         }
//         //run distance for arbitrary tree in O(n^2) time
//         return tt2.getDistance(t1, t2);
// 
//     }
// 
//     public double getDistForBinary(Tree t1, Tree t2) {
//         IdGroup id1 = TreeUtils.getLeafIdGroup(t1);
//         int[][] lcaMatrix1 = TreeCmpUtils.calcLcaMatrix(t1, null);
//         int[][] lcaMatrix2 = TreeCmpUtils.calcLcaMatrix(t2, id1);
//         int n = lcaMatrix1.length;
//         long n_l = (long) n;
//         long val_l;
//         long commonT = 0;
// 
//         for (int i = 0; i < n; i++) {
//             List<Integer> numList = getPatternNum(i, lcaMatrix1, lcaMatrix2);
//             for (Integer val : numList) {
//                 val_l = (long) val;
//                 commonT += val_l * (val_l - 1) / 2;
//             }
//         }
// 
//         long dist = n_l * (n_l - 1) * (n_l - 2) / 6 - commonT;
//         return (double) dist;
//     }
// 
//     class Pattern {
// 
//         public int a;
//         public int b;
// 
//         public Pattern(int a, int b) {
//             this.a = a;
//             this.b = b;
//         }
// 
//         @Override
//         public int hashCode() {
//             return 31 * a + b;
// 
//         }
// 
//         @Override
//         public boolean equals(Object obj) {
//             if (obj == this) {
//                 return true;
//             }
//             if (obj instanceof Pattern) {
//                 Pattern test = (Pattern) obj;
//                 if (a == test.a && b == test.b) {
//                     return true;
//                 }
//             }
//             return false;
//         }
//     }
// 
//     public List<Integer> getPatternNum(int x, int[][] a, int[][] b) {
// 
//         int n = a.length;
//         int mapSize = (4 * n) / 3;
// 
//         List<Integer> mList = new ArrayList<Integer>();
// 
//         Map<Pattern, Integer> patternMap = new HashMap<Pattern, Integer>(mapSize);
//         for (int i = 0; i < n; i++) {
//             if (i == x) {
//                 continue;
//             }
//             Pattern p = new Pattern(a[x][i], b[x][i]);
//             Integer num = patternMap.get(p);
//             if (num == null) {
//                 patternMap.put(p, new Integer(1));
//             } else {
//                 patternMap.put(p, num.intValue() + 1);
//             }
// 
//         }
//         for (Integer val : patternMap.values()) {
//             if (val >= 2) {
//                 mList.add(val);
//             }
//         }
//         return mList;
//     }
// 
//     
// }


import treecmp.metric.TripletMetric;
import treecmp.metric.Metric;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package treecmp.spr;


/**
 *
 * @author Damian
 */
public class SprHeuristicTTMetric extends SprHeuristicBaseMetric{

 @Override
protected Metric getMetric(){
// Path: src/treecmp/metric/TripletMetric.java
// public class TripletMetric extends BaseMetric implements Metric {
//     private TripletMetric2 tt2;
//   public TripletMetric(){
//       super();
//       tt2 = new TripletMetric2();
//   }
// 
//     public double getDistance(Tree t1, Tree t2, int... indexes) {
// 
//         if (TreeCmpUtils.isBinary(t1, true) && TreeCmpUtils.isBinary(t2, true)) {
//             return getDistForBinary(t1, t2);
//         }
//         //run distance for arbitrary tree in O(n^2) time
//         return tt2.getDistance(t1, t2);
// 
//     }
// 
//     public double getDistForBinary(Tree t1, Tree t2) {
//         IdGroup id1 = TreeUtils.getLeafIdGroup(t1);
//         int[][] lcaMatrix1 = TreeCmpUtils.calcLcaMatrix(t1, null);
//         int[][] lcaMatrix2 = TreeCmpUtils.calcLcaMatrix(t2, id1);
//         int n = lcaMatrix1.length;
//         long n_l = (long) n;
//         long val_l;
//         long commonT = 0;
// 
//         for (int i = 0; i < n; i++) {
//             List<Integer> numList = getPatternNum(i, lcaMatrix1, lcaMatrix2);
//             for (Integer val : numList) {
//                 val_l = (long) val;
//                 commonT += val_l * (val_l - 1) / 2;
//             }
//         }
// 
//         long dist = n_l * (n_l - 1) * (n_l - 2) / 6 - commonT;
//         return (double) dist;
//     }
// 
//     class Pattern {
// 
//         public int a;
//         public int b;
// 
//         public Pattern(int a, int b) {
//             this.a = a;
//             this.b = b;
//         }
// 
//         @Override
//         public int hashCode() {
//             return 31 * a + b;
// 
//         }
// 
//         @Override
//         public boolean equals(Object obj) {
//             if (obj == this) {
//                 return true;
//             }
//             if (obj instanceof Pattern) {
//                 Pattern test = (Pattern) obj;
//                 if (a == test.a && b == test.b) {
//                     return true;
//                 }
//             }
//             return false;
//         }
//     }
// 
//     public List<Integer> getPatternNum(int x, int[][] a, int[][] b) {
// 
//         int n = a.length;
//         int mapSize = (4 * n) / 3;
// 
//         List<Integer> mList = new ArrayList<Integer>();
// 
//         Map<Pattern, Integer> patternMap = new HashMap<Pattern, Integer>(mapSize);
//         for (int i = 0; i < n; i++) {
//             if (i == x) {
//                 continue;
//             }
//             Pattern p = new Pattern(a[x][i], b[x][i]);
//             Integer num = patternMap.get(p);
//             if (num == null) {
//                 patternMap.put(p, new Integer(1));
//             } else {
//                 patternMap.put(p, num.intValue() + 1);
//             }
// 
//         }
//         for (Integer val : patternMap.values()) {
//             if (val >= 2) {
//                 mList.add(val);
//             }
//         }
//         return mList;
//     }
// 
//     
// }


// Path: src/treecmp/spr/SprHeuristicTTMetric.java
import treecmp.metric.TripletMetric;
import treecmp.metric.Metric;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package treecmp.spr;


/**
 *
 * @author Damian
 */
public class SprHeuristicTTMetric extends SprHeuristicBaseMetric{

 @Override
protected Metric getMetric(){
    return new TripletMetric();