com.venky.clustering.Clusterer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of common Show documentation
Show all versions of common Show documentation
Commonly used programming tasks in java
package com.venky.clustering;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Clusterer {
private Metric metric;
private CenterFinderBuilder centerFinderBuilder ;
private static class DefaultCenterFinderBuilder implements CenterFinderBuilder {
private CenterFinder centerFinder;
public DefaultCenterFinderBuilder(CenterFinder finder) {
this.centerFinder = finder;
}
@Override
public CenterFinder build(Cluster cluster) {
return this.centerFinder;
}
}
public Clusterer(CenterFinderBuilder cf, Metric m){
this.centerFinderBuilder = cf;
this.metric = m;
}
public Clusterer(CenterFinder cf, Metric m){
this(new DefaultCenterFinderBuilder(cf),m);
}
public Clusterer(Metric m){
this(new DefaultCenterFinderBuilder(null),m);
}
public Metric getMetric(){
return metric;
}
public List> cluster(Collection points, List centroids){
List> clusters = new ArrayList>();
for (T centroid: centroids){
Cluster init = new Cluster(centerFinderBuilder,metric);
init.addPoint(centroid);
clusters.add(init);
}
for (T p : points){
int closestCentroidIndex = -1;
double distanceToClosestCentroid = Double.POSITIVE_INFINITY;
for (int i = 0; i < centroids.size() ; i ++ ){
double distanceToCentroid = metric.distance(centroids.get(i),p);
if (distanceToClosestCentroid > distanceToCentroid){
distanceToClosestCentroid = distanceToCentroid;
closestCentroidIndex = i ;
}
}
if (closestCentroidIndex >= 0 ){
clusters.get(closestCentroidIndex).addPoint(p);
}
}
return clusters;
}
public List> cluster(Collection points, int maxClusters){
return cluster(points,new MaxClustersCreated(maxClusters));
}
public List> cluster(Collection points,StopCriteria stopCriteria){
List> clusters = new ArrayList>();
for (T point: points){
Cluster init = new Cluster(centerFinderBuilder,metric);
init.addPoint(point);
clusters.add(init);
}
Map,Map,Double>> distances = new HashMap, Map,Double>>();
Cluster clusterGrown = null;
Cluster clusterDestroyed = null;
while (!stopCriteria.canStop(clusters,clusterGrown,clusterDestroyed)){
int indexGrown = 0;
int indexDestroyed = 0;
double minDistance = Double.POSITIVE_INFINITY;
for (int i = 0 ; i < clusters.size() ; i ++ ){
Cluster inspected = clusters.get(i);
Map,Double> inspectedDistances = distances.get(inspected);
if (inspectedDistances == null){
inspectedDistances = new HashMap, Double>();
distances.put(inspected, inspectedDistances);
}
for (int j = i +1 ; j < clusters.size() ; j ++){
Cluster other = clusters.get(j);
Double distance = inspectedDistances.get(other);
if (distance == null){
if (inspected.centroid() != null){
distance = inspected.centroidDistance(other);
}else {
distance = inspected.distance(other).getMaxDistance();
}
inspectedDistances.put(other, distance);
}
if (minDistance > distance){
minDistance = distance;
indexGrown = i ;
indexDestroyed = j ;
}
}
}
if (minDistance == Double.POSITIVE_INFINITY){
break;
}
clusterGrown = clusters.get(indexGrown);
clusterDestroyed = clusters.remove(indexDestroyed); //Note index Destroyed >= indexGrown.
for (T p : clusterDestroyed.getPoints()){
clusterGrown.addPoint(p);
}
distances.remove(clusterGrown);
distances.remove(clusterDestroyed);
for (Cluster remaining: distances.keySet()){
distances.get(remaining).remove(clusterGrown);
distances.get(remaining).remove(clusterDestroyed);
}
}
return clusters;
}
}