/// <summary> /// Calculates the centroids of the clusters /// </summary> private void CalculateClusterCenters() { for (int j = 0; j < this.Clusters.Count; j++) { ClusterCentroid c = this.Clusters[j]; double uX = 0.0; double uY = 0.0; double l = 0.0; for (int i = 0; i < this.Points.Count; i++) { ClusterPoint p = this.Points[i]; double uu = Math.Pow(U[i, j], this.Fuzzyness); uX += uu * c.X; uY += uu * c.Y; l += uu; } c.X = ((int)(uX / l)); c.Y = ((int)(uY / l)); this.Log += string.Format("Cluster Centroid: ({0}; {1})" + System.Environment.NewLine, c.X, c.Y); } }
/// <summary> /// Initialize the algorithm with points and initial clusters /// </summary> /// <param name="points">Points</param> /// <param name="clusters">Clusters</param> /// <param name="fuzzy">The fuzzyness factor to be used</param> public CMeansAlgorithm(List <ClusterPoint> points, List <ClusterCentroid> clusters, float fuzzy) { if (points == null) { throw new ArgumentNullException("points"); } if (clusters == null) { throw new ArgumentNullException("clusters"); } this.Points = points; this.Clusters = clusters; U = new double[this.Points.Count, this.Clusters.Count]; //Uk = new double[this.Points.Count, this.Clusters.Count]; this.Fuzzyness = fuzzy; double diff; // Iterate through all points to create initial U matrix for (int i = 0; i < this.Points.Count; i++) { ClusterPoint p = this.Points[i]; double sum = 0.0; for (int j = 0; j < this.Clusters.Count; j++) { ClusterCentroid c = this.Clusters[j]; diff = Math.Sqrt(Math.Pow(p.X - c.X, 2.0) + Math.Pow(p.Y - c.Y, 2.0)); U[i, j] = (diff == 0) ? Eps : diff; sum += U[i, j]; } double sum2 = 0.0; for (int j = 0; j < this.Clusters.Count; j++) { U[i, j] = 1.0 / Math.Pow(U[i, j] / sum, 2.0 / (Fuzzyness - 1.0)); sum2 += U[i, j]; } for (int j = 0; j < this.Clusters.Count; j++) { U[i, j] = U[i, j] / sum2; } } this.RecalculateClusterIndexes(); }
/// <summary> /// Calculates Euler's distance between point and centroid /// </summary> /// <param name="p">Point</param> /// <param name="c">Centroid</param> /// <returns>Calculated distance</returns> private double CalculateEulerDistance(ClusterPoint p, ClusterCentroid c) { return(Math.Sqrt(Math.Pow(p.X - c.X, 2) + Math.Pow(p.Y - c.Y, 2))); }