@Override public void cluster(ArrayList<? extends DataPoint> dataPoints) { { // Initalize the clusters. for (DataPoint dp : dataPoints) { dp.setClusterId(-1); } } { // Main process ArrayList<DataPoint> plane = new ArrayList(dataPoints.size()); ArrayList<DataPoint> neighbors = new ArrayList(16); ArrayList<Integer> nearbyClusters = new ArrayList(4); float e2 = epsilon * epsilon; double d; int lastClusterUsed = 0; int id; main: for (DataPoint dp : dataPoints) { // Check for neighbors. neighbors.clear(); for (DataPoint other : plane) { d = distance(dp, other); if (d <= e2) { neighbors.add(other); } } if (neighbors.isEmpty()) { // New Cluster dp.setClusterId(lastClusterUsed++); } else { // Add to cluster. nearbyClusters.clear(); for (DataPoint n : neighbors) { nearbyClusters.add(n.getClusterId()); } if (nearbyClusters.size() == 1) { // Only near 1 cluster. dp.setClusterId(nearbyClusters.get(0)); } else { // Combine multiple clusters. id = nearbyClusters.remove(0); dp.setClusterId(id); for (DataPoint other : plane) { if (nearbyClusters.contains(other.getClusterId())) { other.setClusterId(id); } } } } plane.add(dp); } } { // Condense the cluster ids. ArrayList<Integer> clusterIdsUsed = new ArrayList(16); int id; for (DataPoint dp : dataPoints) { id = dp.getClusterId(); if (!clusterIdsUsed.contains(id)) { clusterIdsUsed.add(id); } } for (DataPoint dp : dataPoints) { dp.setClusterId(clusterIdsUsed.indexOf(dp.getClusterId())); } } }