All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.venky.clustering.Clusterer Maven / Gradle / Ivy

There is a newer version: 1.18
Show newest version
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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy