public static int SquaredEuclideanDistance(Point point, Centroid centroid) { //(A.x - B.x)^2 + (A.y - B.y)^2 return (point.X - centroid.X) * (point.X - centroid.X) + (point.Y - centroid.Y) * (point.Y - centroid.Y) ; }
public void Start(Boolean needVisualEterations, ref Int32 numberofIterations) { // Input: // K = clustersCount - number of clusters // {Point1, Point2, ... , PointN} - dataset of given points(vectors) {x1, x2, ... , xN} // Output: // {Centroid1, Centroid2, ... , CentroidK} - dataset of new cluster centroids {jm1, jm2, ... , jmK} // // Implementation: // {Centroid1, Centroid2, ... , CentroidK} <-- SelectRandomSeeds({Point1, Point2, ... , PointN}, K) List<Centroid> prevCentroids; do { numberofIterations++; prevCentroids = new List<Centroid>(centroids); // Step 1 - Clear Clusters for (Int32 k = 0; k < clustersCount; k++) clusters[k].Clear(); // Step 2 - Find Closest Centroid for (Int32 n = 0; n < pointsCount; n++) { var point = points[n]; Int32 j = K_Math.ArgMin(K_Math.SquaredEuclideanDistances(point, centroids)); clusters[j].Add(points[n]); // Wj = Wj U {Xn} } if (needVisualEterations) { graphics.Clear(Color.White); DrawClusters(); } //Step 3 - Update Centroids for (Int32 k = 0; k < clustersCount; k++) { // 1 // jm[k] = -------- * ESum(X), where X C W[k]; // | W[k] | Point sum = new Point(0, 0); foreach (var point in clusters[k]) { sum.X += point.X; sum.Y += point.Y; } Int32 newX = sum.X /= clusters[k].Count; Int32 newY = sum.Y /= clusters[k].Count; centroids[k] = new Centroid(newX, newY, centroids[k].Color); } if (needVisualEterations) { DrawCentroids(); Thread.Sleep(100); } } while (!Centroid.AreEqualCentroids(prevCentroids, centroids)); if (!needVisualEterations) { graphics.Clear(Color.White); DrawClusters(); } Thread.Sleep(1000); }