*/
@Override
public void perform()
{
// these are the minimal distances of all data points to any cluster center
DoubleArrayList minDistances = new DoubleArrayList();
// first cluster center is randomly selected
// Random rnd = new Random(randomSeed);
// clusterCenterIndexes[0] = rnd.nextInt(dataPoints.size());
// first cluster center is equal to first frame
Iterator<IDoubleArray> it = data.iterator();
if (!it.hasNext())
{
throw (new RuntimeException("Trying to cluster an empty data set"));
}
IDoubleArray v_0 = it.next().copy();
clusters.add(v_0);
assignedClusters.add(0);
minDistances.add(0);
//clusterCenterIndexes[0]=0;
// consider second data point
/*
* if (!it.hasNext()) throw(new RuntimeException("Trying to cluster a
* data set with one data point")); IVector v_i = it.next();
* assignedClusters.add(0); minDistances.add(distanceMetric.measure(v_i,
* v_0));
*/
// first iteration: go over data, calculate distance to first center and assign first center
System.out.println("KCenter: iteration 1/" + numberOfClusters + ".");
IDoubleArray v_i = null;
double maxMinDistance = 0;
int count = 0;
while (it.hasNext())
{
IDoubleArray p_j = it.next().copy();
// calculate distance to cluster 0
double d = distanceMetric.distance(p_j, v_0);
minDistances.add(d);
// is this the largest distance so far? Then memorize as next center candidate
if (d >= maxMinDistance)
{
count++;
maxMinDistance = d;
v_i = p_j;
}
// assign every data point p_j to cluster 0
assignedClusters.add(0);
}
// for all other clusters, add the most distance point as center and the reassign
// for k clusters do k-2 further passes to the data
for (int i = 1; i < numberOfClusters; i++)
{
System.out.println("KCenter: iteration " + (i + 1) + "/" + numberOfClusters + ".");
// add most distance point as a new center
clusters.add(v_i);
int j = 0;
maxMinDistance = 0;
IDoubleArray v_next = null;
for (it = data.iterator(); it.hasNext(); j++) //for (int j = 0; j < dataPoints.size(); j++)
{
IDoubleArray p_j = it.next().copy();
// get minimal distance of p_j to cluster centers
double currentDistance = minDistances.get(j);
// calculate new distance of p_j to the possible new cluster center
double newDistance = distanceMetric.distance(p_j, v_i);
// if new cluster center closer, then reassign
if (newDistance < currentDistance)
{
assignedClusters.set(j, i);
minDistances.set(j, newDistance);
}
if (minDistances.get(j) >= maxMinDistance)
{
maxMinDistance = minDistances.get(j);
v_next = p_j;
}
}
v_i = v_next;