docs: private ArrayDBIDs greedy(DistanceQuery<V> distFunc, DBIDs sampleSet, int m, Random random) {
      ArrayModifiableDBIDs medoids = DBIDUtil.newArray(m);
  
      ArrayModifiableDBIDs s = DBIDUtil.newArray(sampleSet);
      DBIDArrayIter iter = s.iter();
      DBIDVar m_i = DBIDUtil.newVar();
      int size = s.size();
  
      // Move a random element to the end, then pop()
      s.swap(random.nextInt(size), --size);
      medoids.add(s.pop(m_i));
      if(LOG.isDebugging()) {
        LOG.debugFiner("medoids " + medoids.toString());
      }
  
      // To track the current worst element:
      int worst = -1;
      double worstd = Double.NEGATIVE_INFINITY;
  
      // compute distances between each point in S and m_i
      WritableDoubleDataStore distances = DataStoreUtil.makeDoubleStorage(s, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
      for(iter.seek(0); iter.getOffset() < size; iter.advance()) {
        final double dist = distFunc.distance(iter, m_i);
        distances.putDouble(iter, dist);
        if(dist > worstd) {
          worstd = dist;
          worst = iter.getOffset();
        }
      }
  
      for(int i = 1; i < m; i++) {
        // choose medoid m_i to be far from previous medoids
        s.swap(worst, --size);
        medoids.add(s.pop(m_i));
  
        // compute distances of each point to closest medoid; track worst.
        worst = -1;
        worstd = Double.NEGATIVE_INFINITY;
        for(iter.seek(0); iter.getOffset() < size; iter.advance()) {
          double dist_new = distFunc.distance(iter, m_i);
          double dist_old = distances.doubleValue(iter);
          double dist = (dist_new < dist_old) ? dist_new : dist_old;
          distances.putDouble(iter, dist);
          if(dist > worstd) {
            worstd = dist;
            worst = iter.getOffset();
          }
        }
  
        if(LOG.isDebugging()) {
          LOG.debugFiner("medoids " + medoids.toString());
        }
      }
  
      return medoids;
    }