# `Yog.Community.Leiden`
[🔗](https://github.com/code-shoily/yog_ex/blob/v0.97.0/lib/yog/community/leiden.ex#L1)

Leiden algorithm for community detection.

An improvement over the Louvain algorithm that guarantees well-connected
communities. Adds a refinement step to ensure communities are properly
connected internally.

## Algorithm

The Leiden method works in three phases that repeat until convergence:

1. **Local Optimization** (like Louvain): Nodes move to improve modularity
2. **Refinement**: Partition communities into well-connected sub-communities
3. **Aggregation**: Communities become super-nodes
4. **Repeat** until convergence

## Key Differences from Louvain

| Feature | Louvain | Leiden |
|---------|---------|--------|
| Speed | Faster | Slightly slower |
| Well-connected communities | Not guaranteed | ✓ Guaranteed |
| Hierarchical quality | Good | Better |
| Disconnected communities | Possible | Prevented |

## When to Use

- When **community quality** matters more than raw speed
- When you need **meaningful multi-level structure**
- When **disconnected communities** would be problematic
- For **hierarchical analysis** requiring well-connected communities at each level

## Complexity

- **Time**: Slightly slower than Louvain (refinement adds overhead)
- **Space**: O(V + E) same as Louvain

## Example

    # Basic usage
    communities = Yog.Community.Leiden.detect(graph)
    IO.inspect(communities.num_communities)

    # With custom options
    options = [
      min_modularity_gain: 0.0001,
      max_iterations: 100,
      refinement_iterations: 5,
      seed: 42
    ]
    communities = Yog.Community.Leiden.detect_with_options(graph, options)

    # Hierarchical detection
    dendrogram = Yog.Community.Leiden.detect_hierarchical(graph)

## References

- [Traag et al. 2019 - From Louvain to Leiden](https://doi.org/10.1038/s41598-019-41695-z)
- [Wikipedia: Leiden Algorithm](https://en.wikipedia.org/wiki/Leiden_algorithm)

# `leiden_options`

```elixir
@type leiden_options() :: %{
  min_modularity_gain: float(),
  max_iterations: integer(),
  refinement_iterations: integer(),
  resolution: float(),
  seed: integer()
}
```

Options for the Leiden algorithm

# `default_options`

```elixir
@spec default_options() :: leiden_options()
```

Returns default options for Leiden algorithm.

## Defaults

- `min_modularity_gain`: 0.000001 - Stop when gain < threshold
- `max_iterations`: 100 - Max iterations per phase
- `refinement_iterations`: 5 - Refinement step iterations
- `resolution`: 1.0 - Resolution parameter (gamma)
- `seed`: 42 - Random seed for tie-breaking

# `detect`

```elixir
@spec detect(Yog.graph()) :: Yog.Community.Result.t()
```

Detects communities using the Leiden algorithm with default options.

## Example

    communities = Yog.Community.Leiden.detect(graph)
    IO.inspect(communities.num_communities)

# `detect_hierarchical`

```elixir
@spec detect_hierarchical(Yog.graph()) :: Yog.Community.Dendrogram.t()
```

Full hierarchical Leiden detection.

Returns a dendrogram with all hierarchical levels.

## Example

    dendrogram = Yog.Community.Leiden.detect_hierarchical(graph)
    IO.inspect(length(dendrogram.levels))

# `detect_hierarchical_with_options`

```elixir
@spec detect_hierarchical_with_options(Yog.graph(), keyword() | map()) ::
  Yog.Community.Dendrogram.t()
```

Full hierarchical Leiden detection with custom options.

## Example

    options = [max_iterations: 50, seed: 123]
    dendrogram = Yog.Community.Leiden.detect_hierarchical_with_options(graph, options)

# `detect_with_options`

```elixir
@spec detect_with_options(Yog.graph(), keyword() | map()) :: Yog.Community.Result.t()
```

Detects communities using the Leiden algorithm with custom options.

## Options

- `:min_modularity_gain` - Stop when gain < threshold (default: 0.000001)
- `:max_iterations` - Max iterations per phase (default: 100)
- `:refinement_iterations` - Refinement step iterations (default: 5)
- `:resolution` - Resolution parameter (gamma) (default: 1.0)
- `:seed` - Random seed for tie-breaking (default: 42)

## Example

    options = [min_modularity_gain: 0.0001, refinement_iterations: 10]
    communities = Yog.Community.Leiden.detect_with_options(graph, options)

---

*Consult [api-reference.md](api-reference.md) for complete listing*
