/// <inheritdoc />
 public ClusteringResult <TInstance> GetClustering(ClusterSet <TInstance> clusterSet) =>
 this.GetClustering(clusterSet, clusterSet.Dissimilarity);
        /// <inheritdoc />
        public ClusteringResult <TInstance> GetClustering(IEnumerable <Cluster <TInstance> > clusters,
                                                          double dissimilarity = 0d)
        {
            // initializes elements
            var currentClusters = clusters.ToArray();

            this._clusters        = new Cluster <TInstance> [currentClusters.Length * 2 - 1];
            this._dissimilarities = new double[currentClusters.Length * 2 - 1][];
            this._curClusterCount = 0;

            // calculates initial dissimilarities
            foreach (var cluster in currentClusters)
            {
                this._clusters[this._curClusterCount] = cluster;
                this.UpdateDissimilarities();
                this._curClusterCount++;
            }

            var clustering = new ClusteringResult <TInstance>(currentClusters.Length)
            {
                [0] = new ClusterSet <TInstance>(currentClusters, dissimilarity)
            };
            var numSteps = currentClusters.Length;

            for (var i = 1; i < numSteps; i++)
            {
                // gets minimal dissimilarity between a pair of existing clusters
                var minDissimilarity = this.GetMinDissimilarity(out var clusterIdx1, out var clusterIdx2);

                // gets a copy of previous clusters, removes new cluster elements
                var cluster1    = this._clusters[clusterIdx1];
                var cluster2    = this._clusters[clusterIdx2];
                var newClusters = new Cluster <TInstance> [currentClusters.Length - 1];
                var idx         = 0;
                foreach (var cluster in currentClusters)
                {
                    if (!cluster.Equals(cluster1) && !cluster.Equals(cluster2))
                    {
                        newClusters[idx++] = cluster;
                    }
                }
                this._clusters[clusterIdx1] = null;
                this._clusters[clusterIdx2] = null;

                // creates a new cluster from the union of closest clusters (save reference to parents)
                var newCluster = new Cluster <TInstance>(cluster1, cluster2, minDissimilarity);

                // adds cluster to list and calculates distance to all others
                newClusters[idx] = this._clusters[this._curClusterCount] = newCluster;
                this.UpdateDissimilarities();
                this._curClusterCount++;

                // updates global list of clusters
                currentClusters = newClusters;
                clustering[i]   = new ClusterSet <TInstance>(currentClusters, minDissimilarity);
            }

            this._clusters        = null;
            this._dissimilarities = null;
            return(clustering);
        }
 /// <summary>
 ///     Creates a new <see cref="ClusterSetEvaluation{TInstance}" />.
 /// </summary>
 /// <param name="clusterSet">The cluster-set that was evaluated.</param>
 /// <param name="evaluationValue">The value of the evaluation.</param>
 public ClusterSetEvaluation(ClusterSet <TInstance> clusterSet, double evaluationValue)
 {
     this.ClusterSet      = clusterSet;
     this.EvaluationValue = evaluationValue;
 }