public Transformation getTransformation(TreeDefinition aTree, TreeDefinition bTree) { Transformation transform = new Transformation(); Transformation t1 = findDistance(aTree, bTree); transform.totalCost = distance[aTree.getNodeCount(), bTree.getNodeCount()]; Transformation t2 = findDistance(bTree, aTree); transform.editScriptAtoB = t1.editScriptAtoB; transform.editScriptBtoA = t2.editScriptAtoB; transform.pdlA = t1.pdlA; transform.pdlB = t1.pdlB; transform.pdlMappingTreeB = t1.pdlMappingTreeB; transform.pdlMappingTreeA = t1.pdlMappingTreeA; return transform; }
//Computes tree edits distance betwee aTree and bTree public Transformation findDistance(TreeDefinition aTree, TreeDefinition bTree) { distance = new double[aTree.getNodeCount() + 1, bTree.getNodeCount() + 1]; distScript = new TreeEditScript[aTree.getNodeCount() + 1, bTree.getNodeCount() + 1]; //Preliminaries //1. Find left-most leaf and key roots Dictionary<int, int> aLeftLeaf = new Dictionary<int, int>(); Dictionary<int, int> bLeftLeaf = new Dictionary<int, int>(); List<int> aTreeKeyRoots = new List<int>(); List<int> bTreeKeyRoots = new List<int>(); findHelperTables(aTree, aLeftLeaf, aTreeKeyRoots, aTree.getRootID()); findHelperTables(bTree, bLeftLeaf, bTreeKeyRoots, bTree.getRootID()); var a = bTree.getRootID(); //Comparison foreach (int aKeyroot in aTreeKeyRoots) { foreach (int bKeyroot in bTreeKeyRoots) { //Re-initialise forest distance tables Dictionary<int, Dictionary<int, Double>> fD = new Dictionary<int, Dictionary<int, Double>>(); //Re-initialise forest edit script distance tables Dictionary<int, Dictionary<int, TreeEditScript>> fESD = new Dictionary<int, Dictionary<int, TreeEditScript>>(); setForestDistance(aLeftLeaf[aKeyroot], bLeftLeaf[bKeyroot], 0.0d, fD); //script is automatically null //for all descendents of aKeyroot: i for (int i = aLeftLeaf[aKeyroot]; i <= aKeyroot; i++) { var edit = new Delete(i,aTree); setForestDistance(i, bLeftLeaf[bKeyroot] - 1, getForestDistance(i - 1, bLeftLeaf[bKeyroot] - 1, fD) + edit.getCost(), fD); var scriptSuffix = new TreeEditScript(getForestScript(i - 1, bLeftLeaf[bKeyroot] - 1, fESD)); scriptSuffix.Insert(edit); setForestScript(i, bLeftLeaf[bKeyroot] - 1, scriptSuffix, fESD); } //for all descendents of bKeyroot: j for (int j = bLeftLeaf[bKeyroot]; j <= bKeyroot; j++) { var edit = new Insert(j, bTree); setForestDistance(aLeftLeaf[aKeyroot] - 1, j, getForestDistance(aLeftLeaf[aKeyroot] - 1, j - 1, fD) + edit.getCost(), fD); var scriptSuffix = new TreeEditScript(getForestScript(aLeftLeaf[aKeyroot] - 1, j - 1, fESD)); scriptSuffix.Insert(edit); setForestScript(aLeftLeaf[aKeyroot] - 1, j, scriptSuffix, fESD); } for (int i = aLeftLeaf[aKeyroot]; i <= aKeyroot; i++) { for (int j = bLeftLeaf[bKeyroot]; j <= bKeyroot; j++) { TreeEditScript tempScript = null; EditOperation delEdit = new Delete(i, aTree); ; EditOperation insEdit = new Insert(j, bTree); double min; double delCost = getForestDistance(i - 1, j, fD) + delEdit.getCost(); double insCost = getForestDistance(i, j - 1, fD) + insEdit.getCost(); //This min compares del vs ins if (delCost <= insCost) { //Option 1: Delete node from aTree tempScript = new TreeEditScript(getForestScript(i - 1, j, fESD)); tempScript.Insert(delEdit); min = delCost; } else { //Option 2: Insert node into bTree tempScript = new TreeEditScript(getForestScript(i, j - 1, fESD)); tempScript.Insert(insEdit); min = insCost; } if (aLeftLeaf[i] == aLeftLeaf[aKeyroot] && bLeftLeaf[j] == bLeftLeaf[bKeyroot]) { var renEdit = new Rename(i, j, aTree, bTree); var dist = getForestDistance(i - 1, j - 1, fD) + renEdit.getCost(); distance[i, j] = Math.Min(min, dist); if (min <= dist) { tempScript = new TreeEditScript(tempScript); distScript[i, j] = tempScript; } else { tempScript = new TreeEditScript(getForestScript(i - 1, j - 1, fESD)); tempScript.Insert(renEdit); distScript[i, j] = tempScript; } setForestDistance(i, j, distance[i, j], fD); setForestScript(i, j, new TreeEditScript(distScript[i, j]), fESD); } else { var value = getForestDistance(aLeftLeaf[i] - 1, bLeftLeaf[j] - 1, fD) + distance[i, j]; setForestDistance(i, j, Math.Min(min, value), fD); if (min <= value) setForestScript(i, j, new TreeEditScript(tempScript), fESD); else { var tempList = getForestScript(aLeftLeaf[i] - 1, bLeftLeaf[j] - 1, fESD).script; tempList = distScript[i, j].script.Concat(tempList).ToList(); setForestScript(i, j, new TreeEditScript(tempList), fESD); } setForestDistance(i, j, Math.Min(min, value), fD); } } } } } Transformation transform = new Transformation(); transform.totalCost = distance[aTree.getNodeCount(), bTree.getNodeCount()]; transform.editScriptAtoB = distScript[aTree.getNodeCount(), bTree.getNodeCount()]; transform.pdlA = aTree.pdl; transform.pdlB = bTree.pdl; transform.pdlMappingTreeB = bTree.pdlNodeMapping; transform.pdlMappingTreeA = aTree.pdlNodeMapping; return transform; }
public static string ToEnglishString(PDLPred phi) { Transformation t = new Transformation(); return t.ToEnglishString(phi); }
public PDLEDFeedback(FeedbackLevel level, HashSet<char> alphabet, Transformation transformation, double utility, CharSetSolver solver) : base(level, alphabet, utility,solver) { this.transformation = transformation; this.type = FeedbackType.PDLED; }