docs: public Clustering<?> run(Database database, Relation<? extends UncertainObject> relation) {
      ResultHierarchy hierarchy = database.getHierarchy();
      ArrayList<Clustering<?>> clusterings = new ArrayList<>();
      final int dim = RelationUtil.dimensionality(relation);
      DBIDs ids = relation.getDBIDs();
      // To collect samples
      Result samples = new BasicResult("Samples", "samples");
  
      // Step 1: Cluster sampled possible worlds:
      Random rand = random.getSingleThreadedRandom();
      FiniteProgress sampleP = LOG.isVerbose() ? new FiniteProgress("Clustering samples", numsamples, LOG) : null;
      for(int i = 0; i < numsamples; i++) {
        WritableDataStore<DoubleVector> store = DataStoreUtil.makeStorage(ids, DataStoreFactory.HINT_DB, DoubleVector.class);
        for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
          store.put(iter, relation.get(iter).drawSample(rand));
        }
        clusterings.add(runClusteringAlgorithm(hierarchy, samples, ids, store, dim, "Sample " + i));
        LOG.incrementProcessed(sampleP);
      }
      LOG.ensureCompleted(sampleP);
  
      // Step 2: perform the meta clustering (on samples only).
      DBIDRange rids = DBIDFactory.FACTORY.generateStaticDBIDRange(clusterings.size());
      WritableDataStore<Clustering<?>> datastore = DataStoreUtil.makeStorage(rids, DataStoreFactory.HINT_DB, Clustering.class);
      {
        Iterator<Clustering<?>> it2 = clusterings.iterator();
        for(DBIDIter iter = rids.iter(); iter.valid(); iter.advance()) {
          datastore.put(iter, it2.next());
        }
      }
      assert (rids.size() == clusterings.size());
  
      // Build a relation, and a distance matrix.
      Relation<Clustering<?>> crel = new MaterializedRelation<Clustering<?>>(Clustering.TYPE, rids, "Clusterings", datastore);
      PrecomputedDistanceMatrix<Clustering<?>> mat = new PrecomputedDistanceMatrix<>(crel, rids, distance);
      mat.initialize();
      ProxyDatabase d = new ProxyDatabase(rids, crel);
      d.getHierarchy().add(crel, mat);
      Clustering<?> c = metaAlgorithm.run(d);
      d.getHierarchy().remove(d, c); // Detach from database
  
      // Evaluation
      Result reps = new BasicResult("Representants", "representative");
      hierarchy.add(relation, reps);
  
      DistanceQuery<Clustering<?>> dq = mat.getDistanceQuery(distance);
      List<? extends Cluster<?>> cl = c.getAllClusters();
      List<DoubleObjPair<Clustering<?>>> evaluated = new ArrayList<>(cl.size());
      for(Cluster<?> clus : cl) {
        double besttau = Double.POSITIVE_INFINITY;
        Clustering<?> bestc = null;
        for(DBIDIter it1 = clus.getIDs().iter(); it1.valid(); it1.advance()) {
          double tau = 0.;
          Clustering<?> curc = crel.get(it1);
          for(DBIDIter it2 = clus.getIDs().iter(); it2.valid(); it2.advance()) {
            if(DBIDUtil.equal(it1, it2)) {
              continue;
            }
            double di = dq.distance(curc, it2);
            tau = di > tau ? di : tau;
          }
          // Cluster member with the least maximum distance.
          if(tau < besttau) {
            besttau = tau;
            bestc = curc;
          }
        }
        if(bestc == null) { // E.g. degenerate empty clusters
          continue;
        }
        // Global tau:
        double gtau = 0.;
        for(DBIDIter it2 = crel.iterDBIDs(); it2.valid(); it2.advance()) {
          double di = dq.distance(bestc, it2);
          gtau = di > gtau ? di : gtau;
        }
        final double cprob = computeConfidence(clus.size(), crel.size());
  
        // Build an evaluation result
        hierarchy.add(bestc, new RepresentativenessEvaluation(gtau, besttau, cprob));
  
        evaluated.add(new DoubleObjPair<Clustering<?>>(cprob, bestc));
      }
      // Sort evaluated results by confidence:
      Collections.sort(evaluated, Collections.reverseOrder());
      for(DoubleObjPair<Clustering<?>> pair : evaluated) {
        // Attach parent relation (= sample) to the representative samples.
        for(It<Relation<?>> it = hierarchy.iterParents(pair.second).filter(Relation.class); it.valid(); it.advance()) {
          hierarchy.add(reps, it.get());
        }
      }
      // Add the random samples below the representative results only:
      if(keep) {
        hierarchy.add(relation, samples);
      }
      else {
        hierarchy.removeSubtree(samples);
      }
      return c;
    }