///<summary> /// Finds the longest common subsequence in quadratic time and linear space /// Variant of: /// D. S. Hirschberg. A linear space algorithm for or computing maximal common subsequences. 1975. /// http://dl.acm.org/citation.cfm?id=360861 /// </summary> /// <returns>Number of pairs that were matched</returns> public static int Match(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b, ISymbolicExpressionTreeNodeSimilarityComparer comp) { if (!comp.Equals(a, b)) return 0; int m = a.SubtreeCount; int n = b.SubtreeCount; if (m == 0 || n == 0) return 1; var matrix = new int[m + 1, n + 1]; for (int i = 1; i <= m; ++i) { var ai = a.GetSubtree(i - 1); for (int j = 1; j <= n; ++j) { var bj = b.GetSubtree(j - 1); int match = Match(ai, bj, comp); matrix[i, j] = Math.Max(Math.Max(matrix[i, j - 1], matrix[i - 1, j]), matrix[i - 1, j - 1] + match); } } return matrix[m, n] + 1; }
public SymbolicExpressionTreeMaxCommonSubtreeSimilarityCalculatorTest() { comparer = new SymbolicExpressionTreeNodeEqualityComparer(); }
///<summary> /// Finds the longest common subsequence in quadratic time and linear space /// Variant of: /// D. S. Hirschberg. A linear space algorithm for or computing maximal common subsequences. 1975. /// http://dl.acm.org/citation.cfm?id=360861 /// </summary> /// <returns>Number of pairs that were matched</returns> public static int Match(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b, ISymbolicExpressionTreeNodeSimilarityComparer comp) { if (!comp.Equals(a, b)) { return(0); } int m = a.SubtreeCount; int n = b.SubtreeCount; if (m == 0 || n == 0) { return(1); } var matrix = new int[m + 1, n + 1]; for (int i = 1; i <= m; ++i) { var ai = a.GetSubtree(i - 1); for (int j = 1; j <= n; ++j) { var bj = b.GetSubtree(j - 1); int match = Match(ai, bj, comp); matrix[i, j] = Math.Max(Math.Max(matrix[i, j - 1], matrix[i - 1, j]), matrix[i - 1, j - 1] + match); } } return(matrix[m, n] + 1); }
public static double MaxCommonSubtreeSimilarity(ISymbolicExpressionTree a, ISymbolicExpressionTree b, ISymbolicExpressionTreeNodeSimilarityComparer comparer) { int max = 0; var rootA = a.Root.GetSubtree(0).GetSubtree(0); var rootB = b.Root.GetSubtree(0).GetSubtree(0); foreach (var aa in rootA.IterateNodesBreadth()) { int lenA = aa.GetLength(); if (lenA <= max) { continue; } foreach (var bb in rootB.IterateNodesBreadth()) { int lenB = bb.GetLength(); if (lenB <= max) { continue; } int matches = SymbolicExpressionTreeMatching.Match(aa, bb, comparer); if (max < matches) { max = matches; } } } return(2.0 * max / (rootA.GetLength() + rootB.GetLength())); }
public static double MaxCommonSubtreeSimilarity(ISymbolicExpressionTree a, ISymbolicExpressionTree b, ISymbolicExpressionTreeNodeSimilarityComparer comparer) { int max = 0; var rootA = a.Root.GetSubtree(0).GetSubtree(0); var rootB = b.Root.GetSubtree(0).GetSubtree(0); foreach (var aa in rootA.IterateNodesBreadth()) { int lenA = aa.GetLength(); if (lenA <= max) continue; foreach (var bb in rootB.IterateNodesBreadth()) { int lenB = bb.GetLength(); if (lenB <= max) continue; int matches = SymbolicExpressionTreeMatching.Match(aa, bb, comparer); if (max < matches) max = matches; } } return 2.0 * max / (rootA.GetLength() + rootB.GetLength()); }