Skip to content

Modularity

Formula

\[ Q = \frac{1}{2m}\sum_{i,j}\left(A_{ij} - \frac{k_i k_j}{2m}\right)\,\mathbf{1}[c_i=c_j] \]

Parameters

  • \(A_{ij}\): edge weight between \(i\) and \(j\) (0/1 if unweighted)
  • \(k_i\): degree (or weighted degree/strength)
  • \(m\): number of edges (or total weight / 2)
  • \(c_i\): community label

What it means

Compares actual within-community edges to the expected count under a degree-preserving “null model”.

What it's used for

  • Evaluating the quality of a community assignment.
  • Objective optimized by Louvain/Leiden algorithms.

Key properties

  • Higher \(Q\) suggests stronger community structure
  • Often optimized by Louvain/Leiden heuristics

Common gotchas

  • Resolution limit: modularity can miss small communities in large graphs
  • There are variants with a resolution parameter \(\gamma\): [ A_{ij} - \gamma\frac{k_i k_j}{2m} ]

Example

Graph with edges (1,2) and (3,4), communities {1,2} and {3,4}: \(m=2\), all degrees 1, and \(Q=0.5\).

How to Compute (Pseudocode)

Input: graph G, community labels c[1..n]
Output: modularity score Q

compute node degrees k_i and total edge count/weight m
Q <- 0
for each pair (i, j) (or each edge/nonzero term in an optimized implementation):
  if c[i] == c[j]:
    Q <- Q + (A[i,j] - (k_i * k_j) / (2m))
Q <- Q / (2m)
return Q

Complexity

  • Time: Depends on the implementation and representation; dense formula evaluation is \(O(n^2)\), while sparse/community-aggregated implementations can be much faster in practice
  • Space: Depends on graph representation; dense adjacency is \(O(n^2)\), sparse storage is typically \(O(|V|+|E|)\)
  • Assumptions: Undirected modularity formula shown; weighted/directed/resolution-parameter variants modify the computation