public KMeansFunctionRecognitionAlgorithm(ClusteringSettings settings) { this.Settings = settings; this.Score = new KMeansFunctionRecognitonScore(); this.Score.Centroids = new double[settings.NumberOfClusters][]; if (this.Settings.FuncRecogMethod == 1) { this.Score.InClusterMaxDistance = new double[settings.NumberOfClusters]; this.Score.MaxCentroid = null; this.Score.MinCentroid = null; for (int i = 0; i < settings.NumberOfClusters; i++) { this.Score.Centroids[i] = new double[settings.NumOfDimensions]; } } else { this.Score.InClusterMaxDistance = null; this.Score.MaxCentroid = new double[settings.NumberOfClusters][]; this.Score.MinCentroid = new double[settings.NumberOfClusters][]; for (int i = 0; i < settings.NumberOfClusters; i++) { this.Score.MaxCentroid[i] = new double[settings.NumOfDimensions]; this.Score.MinCentroid[i] = new double[settings.NumOfDimensions]; this.Score.Centroids[i] = new double[settings.NumOfDimensions]; for (int dim = 0; dim < settings.NumOfDimensions; dim++) { this.Score.MaxCentroid[i][dim] = double.MinValue; this.Score.MinCentroid[i][dim] = double.MaxValue; } } } }
public static int OptimalNumberOfClusters_TwoFunctions(double[][] functions1, double[][] functions2, ClusteringSettings settings, int MinNumClusters, int MaxNumClusters, out double[] Fmins_k) { if (MinNumClusters < 2) { MinNumClusters = 2; } double[][] oneFunction = new double[settings.NumOfDimensions][]; int numFun = 0; double dist; int score = 0; KMeansFunctionRecognitionAlgorithm kMeansFR1, kMeansFR2; KMeansFunctionRecognitonScore res1, res2; double Fmax = 0; double Fmin = double.MaxValue; double[] Fmins; Fmins_k = new double[MaxNumClusters - MinNumClusters + 1]; double F = 0; int cluster = -1; for (int k = MinNumClusters; k <= MaxNumClusters; k++) { settings.InitialCentroids = null; settings.NumberOfClusters = k; kMeansFR1 = new KMeansFunctionRecognitionAlgorithm(settings); kMeansFR2 = new KMeansFunctionRecognitionAlgorithm(settings); res1 = new KMeansFunctionRecognitonScore(); res2 = new KMeansFunctionRecognitonScore(); numFun = functions1.Length / settings.NumOfDimensions; for (int f = 0; f < numFun; f++) { oneFunction = KMeansAlgorithm.transposeFunction(KMeansAlgorithm.selectFunction(functions1, f + 1, settings.NumOfDimensions)); res1 = kMeansFR1.Run(oneFunction, null) as KMeansFunctionRecognitonScore; } numFun = functions2.Length / settings.NumOfDimensions; settings.InitialCentroids = null; for (int f = 0; f < numFun; f++) { oneFunction = KMeansAlgorithm.transposeFunction(KMeansAlgorithm.selectFunction(functions2, f + 1, settings.NumOfDimensions)); res2 = kMeansFR2.Run(oneFunction, null) as KMeansFunctionRecognitonScore; } Fmins = new double[k]; // check if there is a non intersection cluster for (int i = 0; i < k; i++) { Fmin = double.MaxValue; score = 0; for (int j = 0; j < k; j++) { dist = KMeansAlgorithm.calculateDistance(res1.Centroids[i], res2.Centroids[j]); if (dist > res1.InClusterMaxDistance[i] + res2.InClusterMaxDistance[j]) { score++; } } if (score == k) { //calculate F; for (int j = 0; j < k; j++) { F = KMeansAlgorithm.calculateDistance(res1.Centroids[i], res2.Centroids[j]) / (res1.InClusterMaxDistance[i] + res2.InClusterMaxDistance[j]); // select min F among the two functions if (F < Fmin) { Fmin = F; } } } //save Fmin of each centroid if (Fmin != double.MaxValue) { Fmins[i] = Fmin; } } // save max Fmin per number of clusters for (int i = 0; i < k; i++) { if (Fmins[i] > Fmins_k[k - MinNumClusters]) { Fmins_k[k - MinNumClusters] = Fmins[i]; } } } //select max F among different number of cluters for (int i = 0; i < Fmins_k.Length; i++) { if (Fmins_k[i] > Fmax) { Fmax = Fmins_k[i]; cluster = i + MinNumClusters; } } return(cluster); }