Я использую кластер k -средства ++ из Apache Commons Math в интерактивном генетическом алгоритме, чтобы уменьшить количество людей, которые оцениваются пользователем.Как рассчитать центроиды в k-средствах ++ с помощью расстояний?
Commons Math делает его очень простым в использовании. Пользователю необходимо реализовать интерфейс Clusterable
. Он имеет два метода:
double distanceFrom(T p)
, что совершенно ясно и T centroidOf(Collection<T> p)
, что позволяет пользователю выбрать центр тяжести кластера.
Если используется в эвклидовых точках, центроид очень легко вычислить. Но на хромосомах это довольно сложно, потому что их смысл не всегда ясен.
Мой вопрос: Существует ли эффективный общий способ выбора центра тяжести, не зависящего от проблемного домена? (Например, с использованием расстояния)
EDIT
Ок, вот теперь мой код для центроида расчета. Идея: точка, которая имеет самое низкое общее расстояние до всех остальных точек, является ближайшей к центроиду.
public T centroidOf(Collection<T> c) {
double minDist = Double.MAX_VALUE;
T minP = null;
// iterate through c
final Iterator<T> it = c.iterator();
while (it.hasNext()) {
// test every point p1
final T p1 = it.next();
double totalDist = 0d;
for (final T p2 : c) {
// sum up the distance to all points p2 | p2!=p1
if (p2 != p1) {
totalDist += p1.distanceFrom(p2);
}
}
// if the current distance is lower that the min, take it as new min
if (totalDist < minDist) {
minDist = totalDist;
minP = p1;
}
}
return minP;
}
Спасибо за подсказку. Я хочу использовать точку населения в качестве центра тяжести, не создавая новых точек. Но я также хочу использовать эту реализацию. Вопрос только в том, как реализовать метод «centroidOf()»? На данный момент я выбираю точку сбора случайным образом. – Stephan
В ссылке есть алгоритм. – cyborg
Я принимаю ответ из-за вашей ссылки. Желаемая реализация теперь показана в исходном вопросе. – Stephan