package edu.hawaii.jmotif.text.cluster; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map.Entry; import java.util.Random; import java.util.TreeSet; import edu.hawaii.jmotif.text.CosineDistanceMatrix; public class FurthestFirstStrategy implements StartStrategy { @Override public LinkedHashMap<String, HashMap<String, Double>> getCentroids(Integer num, HashMap<String, HashMap<String, Double>> data) { Random random = new Random(); // need to make distance matrix for all the words in here // CosineDistanceMatrix matrix = new CosineDistanceMatrix(data); TreeSet<String> keys = new TreeSet<String>(); TreeSet<String> resultKeys = new TreeSet<String>(); for (String k : data.keySet()) { keys.add(k.substring(0)); } int rand = random.nextInt(keys.size()); String center1 = matrix.getRows()[rand]; resultKeys.add(center1); while (resultKeys.size() < num) { // now need to find the next furthest of other elements // double maxDist = 0D; String furthestElement = null; for (String k : keys) { if (resultKeys.contains(k)) { continue; } if (null == furthestElement) { furthestElement = k; maxDist = minCosineDistance(furthestElement, resultKeys, matrix); } else { if (maxDist > minCosineDistance(k, resultKeys, matrix)) { furthestElement = k; maxDist = minCosineDistance(furthestElement, resultKeys, matrix); } } } resultKeys.add(furthestElement); } // compose the result map LinkedHashMap<String, HashMap<String, Double>> res = new LinkedHashMap<String, HashMap<String, Double>>(); int counter = 0; for (String key : resultKeys) { HashMap<String, Double> value = new HashMap<String, Double>(); for (Entry<String, Double> e : data.get(key).entrySet()) { value.put(e.getKey().substring(0), new Double(e.getValue())); } res.put(String.valueOf(counter), value); counter++; } return res; } /** * Finds a minimal distance (largest cosine value) value between vector of interest and all other * vectors. * * @param furthestElement * @param resultKeys * @param matrix * @return */ private double minCosineDistance(String furthestElement, TreeSet<String> resultKeys, CosineDistanceMatrix matrix) { double minDist = 0.0D; for (String currKey : resultKeys) { if (matrix.distanceBetween(currKey, furthestElement) > minDist) { minDist = matrix.distanceBetween(currKey, furthestElement); } } return minDist; } }