private double getCompleteLinkDistance(HierarchicalCluster c1, HierarchicalCluster c2) {
    // merge clusters with the "smallest" "maximum pairwise distance"
    // return maximum pairwise distance
    HashSet<Item> itemsC1 = c1.getItems();
    HashSet<Item> itemsC2 = c2.getItems();

    double maxDist = 0.0;
    for (Item item1 : itemsC1) {
      for (Item item2 : itemsC2) {
        double distance = item1.getDistance(item2);
        if (distance > maxDist) {
          maxDist = distance;
        }
      }
    }

    return maxDist;
  }
  private double getSingleLinkDistance(HierarchicalCluster c1, HierarchicalCluster c2) {
    // merge the two clusters with the smallest minimum pairwise distance
    // return minimum pairwise distance
    HashSet<Item> itemsC1 = c1.getItems();
    HashSet<Item> itemsC2 = c2.getItems();

    double minDist = Double.MAX_VALUE;
    for (Item item1 : itemsC1) {
      for (Item item2 : itemsC2) {
        double distance = item1.getDistance(item2);
        if (distance < minDist) {
          minDist = distance;
        }
      }
    }

    return minDist;
  }
  private double getAvgLinkDistance(HierarchicalCluster c1, HierarchicalCluster c2) {
    // merge the two clusters with the smallest average distance between any
    // two points in the clusters
    // return average distance between each two point in two clusters.
    HashSet<Item> itemsC1 = c1.getItems();
    HashSet<Item> itemsC2 = c2.getItems();

    double sumDist = 0.0;
    int n = 0;
    for (Item item1 : itemsC1) {
      for (Item item2 : itemsC2) {
        sumDist += item1.getDistance(item2);
        n++;
      }
    }

    double avgDist = sumDist / n;
    return avgDist;
  }