public static void MInitializeCentersRandomlyBetweenMaxMinRanges(List <MyPoint> aoPList, ref List <ClusterCenterPoint> aoCList, int aiNumClusters) { ClusterCenterPoint koCP; int kiNum; // determine ranges double kdMinX = (from koP in aoPList select koP.VdX).Min( ); double kdMinY = (from koP in aoPList select koP.VdY).Min( ); double kdMaxX = (from koP in aoPList select koP.VdX).Max( ); double kdMaxY = (from koP in aoPList select koP.VdX).Max( ); // initialize cluster centers randomly Random koRand = new Random(( int )DateTime.Now.Ticks); aoCList = new List <ClusterCenterPoint>( ); for (int i = 0; i < aiNumClusters; i++) { //ClusterCenterPoint cp = new ClusterCenterPoint { Cx = rand.NextDouble() * (maxX - minX), Cy = rand.NextDouble() * (maxY - minY) }; kiNum = ( int )koRand.NextDouble( ) * aoPList.Count; koCP = new ClusterCenterPoint { VdCx = aoPList[kiNum].VdX, VdCy = aoPList[kiNum].VdY }; koCP.ViClusterID = i; aoCList.Add(koCP); } }
public static void MInitializeCentersRandomlyFromGivenPoints(List <MyPoint> aoPList, ref List <ClusterCenterPoint> aoCList, int aiNumClusters) { ClusterCenterPoint koCP; Random koRand = new Random(( int )DateTime.Now.Ticks); List <int> koPListInt = new List <int>( ); int kiNum; aoCList = new List <ClusterCenterPoint>( ); for (int i = 0; i < aoPList.Count; i++) { koPListInt.Add(i); } for (int i = 0; i < aiNumClusters; i++) { kiNum = koRand.Next(koPListInt.Count); koCP = new ClusterCenterPoint { VdCx = aoPList[kiNum].VdX, VdCy = aoPList[kiNum].VdY }; koCP.ViClusterID = i; koPListInt.RemoveAt(kiNum); // remove the number that has been selected so that it does not get selected again aoCList.Add(koCP); } if (aoCList.Count < aiNumClusters) { throw new Exception("problem in initializing cluster centers.."); } }
public static void InitializeCentersRandomlyFromGivenPoints(List <MyPoint> PList, ref List <ClusterCenterPoint> CList, int numClusters) { Random rand = new Random((int)DateTime.Now.Ticks); CList = new List <ClusterCenterPoint>(); List <int> PListInt = new List <int>(); for (int i = 0; i < PList.Count; i++) { PListInt.Add(i); } for (int i = 0; i < numClusters; i++) { int num = rand.Next(PListInt.Count); ClusterCenterPoint cp = new ClusterCenterPoint { Cx = PList[num].X, Cy = PList[num].Y }; cp.ClusterID = i; PListInt.RemoveAt(num); // remove the number that has been selected so that it does not get selected again CList.Add(cp); } if (CList.Count < numClusters) { throw new Exception("problem in initializing cluster centers.."); } }
public static void InitializeCentersRandomlyBetweenMaxMinRanges(List <MyPoint> PList, ref List <ClusterCenterPoint> CList, int numClusters) { // determine ranges double minX = (from p in PList select p.X).Min(); double minY = (from p in PList select p.Y).Min(); double maxX = (from p in PList select p.X).Max(); double maxY = (from p in PList select p.X).Max(); // initialize cluster centers randomly Random rand = new Random((int)DateTime.Now.Ticks); CList = new List <ClusterCenterPoint>(); for (int i = 0; i < numClusters; i++) { //ClusterCenterPoint cp = new ClusterCenterPoint { Cx = rand.NextDouble()*(maxX - minX), Cy = rand.NextDouble() * (maxY - minY) }; int num = (int)rand.NextDouble() * PList.Count; ClusterCenterPoint cp = new ClusterCenterPoint { Cx = PList[num].X, Cy = PList[num].Y }; cp.ClusterID = i; CList.Add(cp); } }
public static void MInitializeCentersRandomlyFromKPP(List <MyPoint> aoPList, ref List <ClusterCenterPoint> aoCList, int aiNumClusters) { Random koRand = new Random(( int )DateTime.Now.Ticks); List <int> koPListInt = new List <int>( ); int kiNum; double kdRandom; double kdSumProbab; double kdDist; double kdDistPrev; double kdDxSquared; double[] kdDxPrimeSquared; ClusterCenterPoint koCP; aoCList = new List <ClusterCenterPoint>( ); for (int i = 0; i < aoPList.Count; i++) { koPListInt.Add(i); } //step1: of KPP - choose a center randomly from given set of points kiNum = koRand.Next(koPListInt.Count); koCP = new ClusterCenterPoint { VdCx = aoPList[kiNum].VdX, VdCy = aoPList[kiNum].VdY }; koCP.ViClusterID = 0; koPListInt.RemoveAt(kiNum); // remove the number that has been selected so that it does not get selected again aoCList.Add(koCP); for (int i = 1; i < aiNumClusters; i++) { // Step2: Compute D(x)^2 where D(x) is the distance of x from closest centers chosen. kdDxSquared = 0; kdDxPrimeSquared = new double[koPListInt.Count]; for (int m = 0; m < koPListInt.Count; m++) { kdDistPrev = double.MaxValue; foreach (ClusterCenterPoint koCCP in aoCList) { kdDist = MFindDistance(aoPList[koPListInt[m]].VdX, aoPList[koPListInt[m]].VdY, koCCP.VdCx, koCCP.VdCy); if (kdDist < kdDistPrev) { kdDistPrev = kdDist; } } //dxprimeSquared[PListInt[m]] = distprev * distprev; kdDxPrimeSquared[m] = kdDistPrev * kdDistPrev; // dxprimesquared value is actually for point PListInt[m] kdDxSquared += kdDistPrev * kdDistPrev; } // select the center according to probability d(x')^2/(d()^2 kdRandom = koRand.NextDouble( ); kdSumProbab = 0; for (int n = 0; n < kdDxPrimeSquared.Length; n++) { kdSumProbab += (kdDxPrimeSquared[n] / kdDxSquared); if (kdRandom <= kdSumProbab) { // choose this PList[PListInt[n]] as the next cluster center koCP = new ClusterCenterPoint { VdCx = aoPList[koPListInt[n]].VdX, VdCy = aoPList[koPListInt[n]].VdY }; koCP.ViClusterID = i; koPListInt.RemoveAt(n); // remove the number that has been selected so that it does not get selected again aoCList.Add(koCP); break; } } } }
public static int MDoKMeans(int aiNumClusters, ref List <MyPoint> aoPList, ref List <ClusterCenterPoint> aoCL, double adMaxError, int aiMaxIterations, bool abDoKmeansPlusPlus = false) { List <ClusterCenterPoint> koCList = null; List <ClusterCenterPoint> koCListNew = null; ClusterCenterPoint koCPNew; double kdError = double.MaxValue; double kdErr = 0; int kiIteration = 0; int kiC0Count; int kiC1Count; int kiC2Count; int[] kiCCount; if (abDoKmeansPlusPlus == false) { MInitializeCentersRandomlyFromGivenPoints(aoPList, ref koCList, aiNumClusters); } else { MInitializeCentersRandomlyFromKPP(aoPList, ref koCList, aiNumClusters); } while ((kiIteration < aiMaxIterations) || (kdError < adMaxError)) { Task koFinal; Task[] koTask = new Task[aoPList.Count]; koCListNew = new List <ClusterCenterPoint>(); kiCCount = new int[koCList.Count]; foreach (ClusterCenterPoint koCP in koCList) { koCPNew = new ClusterCenterPoint( ); koCListNew.Add(koCPNew); koCPNew.VdCx = 0; koCPNew.VdCy = 0; } for (int i = 0; i < aoPList.Count; i++) { koTask[i] = Task.Factory.StartNew((aoP) => { MyPoint koP = ( MyPoint )aoP; int kiK = 0; double kdPrevDist = double.MaxValue; double kdDist; foreach (ClusterCenterPoint koCP in koCList) { kdDist = MFindDistance(koP.VdX, koP.VdY, koCP.VdCx, koCP.VdCy); if (kdDist < kdPrevDist) { kdPrevDist = kdDist; koP.ViClusterId = kiK; } kiK++; } koCListNew[koP.ViClusterId].VdCx += koP.VdX; koCListNew[koP.ViClusterId].VdCy += koP.VdY; kiCCount[koP.ViClusterId]++; }, aoPList[i]); } koFinal = Task.Factory.ContinueWhenAll(koTask, (aoTask) => { // ---------------Recompute cluster centers------------------- int kiKnew = 0; foreach (ClusterCenterPoint koCP in koCListNew) { koCP.VdCx = koCP.VdCx / kiCCount[kiKnew]; koCP.VdCy = koCP.VdCy / kiCCount[kiKnew]; kiKnew++; } //------------------end recompute cluster centers----------------- //---------------see if new centers are different from previous--- kdErr = 0; for (int i = 0; i < koCList.Count; i++) { kdErr += ((koCListNew[i].VdCx - koCList[i].VdCx) * (koCListNew[i].VdCx - koCList[i].VdCx) + (koCListNew[i].VdCy - koCList[i].VdCy) * (koCListNew[i].VdCy - koCList[i].VdCy)); } }); // determine which cluster each point belongs to kiC0Count = (from koP in aoPList where koP.ViClusterId == 0 select koP).ToList <MyPoint>( ).Count; kiC1Count = (from koP in aoPList where koP.ViClusterId == 1 select koP).ToList <MyPoint>( ).Count; kiC2Count = (from koP in aoPList where koP.ViClusterId == 2 select koP).ToList <MyPoint>( ).Count; if (kdErr < adMaxError) { break; } koCList.Clear( ); koCList = koCListNew; kiIteration++; } aoCL = koCList; return(kiIteration); }
public static void InitializeCentersRandomlyFromKPP(List <MyPoint> PList, ref List <ClusterCenterPoint> CList, int numClusters) { Random rand = new Random((int)DateTime.Now.Ticks); CList = new List <ClusterCenterPoint>(); List <int> PListInt = new List <int>(); for (int i = 0; i < PList.Count; i++) { PListInt.Add(i); } //step1: of KPP - choose a center randomly from given set of points int num = rand.Next(PListInt.Count); ClusterCenterPoint cp = new ClusterCenterPoint { Cx = PList[num].X, Cy = PList[num].Y }; cp.ClusterID = 0; PListInt.RemoveAt(num); // remove the number that has been selected so that it does not get selected again CList.Add(cp); for (int i = 1; i < numClusters; i++) { // Step2: Compute D(x)^2 where D(x) is the distance of x from closest centers chosen double dxSquared = 0; double[] dxprimeSquared = new double[PListInt.Count]; for (int m = 0; m < PListInt.Count; m++) { double distprev = double.MaxValue; foreach (ClusterCenterPoint ccp in CList) { double dist = FindDistance(PList[PListInt[m]].X, PList[PListInt[m]].Y, ccp.Cx, ccp.Cy); if (dist < distprev) { distprev = dist; } } //dxprimeSquared[PListInt[m]] = distprev * distprev; dxprimeSquared[m] = distprev * distprev; // dxprimesquared value is actually for point PListInt[m] dxSquared += distprev * distprev; } // select the center according to probability d(x')^2/(d()^2 double randNum = rand.NextDouble(); double sumProbab = 0; for (int n = 0; n < dxprimeSquared.Length; n++) { sumProbab = sumProbab + dxprimeSquared[n] / dxSquared; if (randNum <= sumProbab) { // choose this PList[PListInt[n]] as the next cluster center ClusterCenterPoint cpp = new ClusterCenterPoint { Cx = PList[PListInt[n]].X, Cy = PList[PListInt[n]].Y }; cpp.ClusterID = i; PListInt.RemoveAt(n); // remove the number that has been selected so that it does not get selected again CList.Add(cpp); break; } } } }
public static int DoKMeans(int numClusters, ref List <MyPoint> PList, ref List <ClusterCenterPoint> CL, double maxError, int maxIterations, bool doKmeansPlusPlus = false) { List <ClusterCenterPoint> CList = null; if (doKmeansPlusPlus == false) { InitializeCentersRandomlyFromGivenPoints(PList, ref CList, numClusters); } else { InitializeCentersRandomlyFromKPP(PList, ref CList, numClusters); } double error = double.MaxValue; int iteration = 0; while ((iteration < maxIterations) || (error < maxError)) { // determine which clusetr each point belongs to foreach (MyPoint p in PList) { // determine which cluster it belongs to int k = 0; double prevDist = double.MaxValue; foreach (ClusterCenterPoint cp in CList) { double dist = FindDistance(p.X, p.Y, cp.Cx, cp.Cy); if (dist < prevDist) { prevDist = dist; p.ClusterId = k; } k++; } } int c0count = (from p in PList where p.ClusterId == 0 select p).ToList <MyPoint>().Count; int c1count = (from p in PList where p.ClusterId == 1 select p).ToList <MyPoint>().Count; int c2count = (from p in PList where p.ClusterId == 2 select p).ToList <MyPoint>().Count; // ---------------Recompute cluster centers------------------- List <ClusterCenterPoint> CListNew = new List <ClusterCenterPoint>(); int[] CCount = new int[CList.Count]; foreach (ClusterCenterPoint cp in CList) { ClusterCenterPoint cpnew = new ClusterCenterPoint(); CListNew.Add(cpnew); cpnew.Cx = 0; cpnew.Cy = 0; } foreach (MyPoint p in PList) { CListNew[p.ClusterId].Cx += p.X; CListNew[p.ClusterId].Cy += p.Y; CCount[p.ClusterId]++; } int knew = 0; foreach (ClusterCenterPoint cp in CListNew) { cp.Cx = cp.Cx / CCount[knew]; cp.Cy = cp.Cy / CCount[knew]; knew++; } //------------------end recompute cluster centers----------------- //---------------see if new centers are different from previous--- double err = 0; for (int i = 0; i < CList.Count; i++) { err = err + ((CListNew[i].Cx - CList[i].Cx) * (CListNew[i].Cx - CList[i].Cx) + (CListNew[i].Cy - CList[i].Cy) * (CListNew[i].Cy - CList[i].Cy)); } if (err < maxError) { break; } CList.Clear(); CList = CListNew; iteration++; } CL = CList; return(iteration); }