/** Calculate the shortest paths (not done per default) */
  private void lazyCalculatePaths() {
    // already we have calculated it once.
    if (paths != null) {
      return;
    }

    lazyCalculateMatrix();

    Map<VertexPair<V>, GraphPath<V, E>> sps = new HashMap<VertexPair<V>, GraphPath<V, E>>();
    int n = vertices.size();

    nShortestPaths = 0;
    for (int i = 0; i < n; i++) {
      V v_i = vertices.get(i);
      for (int j = 0; j < n; j++) {
        // don't count this.
        if (i == j) {
          continue;
        }

        V v_j = vertices.get(j);

        GraphPath<V, E> path = getShortestPathImpl(v_i, v_j);

        // we got a path
        if (path != null) {
          sps.put(new VertexPair<V>(v_i, v_j), path);
          nShortestPaths++;
        }
      }
    }

    this.paths = sps;
  }
  /**
   * @return the diameter (longest of all the shortest paths) computed for the graph. If the graph
   *     is vertexless, return 0.0.
   */
  public double getDiameter() {
    lazyCalculateMatrix();

    if (Double.isNaN(diameter)) {
      diameter = 0.0;
      int n = vertices.size();
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
          if (!Double.isInfinite(d[i][j]) && d[i][j] > diameter) {
            diameter = d[i][j];
          }
        }
      }
    }
    return diameter;
  }
  /**
   * Get the length of a shortest path.
   *
   * @param a first vertex
   * @param b second vertex
   * @return shortest distance between a and b
   */
  public double shortestDistance(V a, V b) {
    lazyCalculateMatrix();

    return d[vertices.indexOf(a)][vertices.indexOf(b)];
  }