// 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()); }
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()); }
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 } }
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); } } }
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 } }
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"); }
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); } } }
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()); }