On this page
menu_book
Basic Usage
Run Prism on a graph and inspect the detected communities
Note: Here it is assumed that you have read the quickstarting section and have already installed the library on your operating system, whatever it may be.
Basic Usage
To detect communities using the Prism algorithm from pymocd, follow the steps below.
Note: The input graph must be unweighted and undirected. It can be an object from
networkx.Graph or igraph.Graph. Node IDs must be non-negative integers.First, prepare your graph:
import networkx as nx # You can use igraph too
from pymocd import Prism # Our library
G = nx.karate_club_graph()
Then, instantiate and run the algorithm:
alg = Prism(
graph=G,
debug_level=1,
swarm_size=100,
num_gens=100,
mut_rate=0.2,
turbulence_frac=0.15,
)
solution = alg.run()
print(solution)
solution is a dict[int, int] mapping each node to its community ID — the same shape as HP-MOCD’s output.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| graph | networkx.Graph or igraph.Graph | — | Unweighted, undirected graph with integer node IDs. |
| debug_level | i8 | 0 | Verbosity of internal logging (0 = silent; 1–3 increasing detail). |
| swarm_size | usize | 100 | Number of particles in the swarm. |
| num_gens | usize | 100 | Number of generations to evolve. |
| archive_cap | usize | 100 | Maximum size of the external non-dominated archive. |
| mut_rate | f64 | 0.2 | Per-node mutation rate used by the turbulence operator. |
| turbulence_frac | f64 | 0.15 | Fraction of the swarm (lowest-ranked Pareto slice) that undergoes mutation each generation. |
| v_max | f64 | 0.3 | Upper bound on per-node velocity, i.e. the max per-generation relabel probability. |
| beta | f64 | 0.7 | EM-momentum coefficient. Smooths per-node velocities across generations. |
| lpa_frac | f64 | 0.7 | Fraction of the swarm initialized from a perturbed Label-Propagation seed; the remainder is uniform random. |
| lpa_iters | usize | 3 | Number of LPA passes used to build the seed. |
| vnr_frac | f64 | 0.15 | Reserved for Vulnerable-Node-Reassignment; currently unused. Left in the signature for experimentation. |
| objectives | list[callable] or None | None | Optional list of Python objective functions; when empty, PRISM uses the built-in multi-resolution -Q_γ objectives. |
Tuned defaults — why these numbers
The defaults were tuned for LFR graphs across μ ∈ [0.1, 0.6] and n ∈ [10³, 10⁵]:
swarm_size = num_gens = 100— empirical sweet spot; AMI plateaus around 80 generations.archive_cap = 100— matches swarm size; larger archives waste memetic budget on near-duplicates.v_max = 0.3— larger values thrash; smaller values stagnate.beta = 0.7—0.9is over-damped,0.5is noisy.lpa_frac = 0.7,mut_rate = 0.1-0.2,turbulence_frac = 0.1-0.15— enough topology prior to seed cleanly, enough exploration to escape it.
Most users do not need to touch anything beyond swarm_size and num_gens.
Methods
| Method | Returns | Description |
|---|---|---|
run(polish_iters=20) | dict[int, int] | Evolve, then apply a final Louvain polish (polish_iters sweeps, 0 to disable) to the best Q-score Pareto member. Returns its partition. |
generate_pareto_front() | list[(dict, list[float])] | Full Pareto front. Each entry is (partition, objective_values) — for the default objective objective_values = [-Q_0.5, -Q_1.0, -Q_2.0]. |
best_q() | float | Best Q-score observed in the archive (higher is better). |
set_objectives(list) | — | Replace the default Rust objectives with Python callables. Pass [] to revert. |
set_on_generation(cb) | — | Register a per-generation callback cb(gen, num_gens, archive_size). |
num_gens | int | Getter for the configured number of generations. |
Further reading
- Pareto Front — walk the full Pareto front and pick a preferred trade-off.
- Custom Objectives — replace
-Q_γwith your own metric.
Rust Parameter Types
usize— unsigned integer matching the platform pointer width (64-bit on most systems).i8— signed 8-bit integer.f64— double-precision floating-point.
Last updated 18 Apr 2026, 22:19 -0300 .