private void Traversal(PatternTree xPattern, int yIndex, IList <PatternTree> group, Depth depth) { var pX = xPattern; var pY = group[yIndex]; var childPreStr = pX.CombinePreorderRepresentation(pY).ToPreorderString(MiningParams.Separator); PatternTree child = null; if (PatternsExtended.AlreadyExtended(childPreStr)) { child = PatternsFrequent.GetPatternAtDepth(childPreStr, depth); } else if (pX.HasNewCombineOccurrenceAtDepth(pY, depth)) { child = Combine2Patterns(pX, pY, depth); } if (child == null) { return; } for (var i = 0; i < group.Count; i++) { Traversal(child, i, group, depth); } }
internal void AddMaximal(PatternTree pt) { if (!Maximals.ContainsKey(pt.PreorderString)) { Maximals.Add(pt.PreorderString, pt); } }
internal void CheckSuperPatternAfterCombination(PatternTree pt, Depth depth, bool mineClosed) { if (HasSuperFrequentPattern != YesNoUnknown.Unknown && !mineClosed) { return; } if (!IsSuperPattern(pt, depth)) { return; } HasSuperFrequentPattern = YesNoUnknown.Yes; if (!mineClosed) { return; } if (HasTransactionMatch != YesNoUnknown.Unknown && HasOccurrenceMatch != YesNoUnknown.Unknown) { return; } if (RootSupport == pt.RootSupport) { HasOccurrenceMatch = YesNoUnknown.Yes; } else if (TransactionSupport == pt.TransactionSupport) { HasTransactionMatch = YesNoUnknown.Yes; } }
internal void AddFrequentPattern(PatternTree fpt) { if (!Frequents.ContainsKey(fpt.PreorderString)) { Frequents.Add(fpt.PreorderString, fpt); } if (fpt.Is1Pattern && !Frequent1Pts.ContainsKey(fpt.PreorderString)) { Frequent1Pts.Add(fpt.PreorderString, fpt); return; } if (fpt.Is2Pattern && !Frequent2Pts.ContainsKey(fpt.PreorderString)) { Frequent2Pts.Add(fpt.PreorderString, fpt); } for (Depth d = 0; d < MaxDepth; d++) { if (fpt.ContainsDepth(d) && !DepthBasedFrequentPts[d].ContainsKey(fpt.PreorderString)) { DepthBasedFrequentPts[d].Add(fpt.PreorderString, fpt); } } }
internal void AddClosed(PatternTree pt) { if (!Closeds.ContainsKey(pt.PreorderString)) { Closeds.Add(pt.PreorderString, pt); } }
internal void AddPattern(PatternTree pt) { if (AlreadyExtended(pt.PreorderString)) { throw new InvalidOperationException("Pattern already added."); } PatternsExtended.Add(pt.PreorderString); }
private PatternTree Combine2Patterns(PatternTree px, PatternTree py, Depth depth) { var preList = px.CombinePreorderRepresentation(py); var child = PatternTree.Create(preList, false, MiningParams); PatternsExtended.AddPattern(child); var curDepth = depth + 1; while (--curDepth >= 0) { if (!px.ContainsDepth(curDepth) || !py.ContainsDepth(curDepth)) { continue; } foreach (TreeOccSet tSet in px[curDepth].GetTreeSet()) { if (!py.ContainsTreeAtDepth(curDepth, tSet.TreeId)) { continue; } foreach (RootOcc root in tSet.GetRootSet()) { if (!py.ContainsRootIndex(curDepth, tSet.TreeId, root.RootIndex)) { continue; } var xOcc = px.GetOccurrence(curDepth, tSet.TreeId, root.RootIndex); var yOcc = py.GetFirstOccAfterSpecifiedIndex(xOcc.Depth, xOcc.TreeId, xOcc.RootIndex, xOcc.RightMostIndex); if (yOcc == null) { continue; } child.AddOccurrence(xOcc.Combine(yOcc)); } } } if (!child.IsFrequent) { return(null); } PatternsFrequent.AddFrequentPattern(child); child.Father = px; child.Mother = py; px.CheckMatch(child); py.CheckMatch(child); return(child); }
internal new void CheckMatch(PatternTree superF2) { if (!superF2.Is2Pattern) { throw new InvalidOperationException("Frequent 2 pattern is required."); } if (!IsSuperPattern(superF2)) { throw new InvalidOperationException("Only super-pattern is allowed for match checking."); } base.CheckMatch(superF2); }
public static bool IsInducedSuperPattern(this PatternTree pt, PatternTree largerPt, NodeSymbol backTrack) { if (pt.Size > largerPt.Size) { return(false); } var largeList = largerPt.PreorderRepresentation; var smallList = pt.PreorderRepresentation; const int upperBound = 1; const int lowerBound = int.MaxValue; return(IsInducedMatch(largeList, 0, 0, upperBound, lowerBound, smallList, 0, backTrack)); }
void ScanP1P2(ITreeNode tn, ref Depth maxDepth) { if (maxDepth <= tn.Depth) { maxDepth = tn.Depth; } var treeId = tn.Tree.TreeId; var preList1P = new[] { tn.Symbol, MiningParams.BackTrackSymbol }; var patternKey1P = preList1P.ToPreorderString(MiningParams.Separator); if (!OnePatterns.ContainsKey(patternKey1P)) { var onePt = PatternTree.Create(preList1P, false, MiningParams); PatternsExtended.AddPattern(onePt); OnePatterns.Add(onePt.PreorderString, onePt); } OnePatterns[patternKey1P].AddOccurrence(OccInduced.Create(treeId, tn.Depth, new[] { tn.PreorderIndex })); if (tn.Children == null) { return; } foreach (var child in tn.Children) {// Scan for 2-patterns, and each child implies an existence of right-most 2-occurrence. var preList2P = new[] { tn.Symbol, child.Symbol, MiningParams.BackTrackSymbol, MiningParams.BackTrackSymbol }; var patternKey2P = preList2P.ToPreorderString(MiningParams.Separator); if (!TwoPatterns.ContainsKey(patternKey2P)) { var twoPt = PatternTree.Create(preList2P, true, MiningParams); PatternsExtended.AddPattern(twoPt); TwoPatterns.Add(twoPt.PreorderString, twoPt); } var occ = OccInduced.Create(treeId, tn.Depth, new[] { tn.PreorderIndex, child.PreorderIndex }); if (child.IsLeaf) { occ.AbleToConnect = false; } TwoPatterns[patternKey2P].AddOccurrence(occ); ScanP1P2(child, ref maxDepth); } }
internal static bool HasNewConnectOccurrenceAtDepth(this PatternTree p2, PatternTree pt, Depth depth) { if (p2 == null) { throw new ArgumentNullException("p2"); } if (!p2.Is2Pattern) { throw new ArgumentException("The connect pattern must be a 2-pattern."); } if (pt == null) { throw new ArgumentNullException("pt"); } if (p2.SecondSymbol != pt.FirstSymbol) { return(false); } var depthConnect = depth; var depthToBeConnected = depthConnect + 1; if (!p2.ContainsDepth(depthConnect) || !pt.ContainsDepth(depthToBeConnected)) { return(false); } foreach (TreeOccSet tSet in p2[depthConnect].GetTreeSet()) {// For every tree that contains p2 at 'depthConnect' if (!pt.ContainsTreeAtDepth(depthToBeConnected, tSet.TreeId)) { continue; } foreach (RootOcc rSet in tSet.GetRootSet()) { // For every root occurrence, check its leaves foreach (IOccurrence iOcc in rSet.GetRightMostSet()) { // checks each leaf, if a leaf of root occurrence of p2 is the root of an occurrence of pt, there might be a new pattern. if (pt[depthToBeConnected][tSet.TreeId].ContainsRootIndex(iOcc.RightMostIndex)) { // An occurrence of p2 has a leaf which is the root of an occurrence of pt, a new pattern should be extended. return(true); } } } } return(false); }
internal static bool HasNewCombineOccurrenceAtDepth(this PatternTree xPattern, PatternTree yPattern, Depth depth) { if (xPattern == null) { throw new ArgumentNullException("xPattern"); } if (yPattern == null) { throw new ArgumentNullException("yPattern"); } if (xPattern.FirstSymbol != yPattern.FirstSymbol) { return(false); } if (!xPattern.ContainsDepth(depth) || !yPattern.ContainsDepth(depth)) { return(false); } foreach (TreeOccSet tree in xPattern[depth].GetTreeSet()) { if (!yPattern.ContainsTreeAtDepth(depth, tree.TreeId)) { continue; } foreach (RootOcc rSet in tree.GetRootSet()) { if (!yPattern[depth][tree.TreeId].ContainsRootIndex(rSet.RootIndex)) { continue; } foreach (IOccurrence occY in yPattern[depth][tree.TreeId][rSet.RootIndex].GetRightMostSet()) { if (rSet.FirstOcc.RightMostIndex < occY.SecondIndex) { return(true); } } } } return(false); }
/// <summary> /// Check transaction match and root occurrence match after a super pattern /// is generated via connection or combination. /// </summary> /// <param name="superPt"></param> internal void CheckMatch(PatternTree superPt) { if (HasOccurrenceMatch != YesNoUnknown.Unknown && HasTransactionMatch != YesNoUnknown.Unknown) { return; } if (superPt.IsFrequent) { HasSuperFrequentPattern = YesNoUnknown.Yes; } if (RootSupport.Equals(superPt.RootSupport)) { HasOccurrenceMatch = YesNoUnknown.Yes; } else if (TransactionSupport.Equals(superPt.TransactionSupport)) { HasTransactionMatch = YesNoUnknown.Yes; } }
internal static NodeSymbol[] ConnectPreorderRepresentation(this PatternTree twoPattern, PatternTree pattern) { if (!twoPattern.Is2Pattern) { throw new InvalidOperationException("2-pattern is required."); } if (twoPattern.SecondSymbol != pattern.FirstSymbol) { throw new InvalidOperationException("Cannot connect these two preorder strings."); } var nodeSymbolsP2 = twoPattern.PreorderRepresentation; var nodeSymbolsPt = pattern.PreorderRepresentation; var temp = new List <NodeSymbol> { nodeSymbolsP2[0] }; temp.AddRange(nodeSymbolsPt); temp.Add(nodeSymbolsP2[nodeSymbolsP2.Count - 1]); return(temp.ToArray()); }
internal static NodeSymbol[] CombinePreorderRepresentation(this PatternTree xPattern, PatternTree yPattern) { if (xPattern.FirstSymbol != yPattern.FirstSymbol) { throw new InvalidOperationException("Cannot combine these two preorder strings."); } var nodeSymbols1 = xPattern.PreorderRepresentation; var nodeSymbols2 = yPattern.PreorderRepresentation; var temp = new List <NodeSymbol>(); for (var i = 0; i < nodeSymbols1.Count - 1; i++) { temp.Add(nodeSymbols1[i]); } for (var i = 1; i < nodeSymbols2.Count; i++) { temp.Add(nodeSymbols2[i]); } return(temp.ToArray()); }
internal bool IsSuperPattern(PatternTree largerPt, Depth depth) { return(this.IsInducedSuperPattern(largerPt, MiningParams.BackTrackSymbol)); }
private void ConnectTwoPatterns(PatternTree f2, PatternTree fpt, Depth depth) { if (f2.Size != 2) { throw new InvalidOperationException("The connect pattern must be 2-pattern."); } var preList = f2.ConnectPreorderRepresentation(fpt); var child = PatternTree.Create(preList, true, MiningParams); PatternsExtended.AddPattern(child); var depthC = depth + 1; // Depth of connect while (--depthC >= 0) { if (!f2.ContainsDepth(depthC)) { continue; } var depthTbc = depthC + 1; // Depth of to be connected if (!fpt.ContainsDepth(depthTbc)) { continue; } foreach (TreeOccSet tSet in f2[depthC].GetTreeSet()) { if (!fpt.ContainsTreeAtDepth(depthTbc, tSet.TreeId)) { continue; } foreach (RootOcc root in tSet.GetRootSet()) { foreach (IOccurrence f2Occ in root.GetRightMostSet()) { if (!fpt[depthTbc][tSet.TreeId].RootSet.ContainsKey(f2Occ.SecondIndex)) { continue; } var newOcc = f2Occ.Connect(fpt[depthTbc][tSet.TreeId][f2Occ.SecondIndex].FirstOcc); child.AddOccurrence(newOcc); } } } } if (!child.IsFrequent) { return; } PatternsFrequent.AddFrequentPattern(child); child.Father = f2; child.Mother = fpt; f2.CheckMatch(child); fpt.CheckMatch(child); }
internal bool IsSuperPattern(PatternTree f2) { return(f2.FirstSymbol == FirstSymbol || f2.SecondSymbol == FirstSymbol); }