public Cluster[] apply(Matrix<double> objCoords, int K, double[] weights)
        {
            Cluster[] clusters;
            EuclideanDistMXComputer distMXComp = new EuclideanDistMXComputer();
            ClusteringManagementUtils utils = new ClusteringManagementUtils();
            InitialMedoidsSelection initMedoidsSelection = new InitialMedoidsSelection(utils);
            MedoidsUpdater medoidsUpdater = new MedoidsUpdater();
            ObjectsAssigner objectsAssigner = new ObjectsAssigner(utils);

            Matrix<double> distanceMX = distMXComp.determineEuclideanDistMX(objCoords);
            //Matrix<double> distanceMX = distMXComp.determineWeightedEuclideanDistMX(objCoords, weights);
            double currentTotalCost;
            initMedoidsSelection.selectInitialMedoids(distanceMX, K, out clusters, out currentTotalCost);
            double newTotalCost = currentTotalCost;
            bool firstIter = true;
            do
            {
                if (firstIter)
                {
                    firstIter = false;
                }
                else
                {
                    currentTotalCost = newTotalCost;
                }
                medoidsUpdater.updateMedoids(K, clusters);
                newTotalCost = objectsAssigner.assignObjsToClusters(distanceMX, K, clusters);
            } while (newTotalCost < currentTotalCost);
            return clusters;
        }
 public ObjectsAssigner(ClusteringManagementUtils utils)
 {
     this.utils = utils;
 }
 public InitialMedoidsSelection(ClusteringManagementUtils utils)
 {
     this.utils = utils;
 }