Skip to content

fix(community): async label_propagation with oscillation detection#3

Merged
Ataxia123 merged 2 commits into
mainfrom
fix/label-propagation-async
Apr 11, 2026
Merged

fix(community): async label_propagation with oscillation detection#3
Ataxia123 merged 2 commits into
mainfrom
fix/label-propagation-async

Conversation

@Ataxia123
Copy link
Copy Markdown

The current label_propagation implementation uses synchronous batch updates: it snapshots the community map at the start of each pass, computes new labels for all nodes from that snapshot, then replaces the map. This form is vulnerable to flip-flop oscillation on graphs with high-degree hub nodes. Tied candidate scores cause groups of nodes to swap labels symmetrically every iteration, which repeats forever and blocks the caller indefinitely.

Observed on a real knowledge graph with 48 entities and a central hub connected to 14+ peers: 19 nodes kept flipping between two states forever. The main while True: loop never terminated.

Replace with the Raghavan et al. (2007) asynchronous form described in "Near linear time algorithm to detect community structures in large-scale networks":

  1. Visit nodes in a fresh RANDOM order each pass (deterministic seed for reproducibility).
  2. For each node, read the CURRENT community map and update it IN PLACE before moving to the next node. Neighbors immediately see the new label, which breaks the ping-pong pattern.
  3. Break ties deterministically by preferring the higher community id, and only move when a candidate strictly improves on the current support — so well-connected nodes stay put under ties.
  4. Terminate on natural convergence (no changes in a full pass). As a safeguard, also break if the exact community_map repeats within a short recent window — async LPA converges in O(log n) on real-world graphs but a cycle detector covers any edge case.

Verified on synthetic graphs (disconnected, stars, complete graphs, rings, bridged stars, barbells) and a real-world pathological case (hub + heavy/light satellites) — all converge in milliseconds and produce sensible partitions.

Adds tests/utils/maintenance/test_community_operations.py with 10 unit tests covering the regression case and common graph shapes.

Summary

Brief description of the changes in this PR.

Type of Change

  • Bug fix
  • New feature
  • Performance improvement
  • Documentation/Tests

Objective

For new features and performance improvements: Clearly describe the objective and rationale for this change.

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • All existing tests pass

Breaking Changes

  • This PR contains breaking changes

If this is a breaking change, describe:

  • What functionality is affected
  • Migration path for existing users

Checklist

  • Code follows project style guidelines (make lint passes)
  • Self-review completed
  • Documentation updated where necessary
  • No secrets or sensitive information committed

Related Issues

Closes #[issue number]

Ataxia123 and others added 2 commits April 8, 2026 09:49
The current label_propagation implementation uses synchronous batch
updates: it snapshots the community map at the start of each pass,
computes new labels for all nodes from that snapshot, then replaces
the map. This form is vulnerable to flip-flop oscillation on graphs
with high-degree hub nodes. Tied candidate scores cause groups of
nodes to swap labels symmetrically every iteration, which repeats
forever and blocks the caller indefinitely.

Observed on a real knowledge graph with 48 entities and a central
hub connected to 14+ peers: 19 nodes kept flipping between two
states forever. The main `while True:` loop never terminated.

Replace with the Raghavan et al. (2007) asynchronous form described
in "Near linear time algorithm to detect community structures in
large-scale networks":

1. Visit nodes in a fresh RANDOM order each pass (deterministic
   seed for reproducibility).
2. For each node, read the CURRENT community map and update it IN
   PLACE before moving to the next node. Neighbors immediately see
   the new label, which breaks the ping-pong pattern.
3. Break ties deterministically by preferring the higher community
   id, and only move when a candidate strictly improves on the
   current support — so well-connected nodes stay put under ties.
4. Terminate on natural convergence (no changes in a full pass).
   As a safeguard, also break if the exact community_map repeats
   within a short recent window — async LPA converges in O(log n)
   on real-world graphs but a cycle detector covers any edge case.

Verified on synthetic graphs (disconnected, stars, complete graphs,
rings, bridged stars, barbells) and a real-world pathological case
(hub + heavy/light satellites) — all converge in milliseconds and
produce sensible partitions.

Adds tests/utils/maintenance/test_community_operations.py with 10
unit tests covering the regression case and common graph shapes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Ataxia123 Ataxia123 merged commit 38313f1 into main Apr 11, 2026
2 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant