class KMeansPlusPlusClusterer {

    public List<Cluster<T>> cluster(final Collection<T> points, final int k,
                                    int numTrials, int maxIterationsPerTrial)
        throws MathIllegalArgumentException, ConvergenceException {

        // at first, we have not found any clusters list yet
        List<Cluster<T>> best = null;
        double bestVarianceSum = Double.POSITIVE_INFINITY;

        // do several clustering trials
        for (int i = 0; i < numTrials; ++i) {

            // compute a clusters list
            List<Cluster<T>> clusters = cluster(points, k, maxIterationsPerTrial);

            // compute the variance of the current list
            double varianceSum = 0.0;
            for (final Cluster<T> cluster : clusters) {
                if (!cluster.getPoints().isEmpty()) {

                    // compute the distance variance of the current cluster
                    final T center = cluster.getCenter();
                    final Variance stat = new Variance();
                    for (final T point : cluster.getPoints()) {
                        stat.increment(point.distanceFrom(center));
                    }
                    varianceSum += stat.getResult();

                }
            }

            if (varianceSum <= bestVarianceSum) {
                // this one is the best we have found so far, remember it
                best            = clusters;
                bestVarianceSum = varianceSum;
            }

        }

        // return the best clusters list found
        return best;

    }

    public  KMeansPlusPlusClusterer(final Random random);
    public  KMeansPlusPlusClusterer(final Random random, final EmptyClusterStrategy emptyStrategy);

}