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

Commit b7be624

Browse files
Merge pull request #107 from sauravbhattacharya001/perf/sir-infected-tracking
perf: track infected nodes in SIR simulation instead of scanning all vertices
2 parents 1f09107 + 6797ec6 commit b7be624

1 file changed

Lines changed: 16 additions & 14 deletions

File tree

Gvisual/src/gvisual/InfluenceSpreadSimulator.java

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -315,20 +315,27 @@ public SimulationResult simulateSIR(Collection<String> seeds,
315315
List<RoundSnapshot> snapshots = new ArrayList<>();
316316
List<InfectionEvent> timeline = new ArrayList<>();
317317

318+
// Track currently infected nodes explicitly to avoid iterating
319+
// all V vertices each round just to find the infected subset.
320+
// For large graphs with low infection rates, this reduces per-round
321+
// cost from O(V) to O(|infected| * avg_degree).
322+
Set<String> currentlyInfected = new LinkedHashSet<>();
323+
for (String seed : seeds) {
324+
if (graph.containsVertex(seed)) currentlyInfected.add(seed);
325+
}
326+
318327
int round = 0;
319328
snapshots.add(createSnapshot(round, state));
320329

321-
boolean hasInfected = true;
322-
while (hasInfected) {
330+
while (!currentlyInfected.isEmpty()) {
323331
round++;
324332
if (maxRounds > 0 && round > maxRounds) break;
325333

326334
Set<String> toRecover = new LinkedHashSet<>();
327335
Set<String> toInfect = new LinkedHashSet<>();
328336
Map<String, String> infectedBy = new LinkedHashMap<>();
329337

330-
for (String node : graph.getVertices()) {
331-
if (state.get(node) != NodeState.INFECTED) continue;
338+
for (String node : currentlyInfected) {
332339
for (String neighbor : getNeighbors(node)) {
333340
if (state.get(neighbor) == NodeState.SUSCEPTIBLE &&
334341
!toInfect.contains(neighbor)) {
@@ -341,31 +348,26 @@ public SimulationResult simulateSIR(Collection<String> seeds,
341348
}
342349
}
343350

344-
for (String node : graph.getVertices()) {
345-
if (state.get(node) == NodeState.INFECTED) {
346-
if (random.nextDouble() < recoveryRate) {
347-
toRecover.add(node);
348-
}
351+
for (String node : currentlyInfected) {
352+
if (random.nextDouble() < recoveryRate) {
353+
toRecover.add(node);
349354
}
350355
}
351356

352357
for (String node : toInfect) {
353358
state.put(node, NodeState.INFECTED);
359+
currentlyInfected.add(node);
354360
String source = infectedBy.get(node);
355361
if (source != null) {
356362
timeline.add(new InfectionEvent(source, node, round));
357363
}
358364
}
359365
for (String node : toRecover) {
360366
state.put(node, NodeState.RECOVERED);
367+
currentlyInfected.remove(node);
361368
}
362369

363370
snapshots.add(createSnapshot(round, state));
364-
365-
hasInfected = false;
366-
for (NodeState s : state.values()) {
367-
if (s == NodeState.INFECTED) { hasInfected = true; break; }
368-
}
369371
}
370372

371373
return new SimulationResult(Model.SIR, seeds,

0 commit comments

Comments
 (0)