Пример #1
0
 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) ;
 }
Пример #2
0
        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);
        }