DBID first = DBIDUtil.randomSample(relation.getDBIDs(), 1, random.nextLong()).iterator().next();
means.add(relation.get(first).getColumnVector());
ModifiableDBIDs chosen = DBIDUtil.newHashSet(k);
chosen.add(first);
ArrayDBIDs ids = DBIDUtil.ensureArray(relation.getDBIDs());
// Initialize weights
double[] weights = new double[ids.size()];
double weightsum = initialWeights(weights, ids, first, distQ);
while(means.size() < k) {
if(weightsum > Double.MAX_VALUE) {
LoggingUtil.warning("Could not choose a reasonable mean for k-means++ - too many data points, too large squared distances?");
}
if(weightsum < Double.MIN_NORMAL) {
LoggingUtil.warning("Could not choose a reasonable mean for k-means++ - to few data points?");
}
double r = random.nextDouble() * weightsum;
int pos = 0;
while(r > 0 && pos < weights.length) {
r -= weights[pos];
pos++;
}
// Add new mean:
DBID newmean = ids.get(pos);
means.add(relation.get(newmean).getColumnVector());
chosen.add(newmean);
// Update weights:
weights[pos] = 0.0;
// Choose optimized version for double distances, if applicable.