public void updateMedoids(int K, Cluster[] clusters)
 {
     for (int clusterIdx = 0; clusterIdx < K; clusterIdx++)
     {
         clusters[clusterIdx].updateMedoid();
     }
 }
 public void selectInitialMedoids(Matrix<double> distanceMX, int K, 
     out Cluster[] clusters, out double totalCost)
 {
     Dictionary<double, int> dictOfMiddleness = computeMiddlenessOfObjs(distanceMX);
     int[] selectedMedoids = determineMedoidsBasedOnMiddleness(dictOfMiddleness, K);
     clusters = buildClusters(distanceMX, K, selectedMedoids);
     totalCost = utils.calculateTotalCost(K, clusters);
 }
 public double calculateTotalCost(int K, Cluster[] clusters)
 {
     double totalCost = 0.0;
     for (int clusterIdx = 0; clusterIdx < K; clusterIdx++)
     {
         totalCost += clusters[clusterIdx].calculateCost();
     }
     return totalCost;
 }
 private Cluster[] buildClusters(Matrix<double> distanceMX, int K, int[] selectedMedoids)
 {
     Cluster[] clusters = new Cluster[K];
     for (int selectedMedoidIdx = 0; selectedMedoidIdx < K; selectedMedoidIdx++)
     {
         clusters[selectedMedoidIdx] = new Cluster(distanceMX, selectedMedoids[selectedMedoidIdx]);
     }
     utils.assign(distanceMX, K, selectedMedoids, clusters);
     return clusters;
 }
 public double assignObjsToClusters(Matrix<double> distanceMX, int K, Cluster[] clusters)
 {
     int[] selectedMedoids = new int[K];
     for (int selectedMedoidIdx = 0; selectedMedoidIdx < K; selectedMedoidIdx++)
     {
         selectedMedoids[selectedMedoidIdx] = clusters[selectedMedoidIdx].MedoidIdx;
         clusters[selectedMedoidIdx].Members.Clear();
     }
     utils.assign(distanceMX, K, selectedMedoids, clusters);
     double totalCost = utils.calculateTotalCost(K, clusters);
     return totalCost;
 }
 public void assign(Matrix<double> distanceMX, int K, int[] selectedMedoids, Cluster[] clusters)
 {
     int nObj = distanceMX.RowCount;
     for (int idx = 0; idx < nObj; idx++)
     {
         double minMedoidDist = double.MaxValue;
         int minSelectedMedoidIdx = -1;
         for (int selectedMedoidIdx = 0; selectedMedoidIdx < K; selectedMedoidIdx++)
         {
             double currentMedoidDist = distanceMX[idx, selectedMedoids[selectedMedoidIdx]];
             if (currentMedoidDist < minMedoidDist)
             {
                 minMedoidDist = currentMedoidDist;
                 minSelectedMedoidIdx = selectedMedoidIdx;
             }
         }
         clusters[minSelectedMedoidIdx].Members.Add(idx);
     }
 }