diff --git a/Gvisual/src/gvisual/ForceDirectedLayout.java b/Gvisual/src/gvisual/ForceDirectedLayout.java index 06bb063..12068aa 100644 --- a/Gvisual/src/gvisual/ForceDirectedLayout.java +++ b/Gvisual/src/gvisual/ForceDirectedLayout.java @@ -514,21 +514,24 @@ public double computeStress() { int n = vertexList != null ? vertexList.size() : 0; if (n < 2) return 0; - // BFS shortest paths - Map> shortestPaths = - new HashMap>(); - for (String v : vertexList) { - shortestPaths.put(v, GraphUtils.bfsDistances(graph, v)); - } + // Ideal edge length: constant for this graph/layout + double k = Math.sqrt(width * height / n); + // Compute BFS one source at a time to reduce memory from O(V²) to O(V). + // The previous implementation stored all-pairs shortest paths in a + // Map> before iterating — for a graph + // with V vertices this allocates V HashMap instances with up to V + // entries each, plus V² Integer box objects. By computing BFS for + // vertex i, consuming distances to vertices j > i, and then + // discarding the map, we keep only one BFS result alive at a time. double stress = 0; double normalizer = 0; - // Ideal edge length: constant for this graph/layout, hoist out of loop - double k = Math.sqrt(width * height / n); + for (int i = 0; i < n; i++) { String vi = vertexList.get(i); double[] pi = positions.get(vi); - Map viPaths = shortestPaths.get(vi); + Map viPaths = GraphUtils.bfsDistances(graph, vi); + for (int j = i + 1; j < n; j++) { String vj = vertexList.get(j); Integer graphDist = viPaths.get(vj);