//Sets the inervals private void setIntervalsAndRelations() { relations = new Dictionary <int, Dictionary <int, string> >(); TemporalDB db = CCMiner.mainDB; sequences = new List <EventSequence>(); for (int k = 0; k < actual_ids.Count; k++) { string t_id = TransformedDB.getID(actual_ids[k]); ids.Add(k, t_id); string id = t_id; EventSequence seq = new EventSequence(); List <string> seq_syms = CoincidenceManager. getPatternSymbols(pDB.patterns[actual_ids[k]].Item1); foreach (string sym in seq_syms) { seq.ints.Add(db.seqs[id].getInterval(sym)); } sequences.Add(seq); if (k == 0) { for (int i = 0; i < length; i++) { relations.Add(i, new Dictionary <int, string>()); for (int j = i + 1; j < length; j++) { EventInterval ei1 = seq.ints[i]; EventInterval ei2 = seq.ints[j]; string rel = getRelation(ei1, ei2); relations[i].Add(j, rel); } } } } }
//Returns the slices that appear before slice in the given coincidence //Also the slices that appear in the previous co, if exists and partial are added private List <string> getSlicesBeforeInCo(string slc, List <string> coes, int index, string pat, string id, int last_time) { List <string> befSlices = new List <string>(); List <string> prev_slices = new List <string>(); if (index > 0 && CoincidenceManager.isPartialCo(coes[index - 1])) { prev_slices = CoincidenceManager.getSymPartOfSlices(CoincidenceManager.splitCoToSlices(coes[index - 1])); } List <string> cur_coes = new List <string>(); for (int i = 0; i < index + 1; i++) { cur_coes.Add(coes[i]); } cur_coes[index] = ""; fillSliceList(befSlices, prev_slices, cur_coes, pat, id, last_time); if (slc[0] == Constants.MEET_REP) { return(befSlices); } //Added slices that appears in the previous coincidence after the previous slice if exist string cur_slc = slc; if (slc[0] == Constants.MEET_REP) { cur_slc = cur_slc.Substring(1); } cur_coes[index] = CoincidenceManager.getPartBefore(coes[index], cur_slc); List <string> allSlices = CoincidenceManager.splitCoToSlices(cur_coes[index]); //List<string> allSlices = CoincidenceManager.getSymPartOfSlices(CoincidenceManager.splitCoToSlices(cur_coes[index])); fillSliceList(befSlices, allSlices, cur_coes, pat, id, last_time); return(befSlices); }
//Checks if next co meet slice can be preserved, if exists private static bool checkNextCoMeetOption(List <string> co, string pat) { if (lastPatSlice(pat).IndexOf('-') >= 0 && co.Count > 0) { return(CoincidenceManager.isPartialCo(co[0])); } return(false); }
//Returns the frequent slices with their current supports //Returns also the infriquent slices as a list if the flag is set to true public Dictionary <string, int> slicesFreq() { //vertical support in current db entities (extended) Dictionary <string, int> slices_support = new Dictionary <string, int>(); //Entries IDs and the slices already seen for it Dictionary <string, List <string> > slices_line_ignore = new Dictionary <string, List <string> >(); //For each entity postfix in the current db: foreach (KeyValuePair <string, List <string> > entry in trans_db) { //Add the entity id to ignores if its the first time we see it string ent_id = getID(entry.Key); if (!slices_line_ignore.ContainsKey(entry.Key)) { slices_line_ignore.Add(entry.Key, new List <string>()); } int time = patterns[entry.Key].Item2; //Take the slices of the postfix List <string> concrete_slices = CoincidenceManager.splitCoSeqToSlices(entry.Value, (slc) => maxGapHolds(ent_id, time, slc)); //For each concrete slice: for (int i = 0; i < concrete_slices.Count; i++) { //if slice is @x: Do the following both for @x and x //otherwise: Do only for x string slc = CoincidenceManager.getSymPartOfSlice(concrete_slices[i]); string conc_slc = concrete_slices[i]; for (int j = 0; j < 2; j++) { if (slices_support.ContainsKey(slc)) { //Not the first time we meet the slice if (!slices_line_ignore[entry.Key].Contains(slc)) { slices_support[slc]++; slices_line_ignore[entry.Key].Add(slc); } } else { //First time we see the slice slices_support.Add(slc, 1); slices_line_ignore[entry.Key].Add(slc); } if (slc[0] == Constants.MEET_REP) { slc = slc.Substring(1); conc_slc = conc_slc.Substring(1); } else { break; } } } } return(slices_support); }
//Adds a pattern to the patterns collection public void addPattern(string pat, int sup, TransformedDB projDB) { using (FileStream fileStream = new FileStream(Constants.OUT_FILE, FileMode.Append, FileAccess.Write)) { TextWriter tw = new StreamWriter(fileStream); TemporalPattern tp = new TemporalPattern(CoincidenceManager.outToCoSeq(pat), sup, projDB); tw.WriteLine(tp.ToString()); tw.Close(); } }
// private static KeyValuePair <string, string> getRestCo(string slice, int co_index, List <string> fullCoes, string pattern, string id, string prev_oc, int time) { string slc = slice.Substring(0, slice.Length - 1); if (slice[0] == Constants.MEET_REP) { slc = slc.Substring(1); } if (slice[0] == Constants.CO_REP) { slc = slc.Substring(1); } if (fullCoes[co_index].IndexOf(slc) < 0) { return(new KeyValuePair <string, string>(null, null)); } //co_slices includes only one slice string rest = ""; int j = 0; List <string> fullCo_slices = null; string app = ""; string last_pat_slice = lastPatSlice(pattern); bool passed_prev = prev_oc.Equals(""); if (fullCoes[co_index].Length > 0 && fullCoes[co_index][0] == Constants.MEET_REP) //coincidence has @ inside of it { if (co_index == 0 || (co_index == 1 && CoincidenceManager.isPartialCo(fullCoes[0]))) { if (last_pat_slice.IndexOf(Constants.FIN_REP) >= 0) { //slice is pos: has to be @x+ (don't keep the @) if (slice.IndexOf(Constants.ST_REP) >= 0 && slice.IndexOf(Constants.MEET_REP) >= 0) { //slice = @x+ fullCo_slices = CoincidenceManager.splitCoToSlices(fullCoes[co_index]); for (int i = 0; i < fullCo_slices.Count; i++) { if (slice.Equals(fullCo_slices[i].Substring(0, fullCo_slices[i] .IndexOf(Constants.DUP_SYM)) + fullCo_slices[i][fullCo_slices[i].Length - 1]) && maxGapHolds(id, time, fullCo_slices[i])) { app = fullCo_slices[i]; if (app.Equals(prev_oc)) { passed_prev = true; continue; } if (!passed_prev) { continue; } j++; if (i < fullCo_slices.Count - 1) { for (int k = i + 1; k < fullCo_slices.Count; k++) { if (fullCo_slices[k][0] == Constants.MEET_REP) { string add = ""; if (fullCo_slices[k].Substring(1)[0] != Constants.CO_REP) { add += Constants.CO_REP; } rest += add + fullCo_slices[k].Substring(1); } else { string add = ""; if (fullCo_slices[k][0] != Constants.CO_REP) { add += Constants.CO_REP; } rest += add + fullCo_slices[k]; } } } break; } } if (j == 1) { return(new KeyValuePair <string, string>(rest, app)); } } return(new KeyValuePair <string, string>(null, null)); } return(new KeyValuePair <string, string>(null, null)); } //has to be without @ if (slice.IndexOf(Constants.MEET_REP) < 0) { fullCo_slices = CoincidenceManager.splitCoToSlices(fullCoes[co_index]); for (int i = 0; i < fullCo_slices.Count; i++) { if ((slice.Equals(fullCo_slices[i].Substring(0, fullCo_slices[i] .IndexOf(Constants.DUP_SYM)) + fullCo_slices[i][fullCo_slices[i].Length - 1]) || (fullCo_slices[i][0] == Constants.MEET_REP && slice.Equals(fullCo_slices[i].Substring(1, fullCo_slices[i] .IndexOf(Constants.DUP_SYM) - 1) + fullCo_slices[i][fullCo_slices[i].Length - 1]))) && maxGapHolds(id, time, fullCo_slices[i])) { app = fullCo_slices[i]; if (app[0] == Constants.MEET_REP) { app = app.Substring(1); } if (app.Equals(prev_oc)) { passed_prev = true; continue; } if (!passed_prev) { continue; } if (app.IndexOf(Constants.FIN_REP) >= 0 && !CoincidenceManager.checkNoEndBeforeStart(app, pattern)) { continue; } j++; if (i < fullCo_slices.Count - 1) { for (int k = i + 1; k < fullCo_slices.Count; k++) { if (fullCo_slices[k][0] == Constants.MEET_REP) { string add = ""; if (fullCo_slices[k].Substring(1)[0] != Constants.CO_REP) { add += Constants.CO_REP; } rest += add + fullCo_slices[k].Substring(1); } else { string add = ""; if (fullCo_slices[k][0] != Constants.CO_REP) { add += Constants.CO_REP; } rest += add + fullCo_slices[k]; } } } break; } } if (j == 1) { return(new KeyValuePair <string, string>(rest, app)); } } return(new KeyValuePair <string, string>(null, null)); } //coincidence has no @ in it fullCo_slices = CoincidenceManager.splitCoToSlices(fullCoes[co_index]); for (int i = 0; i < fullCo_slices.Count; i++) { if (slice.Equals(fullCo_slices[i].Substring(0, fullCo_slices[i] .IndexOf(Constants.DUP_SYM)) + fullCo_slices[i][fullCo_slices[i].Length - 1]) && maxGapHolds(id, time, fullCo_slices[i])) { app = fullCo_slices[i]; if (app.Equals(prev_oc)) { passed_prev = true; continue; } if (!passed_prev) { continue; } if (app.IndexOf(Constants.FIN_REP) >= 0 && !CoincidenceManager.checkNoEndBeforeStart(app, pattern)) { continue; } j++; if (i < fullCo_slices.Count - 1) { for (int k = i + 1; k < fullCo_slices.Count; k++) { string add = ""; if (fullCo_slices[k][0] != Constants.CO_REP) { add += Constants.CO_REP; } rest += add + fullCo_slices[k]; } } break; } } if (j == 1) { return(new KeyValuePair <string, string>(rest, app)); } return(new KeyValuePair <string, string>(null, null)); }
//Returns the slices that appears in the i-th co-occuring-checking period in the DB for the last slice private List <string> ithCo(string slice) { string slicetmp = slice[0] == Constants.CO_REP || slice[0] == Constants.MEET_REP ? slice.Substring(1) : slice; Dictionary <string, int> ith_co = new Dictionary <string, int>(); int app_counter = 0; foreach (KeyValuePair <string, List <string> > entry in trans_db) { List <string> seq_coes = entry.Value; //Split entry to coincidences int last_time = patterns[entry.Key].Item2; KeyValuePair <int, KeyValuePair <List <string>, string> > proj = canProjectBy(slice, seq_coes, patterns[entry.Key].Item1, getID(entry.Key), 0, "", last_time); int cpb = proj.Key; List <string> suspect; while (cpb >= 0) { app_counter++; string pref = ""; suspect = new List <string>(); if (CoincidenceManager.isPartialCo(seq_coes[cpb])) { pref = Constants.CO_REP + ""; } else if (seq_coes[cpb].IndexOf(Constants.MEET_REP) >= 0 && (cpb == 0 || (cpb == 1 && CoincidenceManager.isPartialCo(seq_coes[cpb - 1])))) { pref = Constants.MEET_REP + ""; } List <string> toAdd = CoincidenceManager.getSymPartOfSlices (CoincidenceManager.splitCoToSlices(seq_coes[cpb])); foreach (string s in toAdd) { string stmp = s[0] == Constants.CO_REP || s[0] == Constants.MEET_REP ? s.Substring(1) : s; if (stmp.Equals(slicetmp)) { break; } if (!suspect.Contains(pref + stmp)) { suspect.Add(pref + stmp); } } //suspect = getSlicesBeforeInCo(slice, seq_coes, cpb, patterns[entry.Key].Item1, getID(entry.Key), last_time); //Add occurences of the slices that appeared in the current occurence of 'slice' foreach (string sus in suspect) { if (ith_co.ContainsKey(sus)) { ith_co[sus]++; } else { ith_co.Add(sus, 1); } } proj = canProjectBy(slice, seq_coes, patterns[entry.Key].Item1, getID(entry.Key), proj.Key, proj.Value.Value, last_time); cpb = proj.Key; } } //Take those that always appear List <string> ic = new List <string>(); foreach (KeyValuePair <string, int> entry in ith_co) { if (entry.Value == app_counter) { string tmp = entry.Key[0] == Constants.MEET_REP || entry.Key[0] == Constants.CO_REP ? entry.Key.Substring(1) : entry.Key; if (!ic.Contains(tmp)) { ic.Add(tmp); } } } return(ic); }
//Returns the slices that appears in the i-th before-checking period in the DB for the last slice private List <string> ithBefore(string slice) { Dictionary <string, int> ith_bef = new Dictionary <string, int>(); Dictionary <string, int> meet_ith_bef = new Dictionary <string, int>(); int app_counter = 0; foreach (KeyValuePair <string, List <string> > entry in trans_db) { List <string> seq_coes = entry.Value; //Split entry to coincidences int last_time = patterns[entry.Key].Item2; KeyValuePair <int, KeyValuePair <List <string>, string> > proj = canProjectBy(slice, seq_coes, patterns[entry.Key].Item1, getID(entry.Key), 0, "", last_time); //Returns co index and postfix int cpb = proj.Key; //bool skip_one; List <string> suspect; List <string> meet_suspect; while (cpb >= 0) { //skip_one = (seq_coes.Count > 0 && seq_coes[0].IndexOf(Constants.CO_REP) >= 0); suspect = new List <string>(); meet_suspect = new List <string>(); app_counter++; List <string> cur_coes = new List <string>(); for (int i = 0; i < cpb; i++) { cur_coes.Add(""); } string pref; for (int i = 0; i < cpb; i++) { /*if (skip_one) * { * skip_one = false; * continue; * }*/ pref = ""; if (i == 0) { if (CoincidenceManager.isPartialCo(seq_coes[i])) { pref = Constants.CO_REP + ""; } else if (seq_coes[i].IndexOf(Constants.MEET_REP) >= 0) { pref = Constants.MEET_REP + ""; } } else if (i == 1) { if (seq_coes[i].IndexOf(Constants.MEET_REP) >= 0 && CoincidenceManager.isPartialCo(seq_coes[i - 1])) { pref = Constants.MEET_REP + ""; } } bool b1 = i == cpb - 1 && seq_coes[cpb].IndexOf(Constants.MEET_REP) >= 0; bool b2 = slice[0] == Constants.MEET_REP; if (b1 != b2) { List <string> toAdd1 = CoincidenceManager.getSymPartOfSlices (CoincidenceManager.splitCoToSlices(seq_coes[i])); List <string> conc_toAdd1 = CoincidenceManager.splitCoToSlices(seq_coes[i]); int ind1 = 0; foreach (string s in toAdd1) { string stmp = s[0] == Constants.CO_REP || s[0] == Constants.MEET_REP ? s.Substring(1) : s; string cs = conc_toAdd1[ind1]; string cstmp = cs[0] == Constants.CO_REP || cs[0] == Constants.MEET_REP ? cs.Substring(1) : cs; if (!meet_suspect.Contains(pref + stmp) && (stmp.IndexOf(Constants.FIN_REP) >= 0 || (maxGapHolds(getID(entry.Key), last_time, cstmp) && maxGapHolds(getID(entry.Key), getInt(getID(entry.Key), cstmp). st_time, proj.Value.Value)))) { meet_suspect.Add(pref + stmp); } ind1++; } continue; } List <string> toAdd = CoincidenceManager.getSymPartOfSlices (CoincidenceManager.splitCoToSlices(seq_coes[i])); List <string> conc_toAdd = CoincidenceManager.splitCoToSlices(seq_coes[i]); int ind = 0; foreach (string s in toAdd) { string stmp = s[0] == Constants.CO_REP || s[0] == Constants.MEET_REP ? s.Substring(1) : s; string cs = conc_toAdd[ind]; string cstmp = cs[0] == Constants.CO_REP || cs[0] == Constants.MEET_REP ? cs.Substring(1) : cs; if (!suspect.Contains(pref + stmp) && (stmp.IndexOf(Constants.FIN_REP) >= 0 || (maxGapHolds(getID(entry.Key), last_time, cstmp) && maxGapHolds(getID(entry.Key), getInt(getID(entry.Key), cstmp).st_time, proj.Value.Value)))) { suspect.Add(pref + stmp); } ind++; } /* * List<string> toAdd = CoincidenceManager.getSymPartOfSlices * (CoincidenceManager.splitCoToSlices(seq_coes[i])); * cur_coes[i] = seq_coes[i]; * fillSliceList(suspect, toAdd, cur_coes, patterns[entry.Key].Item1, getID(entry.Key), last_time); */ } //Add occurences of the slices that appeared in the current occurence of 'slice' foreach (string sus in suspect) { if (ith_bef.ContainsKey(sus)) { ith_bef[sus]++; } else { ith_bef.Add(sus, 1); } } foreach (string sus in meet_suspect) { if (meet_ith_bef.ContainsKey(sus)) { meet_ith_bef[sus]++; } else { meet_ith_bef.Add(sus, 1); } } proj = canProjectBy(slice, seq_coes, patterns[entry.Key].Item1, getID(entry.Key), proj.Key, proj.Value.Value, last_time); cpb = proj.Key; } } //Take those that always appear List <string> ib = new List <string>(); foreach (KeyValuePair <string, int> entry in ith_bef) { if (entry.Value == app_counter) { string tmp = entry.Key[0] == Constants.MEET_REP || entry.Key[0] == Constants.CO_REP ? entry.Key.Substring(1) : entry.Key; if (!ib.Contains(tmp)) { ib.Add(tmp); } } } foreach (KeyValuePair <string, int> entry in meet_ith_bef) { if (entry.Value == app_counter) { string tmp = entry.Key[0] == Constants.MEET_REP || entry.Key[0] == Constants.CO_REP ? entry.Key.Substring(1) : entry.Key; if (!ib.Contains(tmp)) { ib.Add(tmp); } } } return(ib); }
// Projects the DB with insignificant slices removal iff check_ins = true (alpha is always a single slice) public TransformedDB projectDB(string alpha, Dictionary <string, int> ins_slices, bool check_ins) { KeyValuePair <int, KeyValuePair <List <string>, string> > proj; List <string> postfix; int instance_counter = 0; //the new subids Dictionary <string, int> projSubids = new Dictionary <string, int>(); //new db sequences Dictionary <string, List <string> > projDB = new Dictionary <string, List <string> >(); //new extended patterns Dictionary <string, Tuple <string, int> > projPatterns = new Dictionary <string, Tuple <string, int> >(); //Find the discovered patterns add figure out the real support List <string> patIDs = new List <string>(); //For each co sequence in db int i = 0; foreach (KeyValuePair <string, List <string> > entry in trans_db) { i++; string ent_id = getID(entry.Key); if (!projSubids.ContainsKey(ent_id)) { projSubids.Add(ent_id, subids[ent_id]); } List <string> cleared = null; if (check_ins) { cleared = CoincidenceManager.rem_ins_slices(entry.Value, ins_slices, checkNextCoMeetOption(entry.Value, patterns[entry.Key].Item1)); } int last_time = patterns[entry.Key].Item2; if (check_ins) { proj = canProjectBy(alpha, cleared, patterns[entry.Key].Item1, ent_id, 0, "", last_time); } else { proj = canProjectBy(alpha, entry.Value, patterns[entry.Key].Item1, ent_id, 0, "", last_time); } postfix = proj.Value.Key; if (postfix != null) { projDB.Add(entry.Key, postfix); int updated = getUpdatedEndTime(ent_id, last_time, proj.Value.Value); projPatterns.Add(entry.Key, new Tuple <string, int>(patterns[entry.Key].Item1 + proj.Value.Value, updated)); if (!patIDs.Contains(ent_id)) { patIDs.Add(ent_id); } bool stop = false; int index = 0; index = projSubids[ent_id]; List <string> prev_postfix; string prev_entry = entry.Key; //Look for more occurences in the rest of the entity's sequence while (!stop) { prev_postfix = postfix; if (check_ins) { proj = canProjectBy(alpha, cleared, patterns[entry.Key].Item1, ent_id, proj.Key, proj.Value.Value, last_time); } else { proj = canProjectBy(alpha, entry.Value, patterns[entry.Key].Item1, ent_id, proj.Key, proj.Value.Value, last_time); } postfix = proj.Value.Key; if (postfix != null) { prev_entry = ent_id + "." + index; projDB.Add(prev_entry, postfix); updated = getUpdatedEndTime(ent_id, last_time, proj.Value.Value); projPatterns.Add(prev_entry, new Tuple <string, int>(patterns[entry.Key].Item1 + proj.Value.Value, updated)); if (!patIDs.Contains(ent_id)) { patIDs.Add(ent_id); } } else { stop = true; } index++; } projSubids[ent_id] = index; } } instance_counter = patIDs.Count; return(new TransformedDB(projDB, projPatterns, projSubids, alpha, instance_counter)); }
//The CBIDE algorithm private static void CBIDE(TransformedDB projDB, string alpha, int alpha_support, double totalsup, List <string> BS, ref CTP ctp, bool closed) { long dt1 = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; Dictionary <string, int> LFs = projDB.slicesFreq(); long t = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - dt1; List <string> FS = new List <string>(); bool start = false; if (closed) { foreach (KeyValuePair <string, int> entry in LFs) { //CCMiner wanted only finishing ones, but that's not enough for closed patterns recognition if (/*entry.Key.IndexOf(Constants.FIN_REP) > 0 &&*/ totalsup == entry.Value) { if (entry.Key[entry.Key.Length - 1] == Constants.ST_REP) { start = true; break; } string slice = entry.Key[0] == Constants.MEET_REP || entry.Key[0] == Constants.CO_REP ? entry.Key.Substring(1) : entry.Key; FS.Add(slice); } } } //Check if none appear in pairs in BS U FS bool nip = closed && CoincidenceManager.noneInPairs(BS, FS); //Check if all appear in pairs in the accumulated coincidence bool aip = CoincidenceManager.allInPairs(alpha); //If So, there are no backward & forward extensions and this is a temporal pattern if ((!closed || (!start && nip)) && aip) { //Thus - alpha is a closed temporal pattern ctp.addPattern(alpha, alpha_support, projDB); } //Now Continue Looking for possible extensions List <string> P = new List <string>(); //For each frequent slice: foreach (KeyValuePair <string, int> z in LFs) { if (z.Value < Constants.MINSUP) { continue; } //Finishing slices only if (z.Key.IndexOf(Constants.FIN_REP) >= 0) { string tmp = z.Key[0] == Constants.CO_REP ? z.Key.Substring(1) : z.Key; if (alpha.IndexOf(tmp.Replace(Constants.FIN_REP, Constants.ST_REP)) >= 0) {//pre-pruning P.Add(z.Key); } } else { //Starting slices only P.Add(z.Key); } } //For each possible extension we found: foreach (string z in P) { //post-pruning //Notice that we project another time only by the recent added slice TransformedDB alpha_projDB = projDB.projectDB(z, LFs, true); //If the support of the extended pattern is above the minimum support requested if (alpha_projDB.sup >= Constants.MINSUP) { //Copy Backward extension list List <string> BStag = BS.Take(BS.Count).ToList(); //Check if extensible and update the backward extension slices if (!closed || !projDB.CBackScan(BStag, z)) { if (closed) { BStag.AddRange(projDB.backwardExtensionCheck(z)); } CBIDE(alpha_projDB, alpha + z, alpha_projDB.sup, alpha_projDB.trans_db.Count, BStag, ref ctp, closed); } } } }
//Sets the symbols of the pattern private void setSyms() { syms = CoincidenceManager.getSymbols(coSeqRep); }