docs: public HistogramResult run(Database database, Relation<O> relation) {
      final DistanceQuery<O> distanceQuery = database.getDistanceQuery(relation, getDistanceFunction());
      final KNNQuery<O> knnQuery = database.getKNNQuery(distanceQuery, relation.size());
  
      if(LOG.isVerbose()) {
        LOG.verbose("Preprocessing clusters...");
      }
      // Cluster by labels
      Collection<Cluster<Model>> split = (new ByLabelOrAllInOneClustering()).run(database).getAllClusters();
  
      DoubleHistogram hist = new DoubleHistogram(numbins, 0.0, 1.0);
  
      if(LOG.isVerbose()) {
        LOG.verbose("Processing points...");
      }
      FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("Computing ROC AUC values", relation.size(), LOG) : null;
  
      ROCEvaluation roc = new ROCEvaluation();
      MeanVariance mv = new MeanVariance();
      // sort neighbors
      for(Cluster<?> clus : split) {
        for(DBIDIter iter = clus.getIDs().iter(); iter.valid(); iter.advance()) {
          KNNList knn = knnQuery.getKNNForDBID(iter, relation.size());
          double result = EvaluateClustering.evaluateRanking(roc, clus, knn);
  
          mv.put(result);
          hist.increment(result, 1. / relation.size());
  
          LOG.incrementProcessed(progress);
        }
      }
      LOG.ensureCompleted(progress);
  
      // Transform Histogram into a Double Vector array.
      Collection<double[]> res = new ArrayList<>(relation.size());
      for(DoubleHistogram.Iter iter = hist.iter(); iter.valid(); iter.advance()) {
        res.add(new double[] { iter.getCenter(), iter.getValue() });
      }
      HistogramResult result = new HistogramResult("Ranking Quality Histogram", "ranking-histogram", res);
      result.addHeader("Mean: " + mv.getMean() + " Variance: " + mv.getSampleVariance());
      return result;
    }