Basic Usage

To detect communities using the Prism algorithm from pymocd, follow the steps below.

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

ParameterTypeDefaultDescription
graphnetworkx.Graph or igraph.GraphUnweighted, undirected graph with integer node IDs.
debug_leveli80Verbosity of internal logging (0 = silent; 1–3 increasing detail).
swarm_sizeusize100Number of particles in the swarm.
num_gensusize100Number of generations to evolve.
archive_capusize100Maximum size of the external non-dominated archive.
mut_ratef640.2Per-node mutation rate used by the turbulence operator.
turbulence_fracf640.15Fraction of the swarm (lowest-ranked Pareto slice) that undergoes mutation each generation.
v_maxf640.3Upper bound on per-node velocity, i.e. the max per-generation relabel probability.
betaf640.7EM-momentum coefficient. Smooths per-node velocities across generations.
lpa_fracf640.7Fraction of the swarm initialized from a perturbed Label-Propagation seed; the remainder is uniform random.
lpa_itersusize3Number of LPA passes used to build the seed.
vnr_fracf640.15Reserved for Vulnerable-Node-Reassignment; currently unused. Left in the signature for experimentation.
objectiveslist[callable] or NoneNoneOptional 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.70.9 is over-damped, 0.5 is 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

MethodReturnsDescription
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()floatBest 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_gensintGetter for the configured number of generations.

Further reading

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 . history