private static void MergeClusters(FuzzyModel fm) { List <FuzzyNodeCluster> clustersToRemove = new List <FuzzyNodeCluster>(); foreach (FuzzyNodeCluster fnc in fm.GetClusters()) { // are all predecessors clusters? bool allClustersIn = true; if (fnc.GetInEdges().Count == 0) { allClustersIn = false; } else { foreach (FuzzyEdge fe in fnc.GetInEdges()) { if (!fm.IsCluster(fe.GetFromNode())) { allClustersIn = false; break; } } } // if they are if (allClustersIn) { // find the most correlated float max = 0; FuzzyNodeCluster chosenOne = null; foreach (FuzzyEdge fe in fnc.GetInEdges()) { if ((fe.GetEndpointCorrelation() + fe.GetProximityCorrelation()) > max) { max = fe.GetEndpointCorrelation() + fe.GetProximityCorrelation(); chosenOne = fm.GetCluster(fe.GetFromNode()); } } // merge the clusters foreach (FuzzyNode fn in fnc.GetNodesInCluster()) { chosenOne.AddNodeToCluster(fn); } List <FuzzyEdge> toRemove = new List <FuzzyEdge>(); foreach (FuzzyEdge fe in fnc.GetInEdges()) { if (fe.Equals(fm.GetEdge(chosenOne, fnc))) { //RemoveEdge(fe); toRemove.Add(fe); } else { FuzzyEdge newFe = new FuzzyEdge(fe.GetFromNode(), chosenOne); //RemoveEdge(fe); toRemove.Add(fe); fm.AddEdge(newFe); } } foreach (FuzzyEdge fe in fnc.GetOutEdges()) { FuzzyEdge newFe = new FuzzyEdge(chosenOne, fe.GetToNode()); //RemoveEdge(fe); toRemove.Add(fe); fm.AddEdge(newFe); } foreach (FuzzyEdge fe in toRemove) { fm.RemoveEdge(fe); } //RemoveCluster(fnc); clustersToRemove.Add(fnc); } else { // are all successors clusters? bool allClustersOut = true; if (fnc.GetOutEdges().Count == 0) { allClustersOut = false; } else { foreach (FuzzyEdge fe in fnc.GetOutEdges()) { if (!fm.IsCluster(fe.GetToNode())) { allClustersOut = false; break; } } } // if they are if (allClustersOut) { // find the most correlated float max = 0; FuzzyNodeCluster chosenOne = null; foreach (FuzzyEdge fe in fnc.GetOutEdges()) { if ((fe.GetEndpointCorrelation() + fe.GetProximityCorrelation()) > max) { max = fe.GetEndpointCorrelation() + fe.GetProximityCorrelation(); chosenOne = fm.GetCluster(fe.GetToNode()); } } // merge the clusters foreach (FuzzyNode fn in fnc.GetNodesInCluster()) { chosenOne.AddNodeToCluster(fn); } List <FuzzyEdge> toRemove = new List <FuzzyEdge>(); foreach (FuzzyEdge fe in fnc.GetOutEdges()) { if (fe.Equals(fm.GetEdge(chosenOne, fnc))) { toRemove.Add(fe); } else { FuzzyEdge newFe = new FuzzyEdge(chosenOne, fe.GetToNode()); toRemove.Add(fe); fm.AddEdge(newFe); } } foreach (FuzzyEdge fe in fnc.GetInEdges()) { FuzzyEdge newFe = new FuzzyEdge(fe.GetFromNode(), chosenOne); toRemove.Add(fe); fm.AddEdge(newFe); } foreach (FuzzyEdge fe in toRemove) { fm.RemoveEdge(fe); } clustersToRemove.Add(fnc); } } } foreach (FuzzyNodeCluster fnc in clustersToRemove) { fm.RemoveCluster(fnc); } }
public static FuzzyModel parseLogFile(string file) { FuzzyModel fm = new FuzzyModel(); List <XTrace> traces = getTracesXES(file); string root = "start_node"; string end = "end_node"; fm.AddNode(root); foreach (XTrace xt in traces) { fm.GetNode(root).IncreaseFrequencySignificance(); var xamTrace = xt.GetAttributes(); foreach (string key in xamTrace.Keys) { if (key != "concept:name") { fm.GetNode(root).AddSignificantAttribute(key, xamTrace[key].ToString()); } } string previousEvent = root; string previousState = ""; double eventDuration = 0; double traceDuration = 0; double previousTime = 0; foreach (XEvent xe in xt) { // find event name XAttributeMap xam = (XAttributeMap)xe.GetAttributes(); string currentEvent; string currentState = ""; if (xam.Keys.Contains <string>("lifecycle:transition")) { currentState = xam["lifecycle:transition"].ToString(); } double currentTime = 0; if (xam.Keys.Contains <string>("time:timestamp")) { currentTime = Convert.ToDateTime(xam["time:timestamp"].ToString()).ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; } currentEvent = xam["concept:name"].ToString(); // if the event is new, add it to the graph if (!fm.GetEvents().Contains(currentEvent)) { FuzzyNode node = new FuzzyNode(currentEvent); fm.AddNode(node); // if it is not the first event in the trace, add edges if (previousEvent != null) { FuzzyEdge e = new FuzzyEdge(fm.GetNode(previousEvent), node); // if the edge is new add it to the list if (!fm.GetNode(previousEvent).GetOutEdges().Contains(e)) { fm.AddEdge(e); } // if it's not the start node, compute the duration of the transition if (previousEvent != "start_node") { fm.GetEdge(e).AddDuration(currentTime - previousTime); traceDuration += currentTime - previousTime; } fm.GetEdge(e).IncreaseFrequencySignificance(); } fm.GetNode(currentEvent).IncreaseFrequencySignificance(); } else { // if it is not the first event in the trace, add edges if (previousEvent != null) { FuzzyEdge e = new FuzzyEdge(fm.GetNode(previousEvent), fm.GetNode(currentEvent)); // if the edge is new add it to the list if (!fm.GetNode(previousEvent).GetOutEdges().Contains(e)) { fm.AddEdge(e); } // if it's not the start node, compute the duration of the transition if (previousEvent != "start_node") { fm.GetEdge(e).AddDuration(currentTime - previousTime); traceDuration += currentTime - previousTime; } fm.GetEdge(e).IncreaseFrequencySignificance(); } // if the event is the same but the state is different, compute the event duration if (previousEvent == currentEvent && previousState != currentState) { if (previousState == "complete" && currentState == "start") { fm.GetNode(currentEvent).IncreaseFrequencySignificance(); } eventDuration += currentTime - previousTime; } else { fm.GetNode(currentEvent).IncreaseFrequencySignificance(); } } // if the event is complete add its duration to the node if (currentState == "complete") { fm.GetNode(currentEvent).AddDuration(eventDuration); traceDuration += eventDuration; eventDuration = 0; } // add the event attributes to the node foreach (string key in xam.Keys) { if (key != "concept:name" && key != "lifecycle:transition") { if (key != "time:timestamp" && key.IndexOf("id", StringComparison.OrdinalIgnoreCase) < 0) { fm.GetNode(currentEvent).AddSignificantAttribute(key, xam[key].ToString()); } fm.GetNode(currentEvent).AddAttribute(key, xam[key].ToString()); } } previousEvent = currentEvent; previousState = currentState; previousTime = currentTime; } if (!fm.GetEvents().Contains(end)) { fm.AddNode(end); fm.GetNode(end).IncreaseFrequencySignificance(); } else { fm.GetNode(end).IncreaseFrequencySignificance(); } FuzzyEdge fe = new FuzzyEdge(fm.GetNode(previousEvent), fm.GetNode(end)); if (!fm.GetEdges().Contains(fe)) { fm.AddEdge(fe); fm.GetEdge(fe).IncreaseFrequencySignificance(); } else { fm.GetEdge(fe).IncreaseFrequencySignificance(); } fm.GetNode(root).AddDuration(traceDuration); } foreach (XTrace xt in traces) { foreach (FuzzyNode fn in fm.GetNodes()) { foreach (XEvent xe in xt) { if (xe.GetAttributes()["concept:name"].ToString().Equals(fn.GetLabel())) { fn.IncreaseCaseFrequencySignificance(); break; } } } foreach (FuzzyEdge fe in fm.GetEdges()) { string previousEvent = ""; foreach (XEvent xe in xt) { string currentEvent = xe.GetAttributes()["concept:name"].ToString(); if (previousEvent.Equals(fe.GetFromNode().GetLabel()) && currentEvent.Equals(fe.GetToNode().GetLabel())) { fe.IncreaseCaseFrequencySignificance(); break; } previousEvent = currentEvent; } } } return(fm); }
public static void ConflictResolution(FuzzyModel fm, float preserveThr, float ratioThr) { List <FuzzyEdge> toRemove = new List <FuzzyEdge>(); foreach (FuzzyEdge AB in fm.GetEdges()) { FuzzyEdge BA = fm.GetEdge(AB.GetToNode(), AB.GetFromNode()); float relAB = 0; float relBA = 0; if (BA != null) { if (AB.Equals(BA)) { toRemove.Add(AB); } if (toRemove.Contains(AB) || toRemove.Contains(BA)) { continue; } FuzzyNode A = AB.GetFromNode(); FuzzyNode B = AB.GetToNode(); // compute relative significance of edge A->B float sigAB = AB.GetFrequencySignificance(); float sigAX = 0; foreach (FuzzyEdge AX in A.GetOutEdges()) { sigAX += AX.GetFrequencySignificance(); } float sigXB = 0; foreach (FuzzyEdge XB in B.GetInEdges()) { sigXB += XB.GetFrequencySignificance(); } relAB = (0.5F * (sigAB / sigAX)) + (0.5F * (sigAB / sigXB)); Console.WriteLine("{0}, Relative significance: {1}", AB.ToString(), relAB); // compute relative significance of edge B->A float sigBA = BA.GetFrequencySignificance(); float sigBX = 0; foreach (FuzzyEdge BX in B.GetOutEdges()) { sigBX += BX.GetFrequencySignificance(); } float sigXA = 0; foreach (FuzzyEdge XA in A.GetInEdges()) { sigXA += XA.GetFrequencySignificance(); } relBA = (0.5F * (sigBA / sigBX)) + (0.5F * (sigBA / sigXA)); Console.WriteLine("{0}, Relative significance: {1}", BA.ToString(), relBA); // Decide preservation if (relAB < preserveThr || relBA < preserveThr) { float ofsAB = Math.Abs(relAB - relBA); if (ofsAB < ratioThr) { toRemove.Add(AB); toRemove.Add(BA); } else { if (relAB > relBA) { toRemove.Add(BA); } else { toRemove.Add(AB); } } } } } foreach (FuzzyEdge fe in toRemove) { fm.RemoveEdge(fe); } }