/// <summary> /// Оценка частоты каждого поддерева из 1 и 2 узлов /// </summary> private void EvaluateFrequency() { foreach (Tree t1 in OneNodeTrees.Values.Where(t => t.IsFrequent)) { FrequentSubtrees.AddFrequentSubtree(t1); } foreach (Tree t2 in TwoNodeTrees.Values.Where(t => t.IsFrequent)) { FrequentSubtrees.AddFrequentSubtree(t2); } }
/// <summary> /// Соединение 2 поддеревьев /// </summary> /// <param name="t2">Поддерево из 2 узлов</param> /// <param name="tree">Поддерево с корнем в листе первого</param> /// <param name="depth">Глубина</param> private void Connect2Subtrees(Tree t2, Tree tree, int depth) { Debug.Assert(t2.Size == 2); string[] preList = t2.ConnectDfsRepresentation(tree); Tree child = Tree.Create(preList, true, SearchParams.Support); ExtendedSubtrees.AddSubtree(child); int depthC = depth + 1; // Глубина соединения while (--depthC >= 0) { if (!t2.ContainsDepth(depthC)) { continue; } int depthTree = depthC + 1; if (!tree.ContainsDepth(depthTree)) { continue; } foreach (TreeEntries tSet in t2[depthC].GetTreeEntries()) { if (!tree.ContainsTreeAtDepth(depthTree, tSet.TreeId)) { continue; } foreach (RootEntry root in tSet.GetRootEntries()) { foreach (SubtreeEntry t2Entry in root.RightMostList) { if (!tree[depthTree][tSet.TreeId].RootDictionary.ContainsKey(t2Entry.SecondIndex)) { continue; } var newEntry = t2Entry.Connect(tree[depthTree][tSet.TreeId][t2Entry.SecondIndex].FirstEntry); child.AddEntry(newEntry); } } } } if (!child.IsFrequent) { return; } FrequentSubtrees.AddFrequentSubtree(child); child.Father = t2; child.Mother = tree; }
/// <summary> /// Комбинирование 2 поддеревьев /// </summary> /// <param name="xTree">Первое поддерево</param> /// <param name="yTree">Второе поддерево</param> /// <param name="depth">Глубина</param> /// <returns>Новое поддерево, полученное путем комбинирования</returns> private Tree Combine2Subtrees(Tree xTree, Tree yTree, int depth) { string[] dfsList = xTree.CombineDfsRepresentation(yTree); Tree child = Tree.Create(dfsList, false, SearchParams.Support); ExtendedSubtrees.AddSubtree(child); int curDepth = depth + 1; while (--curDepth >= 0) { if (!xTree.ContainsDepth(curDepth) || !yTree.ContainsDepth(curDepth)) { continue; } foreach (TreeEntries tSet in xTree[curDepth].GetTreeEntries()) { if (!yTree.ContainsTreeAtDepth(curDepth, tSet.TreeId)) { continue; } foreach (RootEntry root in tSet.GetRootEntries()) { if (!yTree.ContainsRootIndex(curDepth, tSet.TreeId, root.RootIndex)) { continue; } SubtreeEntry xEntry = xTree.GetEntry(curDepth, tSet.TreeId, root.RootIndex); SubtreeEntry yEntry = yTree.GetFirstEntryAfterSpecifiedIndex(xEntry.Depth, xEntry.TreeId, xEntry.RootIndex, xEntry.RightMostIndex); if (yEntry == null) { continue; } child.AddEntry(xEntry.Combine(yEntry)); } } } if (!child.IsFrequent) { return(null); } FrequentSubtrees.AddFrequentSubtree(child); child.Father = xTree; child.Mother = yTree; return(child); }