/*
* Copyright (c) 2003, the JUNG Project and the Regents of the University
* of California
* All rights reserved.
*
* This software is open-source under the BSD license; see either
* "license.txt" or
* http://jung.sourceforge.net/license.txt for a description.
*/
/*
* Created on Aug 9, 2004
*
*/
package edu.uci.ics.jung.algorithms.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
/**
* Groups items into a specified number of clusters, based on their proximity in
* d-dimensional space, using the k-means algorithm. Calls to
* cluster
will terminate when either of the two following
* conditions is true:
*
* the number of iterations is > max_iterations
* none of the centroids has moved as much as convergence_threshold
* since the previous iteration
*
*
* @author Joshua O'Madadhain
*/
public class KMeansClusterer
{
protected int max_iterations;
protected double convergence_threshold;
protected Random rand;
/**
* Creates an instance whose termination conditions are set according
* to the parameters.
*/
public KMeansClusterer(int max_iterations, double convergence_threshold)
{
this.max_iterations = max_iterations;
this.convergence_threshold = convergence_threshold;
this.rand = new Random();
}
/**
* Creates an instance with max iterations of 100 and convergence threshold
* of 0.001.
*/
public KMeansClusterer()
{
this(100, 0.001);
}
/**
* Returns the maximum number of iterations.
*/
public int getMaxIterations()
{
return max_iterations;
}
/**
* Sets the maximum number of iterations.
*/
public void setMaxIterations(int max_iterations)
{
if (max_iterations < 0)
throw new IllegalArgumentException("max iterations must be >= 0");
this.max_iterations = max_iterations;
}
/**
* Returns the convergence threshold.
*/
public double getConvergenceThreshold()
{
return convergence_threshold;
}
/**
* Sets the convergence threshold.
* @param convergence_threshold
*/
public void setConvergenceThreshold(double convergence_threshold)
{
if (convergence_threshold <= 0)
throw new IllegalArgumentException("convergence threshold " +
"must be > 0");
this.convergence_threshold = convergence_threshold;
}
/**
* Returns a Collection
of clusters, where each cluster is
* represented as a Map
of Objects
to locations
* in d-dimensional space.
* @param object_locations a map of the Objects to cluster, to
* double
arrays that specify their locations in d-dimensional space.
* @param num_clusters the number of clusters to create
* @throws NotEnoughClustersException
*/
@SuppressWarnings("unchecked")
public Collection