/// <summary> /// Checks the validity between two clusters /// </summary> /// <param name="A">The first cluster</param> /// <param name="S">The second cluster</param> /// <returns>True if they can merge, false otherwise</returns> private bool checkValidity(Cluster A, Cluster S) { if (A.StartData == S.StartData) { return true; } else if (A.StartData > S.StartData) { if ( 1 - Math.Abs((A.StartData - S.Min) / A.StartData) >= QoS) { return true; } else { return false; } } else if (A.StartData < S.StartData) { if ( 1 - Math.Abs((A.StartData - S.Max) / A.StartData) >= QoS) { return true; } else { return false; } } else { return false; } }
/// <summary> /// Handles a MSGReport message that the nodes sent to inform the representative /// </summary> /// <param name="message">The message</param> private void handleMSGReportCluster(MSGReportCluster message) { bool clusterFound = false; if (message.RID == Info.ID) { foreach (var cluster in Clusters) { if (cluster.ID == message.OriginalNode.CID) { cluster.Add(message.OriginalNode); clusterFound = true; break; } } if (!clusterFound) { Cluster cluster = new Cluster(message.OriginalNode.CID); cluster.Add(message.OriginalNode); Clusters.Add(cluster); ClustersI.Add(cluster.ID); } } }
/// <summary> /// Fixes the cluster formation to make it more realistic (in case the starter node has gone absent) /// </summary> /// <param name="cluster">The cluster to check</param> internal void fixCSID(Cluster cluster) { //Fix Singleton foreach (var cCluster in Clusters) { if (cCluster.Nodes.Count == 1) { cCluster.ID = SimLib.Properties.Simulation.Default.Nodes * 100 + cCluster.Nodes[0].Info.ID; cCluster.StartData = cCluster.Nodes[0].Data; cCluster.StartID = cCluster.Nodes[0].Info.ID; cCluster.Max = cCluster.StartData; cCluster.Min = cCluster.StartData; } } bool foundSID = false; int SID = cluster.StartID; double SIDM = cluster.StartData; foreach (var node in cluster.Nodes) { if (node.Info.ID == cluster.StartID) { foundSID = true; break; } } if (!foundSID) { //Fix SID selection double MaxAccuracy = -2; int _SID = SID; double _SIDMeasurement = SIDM; foreach (var reference in cluster.Nodes) { bool isValid = true; int __SID = reference.Info.ID; double __SIDMeasurement = reference.Data; double _MinAccuracy = double.MaxValue; foreach (var node1 in cluster.Nodes) { double __Accuracy = getDataChange(node1.Data, __SIDMeasurement); if (__Accuracy < 0) { isValid = false; break; } _MinAccuracy = Math.Min(__Accuracy, _MinAccuracy); //It is actually the minimum accuracy :-) } if (!isValid) { continue; } if (_MinAccuracy > MaxAccuracy) //Min-Max criterion { _SID = __SID; _SIDMeasurement = __SIDMeasurement; MaxAccuracy = _MinAccuracy; } } cluster.StartID = _SID; cluster.StartData = _SIDMeasurement; cluster.ID = (-1 * cluster.StartID); //Fix Min, Max values double _Min = Double.MaxValue; double _Max = Double.MinValue; foreach (var node in cluster.Nodes) { node.CID = cluster.ID; node.SID = cluster.StartID; node.SIDMeasurement = cluster.StartData; _Min = Math.Min(node.Data, _Min); _Max = Math.Max(node.Data, _Max); } cluster.Max = _Max; cluster.Min = _Min; } }