/**
  * Returns the k instances of the given data set that are the closest to the instance that is
  * given as a parameter.
  *
  * @param dm the distance measure used to calculate the distance between instances
  * @param inst the instance for which we need to find the closest
  * @return the instances from the supplied data set that are closest to the supplied instance
  */
 @Override
 public Set<Instance> kNearest(int k, Instance inst, DistanceMeasure dm) {
   Map<Instance, Double> closest = new HashMap<Instance, Double>();
   double max = dm.getMaxValue();
   for (Instance tmp : this) {
     double d = dm.measure(inst, tmp);
     if (dm.compare(d, max) && !inst.equals(tmp)) {
       closest.put(tmp, d);
       if (closest.size() > k) max = removeFarthest(closest, dm);
     }
   }
   return closest.keySet();
 }
  /*
   * Removes the element from the vector that is farthest from the supplied
   * element.
   */
  private double removeFarthest(Map<Instance, Double> vector, DistanceMeasure dm) {
    Instance tmp = null; // ; = vector.get(0);
    double max = dm.getMinValue();
    // System.out.println("minvalue:"+max);
    for (Instance inst : vector.keySet()) {
      double d = vector.get(inst);

      if (dm.compare(max, d)) {
        max = d;
        tmp = inst;
      }
      // System.out.println("d="+d+"\t"+max);
    }
    vector.remove(tmp);
    return max;
  }
  /** XXX DOC */
  public double score(Dataset[] datas) {

    Instance[] centroids = new Instance[datas.length];
    for (int i = 0; i < datas.length; i++) {
      centroids[i] = DatasetTools.average(datas[i]);
    }
    double sum = 0;
    for (int i = 0; i < datas.length; i++) {
      for (int j = 0; j < datas[i].size(); j++) {
        double error = dm.measure(datas[i].instance(j), centroids[i]);
        sum += error;
      }
    }
    return sum;
  }