Beispiel #1
0
        public static KMeansResult Compute(int k, Vector3[] data)
        {
            int n = data.Length;
            KMeansResult res = new KMeansResult(n, k);

            // Find Random Points
            Random r = new Random();
            List<int> rAssign = new List<int>(k);
            int li = 0;
            while(li < k) {
                int rn = r.Next(n);
                if(rAssign.Contains(rn)) continue;
                li++;
                rAssign.Add(rn);
            }

            // Assign Random Centroids
            for(int i = 0; i < k; i++)
                res.Centroids[i] = data[rAssign[i]];

            int[] lastAssign = Enumerable.Repeat<int>(-1, n).ToArray();
            while(Different(lastAssign, res.ClusterAssigns)) {
                // Swap
                var buf = lastAssign;
                lastAssign = res.ClusterAssigns;
                res.ClusterAssigns = buf;

                // Compute
                for(int ni = 0; ni < n; ni++) {
                    int c = 0;
                    float d = (data[ni] - res.Centroids[0]).LengthSquared();
                    for(int ci = 1; ci < k; ci++) {
                        float nd = (data[ni] - res.Centroids[ci]).LengthSquared();
                        if(nd < d) {
                            c = ci;
                            d = nd;
                        }
                    }
                    res.ClusterAssigns[ni] = c;
                }

                // Find New Centroids
                int[] count = new int[k];
                for(int i = 0; i < k; i++)
                    res.Centroids[i] = Vector3.Zero;
                for(int ni = 0; ni < n; ni++) {
                    res.Centroids[res.ClusterAssigns[ni]] += data[ni];
                    count[res.ClusterAssigns[ni]]++;
                }
                for(int i = 0; i < k; i++)
                    res.Centroids[i] /= count[i];
            }
            return res;
        }
Beispiel #2
0
        public static void Compute(int k, Vector3[] data, ref KMeansResult res, int stepPause)
        {
            int n = data.Length;

            // Find Random Points
            Random     r       = new Random();
            List <int> rAssign = new List <int>(k);
            int        li      = 0;

            while (li < k)
            {
                int rn = r.Next(n);
                if (rAssign.Contains(rn))
                {
                    continue;
                }
                li++;
                rAssign.Add(rn);
            }

            // Assign Random Centroids
            for (int i = 0; i < k; i++)
            {
                res.Centroids[i] = data[rAssign[i]];
            }

            int[] lastAssign = Enumerable.Repeat <int>(-1, n).ToArray();
            while (Different(lastAssign, res.ClusterAssigns))
            {
                // Copy Swap
                res.ClusterAssigns.CopyTo(lastAssign, 0);

                // Compute
                for (int ni = 0; ni < n; ni++)
                {
                    int   c = 0;
                    float d = (data[ni] - res.Centroids[0]).LengthSquared();
                    for (int ci = 1; ci < k; ci++)
                    {
                        float nd = (data[ni] - res.Centroids[ci]).LengthSquared();
                        if (nd < d)
                        {
                            c = ci;
                            d = nd;
                        }
                    }
                    res.ClusterAssigns[ni] = c;
                }

                // Find New Centroids
                int[] count = new int[k];
                for (int i = 0; i < k; i++)
                {
                    res.Centroids[i] = Vector3.Zero;
                }
                for (int ni = 0; ni < n; ni++)
                {
                    res.Centroids[res.ClusterAssigns[ni]] += data[ni];
                    count[res.ClusterAssigns[ni]]++;
                }
                for (int i = 0; i < k; i++)
                {
                    res.Centroids[i] /= count[i];
                }

                // Pause
                Thread.Sleep(stepPause);
            }
        }