private void findUnitClusters(int[] clusterassoc, double[][] lkvalues, int[][] neighbors) { Vector<ObjectComparablePair> topunitterms = new Vector<ObjectComparablePair>(); // sort units according to their highest value -> order to find clusters for (int i = 0; i < lkvalues.length; i++) { double max = Stat.max(lkvalues[i]); if (max <= 0.) continue; topunitterms.addElement(new ObjectComparablePair(new Integer(i), new Double(max))); } Collections.sort(topunitterms); Collections.reverse(topunitterms); Iterator<ObjectComparablePair> ocpit = topunitterms.iterator(); while (ocpit.hasNext()) { int curunit = ((Integer) (ocpit.next().getObject())).intValue(); floodFillSimilarClusters(curunit, clusterassoc, lkvalues, neighbors, curunit); } // join all empty units int firstemptyindex = -1; for (int i = 0; i < lkvalues.length; i++) { if (Stat.max(lkvalues[i]) <= 0.) { if (firstemptyindex == -1) firstemptyindex = i; else clusterassoc[i] = firstemptyindex; } } }
private void floodFillSimilarClusters( int unitpos, int[] clusterassoc, double[][] lkvalues, int[][] neighbors, int startunitpos) { // check if already associated to other cluster (end of recursion) if (clusterassoc[unitpos] != unitpos && clusterassoc[unitpos] != startunitpos) return; Vector<Integer> joinedunits = new Vector<Integer>(); // check neighbors (starts with index 1) for join candidates for (int i = 1; i < neighbors[unitpos].length; i++) { if (neighbors[unitpos][i] != -1 && // on the som clusterassoc[neighbors[unitpos][i]] != startunitpos && // not already in cluster clusterassoc[neighbors[unitpos][i]] == neighbors[unitpos][i]) { // not part of any other cluster // join two units iff summed up vector differs below threshold from both original vectors double[] cosNormA = Vec.cosineNormalize(Vec.cloneVector(lkvalues[unitpos])); double[] cosNormB = Vec.cosineNormalize(Vec.cloneVector(lkvalues[neighbors[unitpos][i]])); double[] sumAB = Vec.add(lkvalues[unitpos], lkvalues[neighbors[unitpos][i]]); double[] cosNormAB = Vec.cosineNormalize(Vec.cloneVector(sumAB)); if (Vec.euclDist(cosNormA, cosNormAB) < 0.6 && Vec.euclDist(cosNormB, cosNormAB) < 0.6) { // similar units -> join clusterassoc[neighbors[unitpos][i]] = startunitpos; // write new vector to all associated for (int k = 0; k < clusterassoc.length; k++) { if (clusterassoc[k] == startunitpos) { lkvalues[k] = sumAB; } } // Vec.copyTo(lkvalues[unitpos], sumAB); // Vec.copyTo(lkvalues[neighbors[unitpos][i]], sumAB); // add to list for recursion joinedunits.addElement(new Integer(neighbors[unitpos][i])); } } } // recursion over joined units Iterator<Integer> iit = joinedunits.iterator(); while (iit.hasNext()) { floodFillSimilarClusters( iit.next().intValue(), clusterassoc, lkvalues, neighbors, startunitpos); } }