Пример #1
0
            // O(k*n)
            List <XY> RunClusterAlgo()
            {
                // put points in buckets
                int allPointsCount = BaseDataset.Count;
                var firstPoint     = BaseDataset[0];

                firstPoint.Color = GetRandomColor();
                var firstId     = 0.ToString();
                var firstBucket = new Bucket(firstId)
                {
                    Centroid = firstPoint
                };

                BaseBucketsLookup.Add(firstId, firstBucket);

                for (int i = 1; i < allPointsCount; i++)
                {
                    var set = new HashSet <string>();    //cluster candidate list
                    var p   = BaseDataset[i];
                    // iterate clusters and collect candidates
                    foreach (var bucket in BaseBucketsLookup.Values)
                    {
                        var isInCluster = MathTool.BoxWithin(p, bucket.Centroid, MARKERCLUSTERER_SIZE);
                        if (!isInCluster)
                        {
                            continue;
                        }

                        set.Add(bucket.Id);
                        //use first, short dist will be calc at last step before returning data
                        break;
                    }

                    // if not within box area, then make new cluster
                    if (set.Count == 0)
                    {
                        var pid = i.ToString();
                        p.Color = GetRandomColor();
                        var newbucket = new Bucket(pid)
                        {
                            Centroid = p
                        };
                        BaseBucketsLookup.Add(pid, newbucket);
                    }
                }

                //important, align all points to closest cluster point
                BaseUpdatePointsByCentroid();

                return(BaseGetClusterResult());
            }
Пример #2
0
            public List <XY> RunClusterAlgo(int grxid, int gryid)
            {
                GlobalClass.program += "43. GridBaseCluster.RunClusterAlgo .. ";
                // var clusterPoints = new List<XY>();
                // params invalid
                if (BaseDataset == null || BaseDataset.Count == 0 ||
                    grxid <= 0 || gryid <= 0)
                {
                    return(clusterPoints);
                }

                // put points in buckets
                foreach (var p in BaseDataset)
                {
                    // find relative val
                    var relativeX = p.X - MinX;
                    var relativeY = p.Y - MinY;

                    int xid = (int)(relativeX / DeltaX);
                    int yid = (int)(relativeY / DeltaY);

                    // bucket id
                    string id = GetId(xid, yid);

                    // bucket exists, add point
                    if (BaseBucketsLookup.ContainsKey(id))
                    {
                        BaseBucketsLookup[id].Points.Add(p);
                    }

                    // new bucket, create and add point
                    else
                    {
                        Bucket bucket = new Bucket(xid, yid);
                        bucket.Points.Add(p);
                        BaseBucketsLookup.Add(id, bucket);
                    }
                }

                // calc centrod for all buckets
                BaseSetCentroidForAllBuckets(BaseBucketsLookup.Values);

                // merge if gridpoint is to close
                MergeClustersGrid();

                return(BaseGetClusterResult());
            }
Пример #3
0
            void MergeClustersGridHelper(string currentKey, string[] neighborKeys)
            {
                GlobalClass.program += "41. GridBaseCluster.MergeClustersGridHelper .. ";
                double minDistX = DeltaX / 2.0;//heuristic, higher value gives less merging
                double minDistY = DeltaY / 2.0;
                //if clusters in grid are too close to each other, merge them
                double minDist = MathTool.Max(minDistX, minDistY);

                foreach (var neighborKey in neighborKeys)
                {
                    if (!BaseBucketsLookup.ContainsKey(neighborKey))
                    {
                        continue;
                    }

                    var neighbor = BaseBucketsLookup[neighborKey];
                    if (neighbor.IsUsed == false)
                    {
                        continue;
                    }

                    var current = BaseBucketsLookup[currentKey];
                    var dist    = MathTool.Distance(current.Centroid, neighbor.Centroid);
                    if (dist > minDist)
                    {
                        continue;
                    }

                    var centroidgroup = current.Centroid.CGroup;
                    foreach (var p in neighbor.Points)
                    {
                        //update CGroup
                        p.CGroup = centroidgroup;
                    }//end

                    neighP = neighbor.Points.ToArray();


                    current.Points.AddRange(neighbor.Points);//O(n)

                    // recalc centroid
                    var cp = BaseGetCentroidFromCluster(current.Points);
                    current.Centroid = cp;
                    neighbor.IsUsed  = false; //merged, then not used anymore
                }
            }
Пример #4
0
            void RunAlgo()
            {
                // Init clusters
                var centroids = BaseGetRandomCentroids(BaseDataset, _InitClusterSize);

                for (int i = 0; i < centroids.Length; i++)
                {
                    var pid       = i.ToString();
                    var newbucket = new Bucket(pid)
                    {
                        Centroid = centroids[i]
                    };
                    BaseBucketsLookup.Add(pid, newbucket);
                }

                //
                double currentMaxError = double.MaxValue;

                while (currentMaxError > MAX_ERROR && BaseBucketsLookup.Count < _MaxClusters)
                {
                    RunIterationsUntilKClusterPlacementAreDone();

                    var id     = BaseGetMaxError();
                    var bucket = BaseBucketsLookup[id];
                    currentMaxError = bucket.ErrorLevel;     //update
                    if (currentMaxError > MAX_ERROR)
                    {
                        // Here it is linear speed when putting one new centroid at a time
                        // should be semi-fast because the new point is inserted at best area
                        //from current centroids view.
                        // possible improvement exists by log2 search by inserting multiple centroids and
                        // reducing centroid again if needed

                        // put new centroid in area where maxError but farthest away from current centroid in area
                        var longest     = BaseGetLongestPoint(bucket.Centroid, bucket.Points);
                        var newcentroid = new XY(longest);
                        var newid       = BaseBucketsLookup.Count.ToString();
                        var newbucket   = new Bucket(newid)
                        {
                            Centroid = newcentroid
                        };
                        BaseBucketsLookup.Add(newid, newbucket);
                    }
                }
            }
Пример #5
0
            void MergeClustersGridHelper(string currentKey, string[] neighborKeys)
            {
                double minDistX = DeltaX / 2.0;    //heuristic, higher value gives less merging
                double minDistY = DeltaY / 2.0;
                //if clusters in grid are too close to each other, merge them
                double minDist = MathTool.Max(minDistX, minDistY);

                foreach (var neighborKey in neighborKeys)
                {
                    if (!BaseBucketsLookup.ContainsKey(neighborKey))
                    {
                        continue;
                    }

                    var neighbor = BaseBucketsLookup[neighborKey];
                    if (neighbor.IsUsed == false)
                    {
                        continue;
                    }

                    var current = BaseBucketsLookup[currentKey];
                    var dist    = MathTool.Distance(current.Centroid, neighbor.Centroid);
                    if (dist > minDist)
                    {
                        continue;
                    }

                    // merge
                    var color = current.Centroid.Color;
                    foreach (var p in neighbor.Points)
                    {
                        //update color
                        p.Color = color;
                    }

                    current.Points.AddRange(neighbor.Points);    //O(n)

                    // recalc centroid
                    var cp = BaseGetCentroidFromCluster(current.Points);
                    current.Centroid = cp;
                    neighbor.IsUsed  = false;    //merged, then not used anymore
                    neighbor.Points.Clear();     //clear mem
                }
            }
Пример #6
0
            static void UpdatePointsByCentroid()//O(n*k)
            {
                GlobalClass.program += "36. Updatepointsbycentroid.. ";
                int count = BaseBucketsLookup.Count();

                // clear points in the buckets, they will be re-inserted
                foreach (var bucket in BaseBucketsLookup.Values)
                {
                    bucket.Points.Clear();
                }

                foreach (XY p in BaseDataset)
                {
                    double minDist = Double.MaxValue;
                    int    index   = -1;
                    for (int i = 0; i < count; i++)
                    {
                        var bucket = BaseBucketsLookup[i.ToString()];
                        if (bucket.IsUsed == false)
                        {
                            continue;
                        }

                        var centroid = bucket.Centroid;
                        var dist     = MathTool.Distance(p, centroid);
                        if (dist < minDist)
                        {
                            // update
                            minDist = dist;
                            index   = i;
                        }
                    }
                    //update CGroup for point to match centroid and re-insert
                    var closestBucket = BaseBucketsLookup[index.ToString()];
                    p.CGroup = closestBucket.Centroid.CGroup;
                    closestBucket.Points.Add(p);
                }

                Profile("UpdatePointsByCentroid");
            }
Пример #7
0
            public static void RunAlgo()
            {
                GlobalClass.program += "32. runalgo .. ";
                // Init clusters
                var centroids = BaseGetRandomCentroids(BaseDataset, InitClusterSize);

                for (int i = 0; i < centroids.Length; i++)
                {
                    var newbucket = new Bucket(i.ToString())
                    {
                        Centroid = centroids[i]
                    };
                    BaseBucketsLookup.Add(i.ToString(), newbucket);
                }

                //
                double currentMaxError = double.MaxValue;

                while (currentMaxError > MAX_ERROR && BaseBucketsLookup.Count < _MaxClusters)
                {
                    RunIterationsUntilKClusterPlacementAreDone();

                    var id = BaseGetMaxError();
                    //BaseGetMaxError();
                    var bucket = BaseBucketsLookup[id];
                    currentMaxError = bucket.ErrorLevel; //update
                    if (currentMaxError > MAX_ERROR)
                    {
                        var longest     = BaseGetLongestPoint(bucket.Centroid, bucket.Points);
                        var newcentroid = new XY(longest);
                        var newid       = BaseBucketsLookup.Count.ToString();
                        var newbucket   = new Bucket(newid)
                        {
                            Centroid = newcentroid
                        };
                        BaseBucketsLookup.Add(newid, newbucket);
                    }
                }
            }
Пример #8
0
            public List <XY> RunClusterAlgo(int gridx, int gridy)
            {
                // params invalid
                if (gridx <= 0 || gridy <= 0)
                {
                    throw new ApplicationException("GridCluster.RunClusterAlgo gridx or gridy is <= 0");
                }

                // put points in buckets
                foreach (var p in BaseDataset)
                {
                    // find relative val
                    var relativeX = p.X - MinX;
                    var relativeY = p.Y - MinY;

                    int idx = (int)(relativeX / DeltaX);
                    int idy = (int)(relativeY / DeltaY);

                    // bucket id
                    string id = GetId(idx, idy);

                    // bucket exists, add point
                    if (BaseBucketsLookup.ContainsKey(id))
                    {
                        BaseBucketsLookup[id].Points.Add(p);
                    }

                    // new bucket, create and add point
                    else
                    {
                        Bucket bucket = new Bucket(idx, idy);
                        bucket.Points.Add(p);
                        BaseBucketsLookup.Add(id, bucket);
                    }
                }

                // calc centrod for all buckets
                BaseSetCentroidForAllBuckets(BaseBucketsLookup.Values);

                // merge if gridpoint is to close
                if (DoMergeGridIfCentroidsAreCloseToEachOther)
                {
                    MergeClustersGrid();
                }

                if (DoUpdateAllCentroidsToNearestContainingPoint)
                {
                    BaseUpdateAllCentroidsToNearestContainingPoint();
                }

                // check again
                // merge if gridpoint is to close
                if (DoMergeGridIfCentroidsAreCloseToEachOther &&
                    DoUpdateAllCentroidsToNearestContainingPoint)
                {
                    MergeClustersGrid();
                    // and again set centroid to closest point in bucket
                    BaseUpdateAllCentroidsToNearestContainingPoint();
                }

                return(BaseGetClusterResult());
            }