Skip to content
This repository was archived by the owner on Jun 18, 2026. It is now read-only.

Commit 19d034a

Browse files
refactor: remove dead code and cache flow path decomposition in NetworkFlowAnalyzer
- Remove unused parentArcKey parameter from bfsAugmentingPath (populated but never consumed) - Remove identity formatKey method (was just returning its input) - Cache decomposeFlowPaths() result to avoid redundant O(V·E) recomputation when called from getSummary(), getResult(), and getAugmentingPathCount() - Invalidate cache on recomputation (new compute() call)
1 parent 5f5e2be commit 19d034a

1 file changed

Lines changed: 13 additions & 20 deletions

File tree

Gvisual/src/gvisual/NetworkFlowAnalyzer.java

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ public class NetworkFlowAnalyzer {
5555
private String sink;
5656
private double maxFlowValue;
5757
private boolean computed;
58+
// Cached flow path decomposition (expensive to compute, requested by multiple methods)
59+
private List<FlowPath> cachedFlowPaths;
5860

5961
/**
6062
* Creates a new NetworkFlowAnalyzer for the given graph.
@@ -96,12 +98,12 @@ public double compute(String source, String sink) {
9698
buildResidualGraph();
9799

98100
maxFlowValue = 0;
101+
cachedFlowPaths = null;
99102

100103
// Edmonds–Karp: BFS for shortest augmenting path
101104
while (true) {
102105
Map<String, String> parent = new LinkedHashMap<String, String>();
103-
Map<String, String> parentArcKey = new LinkedHashMap<String, String>();
104-
double pathFlow = bfsAugmentingPath(parent, parentArcKey);
106+
double pathFlow = bfsAugmentingPath(parent);
105107

106108
if (pathFlow <= 0) break;
107109

@@ -181,9 +183,9 @@ public Map<String, Double> getEdgeFlows() {
181183

182184
// Net flow direction
183185
if (fwdFlow > 1e-9) {
184-
result.put(formatKey(fwd), fwdFlow);
186+
result.put(fwd, fwdFlow);
185187
} else if (revFlow > 1e-9) {
186-
result.put(formatKey(rev), revFlow);
188+
result.put(rev, revFlow);
187189
}
188190
}
189191
return Collections.unmodifiableMap(result);
@@ -338,12 +340,15 @@ public int getAugmentingPathCount() {
338340

339341
/**
340342
* Decomposes the max flow into individual source-to-sink paths,
341-
* each with its flow value.
343+
* each with its flow value. Results are cached to avoid redundant
344+
* O(V·E) recomputation across {@link #getSummary()},
345+
* {@link #getResult()}, and {@link #getAugmentingPathCount()}.
342346
*
343347
* @return list of flow paths, each described by vertices and flow value
344348
*/
345349
public List<FlowPath> decomposeFlowPaths() {
346350
ensureComputed();
351+
if (cachedFlowPaths != null) return cachedFlowPaths;
347352

348353
// Work on a copy of flows
349354
Map<String, Double> flowCopy = new HashMap<String, Double>(flow);
@@ -402,7 +407,8 @@ public List<FlowPath> decomposeFlowPaths() {
402407
Collections.unmodifiableList(pathVertices), pathFlow));
403408
}
404409

405-
return Collections.unmodifiableList(paths);
410+
cachedFlowPaths = Collections.unmodifiableList(paths);
411+
return cachedFlowPaths;
406412
}
407413

408414
// ── Result object ──────────────────────────────────────────────
@@ -597,8 +603,7 @@ private void buildResidualGraph() {
597603
}
598604
}
599605

600-
private double bfsAugmentingPath(Map<String, String> parent,
601-
Map<String, String> parentArcKey) {
606+
private double bfsAugmentingPath(Map<String, String> parent) {
602607
Queue<String> queue = new ArrayDeque<String>();
603608
queue.add(source);
604609
parent.put(source, null);
@@ -613,7 +618,6 @@ private double bfsAugmentingPath(Map<String, String> parent,
613618
if (!parent.containsKey(v) &&
614619
residualCapacity.getOrDefault(key, 0.0) > 1e-9) {
615620
parent.put(v, u);
616-
parentArcKey.put(v, key);
617621
if (v.equals(sink)) {
618622
// Find bottleneck
619623
double pathFlow = Double.MAX_VALUE;
@@ -643,17 +647,6 @@ private String directedKey(String from, String to) {
643647
return from + "->" + to;
644648
}
645649

646-
/**
647-
* Formats a directed key as a human-readable string for display purposes.
648-
* Since keys are already in "from->to" format, this is an identity operation.
649-
*
650-
* @param key the directed key string
651-
* @return the key itself
652-
*/
653-
private String formatKey(String key) {
654-
return key;
655-
}
656-
657650
private void validateVertex(String vertex, String name) {
658651
if (vertex == null) {
659652
throw new IllegalArgumentException(name + " must not be null");

0 commit comments

Comments
 (0)