docs: public OutlierResult run(Database database, Relation<O> relation) {
      StepProgress stepprog = LOG.isVerbose() ? new StepProgress("CBLOF", 3) : null;
      DBIDs ids = relation.getDBIDs();
  
      LOG.beginStep(stepprog, 1, "Computing clustering.");
      Clustering<MeanModel> clustering = clusteringAlgorithm.run(database);
  
      LOG.beginStep(stepprog, 2, "Computing boundary between large and small clusters.");
      List<? extends Cluster<MeanModel>> clusters = clustering.getAllClusters();
      Collections.sort(clusters, new Comparator<Cluster<MeanModel>>() {
        @Override
        public int compare(Cluster<MeanModel> o1, Cluster<MeanModel> o2) {
          // Sort in descending order by size
          return Integer.compare(o2.size(), o1.size());
        }
      });
      int clusterBoundary = getClusterBoundary(relation, clusters);
  
      List<? extends Cluster<MeanModel>> largeClusters = clusters.subList(0, clusterBoundary + 1);
      List<? extends Cluster<MeanModel>> smallClusters = clusters.subList(clusterBoundary + 1, clusters.size());
  
      LOG.beginStep(stepprog, 3, "Computing Cluster-Based Local Outlier Factors (CBLOF).");
      WritableDoubleDataStore cblofs = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_DB);
      DoubleMinMax cblofMinMax = new DoubleMinMax();
      computeCBLOFs(relation, distance, cblofs, cblofMinMax, largeClusters, smallClusters);
  
      LOG.setCompleted(stepprog);
  
      DoubleRelation scoreResult = new MaterializedDoubleRelation("Cluster-Based Local Outlier Factor", "cblof-outlier", cblofs, ids);
      OutlierScoreMeta scoreMeta = new QuotientOutlierScoreMeta(cblofMinMax.getMin(), cblofMinMax.getMax(), 0.0, Double.POSITIVE_INFINITY, 1.0);
      return new OutlierResult(scoreMeta, scoreResult);
    }