Metadata-Version: 2.4
Name: pymocd
Version: 5.1.0
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Rust
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
License-File: LICENSE
Summary: pymocd is a lib for multi-objective evolutionary community detection in complex networks. The evolutionary core is written in Rust and exposed through PyO3, giving it a large speed advantage over pure-Python implementations while staying a drop-in for the NetworkX/igraph ecosystem, making it well-suited to large-scale graphs.
Keywords: community-detection,graph,networks,networkx,multi-objective-optimization,nsga-ii,particle-swarm,modularity,rust
Author-email: "Guilherme O. Santos" <git@guiolvr.com>
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Project-URL: Documentation, https://oliveira-sh.github.io/pymocd/
Project-URL: Issues, https://github.com/oliveira-sh/pymocd/issues
Project-URL: Repository, https://github.com/oliveira-sh/pymocd

<div align="center">
  <img src="res/logo.svg" alt="pymocd logo" width="75%">  
</div>

<div align="center">

[![PyPI Publish](https://github.com/oliveira-sh/pymocd/actions/workflows/release.yml/badge.svg)](https://github.com/oliveira-sh/pymocd/actions/workflows/release.yml)![Rust Compilation](https://img.shields.io/github/actions/workflow/status/oliveira-sh/pymocd/rust.yml)
![PyPI - Version](https://img.shields.io/pypi/v/pymocd)
![PyPI - License](https://img.shields.io/pypi/l/pymocd)

</div>

**pymocd** is a Python library, powered by a Rust backend, for multi-objective
evolutionary community detection in complex networks. The evolutionary core is
written in Rust and exposed through [PyO3](https://pyo3.rs), giving it a large
speed advantage over pure-Python implementations while staying a drop-in for
the **NetworkX** / **igraph** ecosystem, making it well-suited to large-scale
graphs.

**Read the [Documentation](https://pymocd.guiolvr.com/) for detailed
guidance and usage instructions.**

---

### Getting started

```bash
pip install pymocd
```

```python
import networkx as nx
import pymocd

G = nx.karate_club_graph()          # any NetworkX / igraph graph, integer node ids
communities = pymocd.smocc(G)       # -> dict[node, community]
```

> [!IMPORTANT]
> Graphs must be in **NetworkX** or **igraph** compatible format with integer
> node ids. Isolated nodes are assigned community `-1`.

Every detector returns a single crisp partition as `dict[node, community]`.

### Algorithms

`pymocd` ships eight detectors. **SMOCC** and **HP-MOCD** are the library's
own contributions; the remaining six are faithful re-implementations of
published baselines (the original authors released no code).

| API | Algorithm | Objectives & engine | Solution selection | Year |
|---|---|---|---|---|
| `smocc` | **SMOCC** (Santos, in prep.) | heterogeneous intra/inter + KKM/ratio-cut objectives, sparse macro–micro co-evolutionary NSGA-II (near-linear, no dense kernel) | label-free normalised scalarisation | 2026 |
| `hpmocd` | **HP-MOCD** ([Santos et al.](https://doi.org/10.1007/s13278-025-01519-7)) | decomposed modularity, parallel NSGA-II | max modularity *Q* | 2025 |
| `mmcomo` | **MMCoMO** ([Zhang et al.](https://ieeexplore.ieee.org/document/10188453)) | kernel *k*-means + ratio cut, macro/micro co-evolutionary NSGA-II | max *Q* (front via `mmcomo_fronts`) | 2023 |
| `ccm` | **CCM** ([Shaik et al.](https://doi.org/10.1007/s42979-020-00382-x)) | score + fitness + modularity, NSGA-III | max *Q* (front via `ccm_fronts`) | 2021 |
| `krm` | **KRM** ([Shaik et al.](https://doi.org/10.1007/s42979-020-00382-x)) | kernel *k*-means + ratio cut + modularity, NSGA-III | max *Q* (front via `krm_fronts`) | 2021 |
| `mocd_q` | **Shi-MOCD** ([Shi et al.](https://doi.org/10.1016/j.asoc.2011.10.005)) | decomposed modularity, PESA-II | max *Q* | 2012 |
| `mocd_d` | **Shi-MOCD** ([Shi et al.](https://doi.org/10.1016/j.asoc.2011.10.005)) | decomposed modularity, PESA-II | max-min distance to random nets | 2012 |
| `moga_net` | **MOGA-Net** ([Pizzuti](https://doi.org/10.1109/ICTAI.2009.58)) | community score + fitness, NSGA-II | max *Q* (front via `moga_net_fronts`) | 2009 |

### Usage

```python
import pymocd

# Recommended detectors (defaults work out of the box)
part = pymocd.smocc(G)            # SMOCC
part = pymocd.hpmocd(G)           # HP-MOCD

# Baselines (sensible defaults; pop_size / num_gens / rates are tunable kwargs)
part = pymocd.mocd_q(G)           # Shi-MOCD, max-modularity selection
part = pymocd.mocd_d(G)           # Shi-MOCD, max-min-distance selection
part = pymocd.moga_net(G)         # MOGA-Net (Pizzuti)
part = pymocd.ccm(G)              # NSGA-III CCM (Shaik et al.)
part = pymocd.krm(G)              # NSGA-III KRM (Shaik et al.)
part = pymocd.mmcomo(G)           # MMCoMO (Zhang et al.), macro/micro co-evolution

# All return dict[node, community]; isolated nodes -> -1
```

The Pareto frontier of some algorithms is exposed for inspection:

```python
fronts = pymocd.smocc_fronts(G)      # list[dict[node, community]]
fronts = pymocd.mmcomo_fronts(G)     # list[dict[node, community]]
```

Helpers:

```python
pymocd.max_cores(8)                  # set Rayon thread pool (first call wins)

# Fast native ground-truth agreement metrics between two {node: community}
# dicts, computed over their shared nodes
nmi, ami, ari, f1 = pymocd.gt_metrics(partition, gt)
pymocd.nmi(partition, gt)            # or each metric individually
pymocd.ami(partition, gt)
pymocd.ari(partition, gt)
pymocd.f1(partition, gt)             # pairwise F1
```

### Contributing

Contributions are welcome, open an issue or a pull request for features, bug
fixes, or improvements. This project is licensed under **GPL-3.0 or later**.

---

### Citation

If you use any algorithm in your research, please cite:

```bibtex
@article{Santos2025,
  author    = {Santos, Guilherme O. and Vieira, Lucas S. and Rossetti, Giulio and Ferreira, Carlos H. G. and Moreira, Gladston J. P.},
  title     = {A high-performance evolutionary multiobjective community detection algorithm},
  journal   = {Social Network Analysis and Mining},
  year      = {2025},
  volume    = {15},
  number    = {1},
  pages     = {110},
  doi       = {10.1007/s13278-025-01519-7},
  url       = {https://doi.org/10.1007/s13278-025-01519-7},
  issn      = {1869-5469},
  date      = {2025-11-18}
}
```

