# YogEx 🌳
> **যোগ** • (*jōg*)
> *noun*
> 1. connection, link, union
> 2. addition, sum
```text
λ
/|\
/ | \
/ | \
Y | O--------G
/ | \ /
/ | \ /
/ | \ /
যো------+-------গ
/ \ | / \
/ \ | / \
/ \ | / \
✦ ✦ | ✦ ✦
```
[](https://hex.pm/packages/yog_ex)
[](https://hexdocs.pm/yog_ex/)
Yog is a set of Graph and Network algorithms and data structures implemented in Elixir and packaged as a common API.
It started off as a wrapper around the Gleam [Yog](https://hex.pm/packages/yog) library, but now YogEx is now fully implemented in Elixir and a superset of the original Gleam version.
See the [Gleam vs Elixir Comparison](GLEAM_ELIXIR_COMPARISON.md) for feature comparison between the two implementations.
> [!WARNING]
> **API Stability**: Until the version reaches 0.98.0 ~~1.0.0~~, there may be ~~breaking changes. While I'll try my best to keep the API stable, there's no guarantee~~ some hiccups in performance, and documentation quality maybe less than optimal. Before version 0.99.0 is released in **12-12-2026**, the primary focus is on **performance**, **documentation**, and **bugfixes**. From v0.96.0 onwards, there will be no breaking changes until v2.0 (No plans for that).
## Features
YogEx provides comprehensive graph algorithms organized into modules:
### Core Capabilities
**[Pathfinding & Flow](https://hexdocs.pm/yog_ex/Yog.Pathfinding.html)** — Shortest paths (Dijkstra, A*, Bellman-Ford, Floyd-Warshall, Johnson's), maximum flow (Edmonds-Karp), min-cut (Stoer-Wagner), and implicit state-space search for on-demand graphs.
**[Network Analysis](https://hexdocs.pm/yog_ex/Yog.Centrality.html)** — Centrality measures (PageRank, betweenness, closeness, eigenvector, Katz), community detection (Louvain, Leiden, Infomap, Walktrap), and network health metrics.
**[Connectivity & Structure](https://hexdocs.pm/yog_ex/Yog.Connectivity.html)** — SCCs (Tarjan/Kosaraju), bridges, articulation points, K-core decomposition, and reachability analysis with exact and HyperLogLog-based estimation.
**[Graph Operations](https://hexdocs.pm/yog_ex/Yog.Operation.html)** — Union, intersection, difference, Cartesian product, power, isomorphism, and O(1) transpose.
### Developer Experience
**[Generators & Builders](https://hexdocs.pm/yog_ex/Yog.Generator.Classic.html)** — Classic patterns (complete, cycle, grid, Petersen), random models (SBM, R-MAT), and a comprehensive **Maze Generation** suite (Recursive Backtracker, Wilson's, Kruskal's, Eller's, etc.) with labeled and grid builders.
**[I/O & Visualization](https://hexdocs.pm/yog_ex/Yog.IO.GraphML.html)** — GraphML, GDF, Pajek, LEDA, TGF, JSON serialization plus ASCII, DOT, and Mermaid rendering.
**[Functional Graphs](https://hexdocs.pm/yog_ex/Yog.Functional.html)** *(Experimental)* — Pure inductive graph library (FGL) for elegant recursive algorithms.
**[Complete Algorithm Catalog](ALGORITHMS.md)** — See all 60+ algorithms, underlying data structures (Pairing Heap, Union-Find, HyperLogLog), and selection guidance with Big-O complexities.
## Installation
### Basic Installation
Add YogEx to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:yog_ex, "~> 0.95.0"}
]
end
```
Then run:
```bash
mix deps.get
```
### Optional Dependencies
YogEx includes several optional dependencies that enable additional I/O and interoperability features:
| Dependency | Module | Purpose |
|------------|--------|---------|
| [`:saxy`](https://hex.pm/packages/saxy) | `Yog.IO.GraphML` | Fast streaming XML parser for GraphML files (3-4x faster than default `:xmerl`) |
| [`:jason`](https://hex.pm/packages/jason) | `Yog.IO.JSON` | JSON serialization/deserialization for D3.js, Cytoscape, vis.js, NetworkX formats |
| [`:libgraph`](https://hex.pm/packages/libgraph) | `Yog.IO.Libgraph` | Bidirectional conversion with libgraph library |
To use these features, add the optional dependencies to your `mix.exs`:
```elixir
def deps do
[
{:yog_ex, "~> 0.95.0"},
{:saxy, "~> 1.5"}, # For fast GraphML/XML parsing
{:jason, "~> 1.4"}, # For JSON import/export
{:libgraph, "~> 0.16"} # For libgraph interoperability
]
end
```
#### XML/GraphML with Saxy
```elixir
# Reading large GraphML files is significantly faster with saxy
{:ok, graph} = Yog.IO.GraphML.read("large_network.graphml")
# Writing GraphML
Yog.IO.GraphML.write("output.graphml", graph)
```
#### JSON Serialization with Jason
```elixir
# Export to various JSON formats
json = Yog.IO.JSON.to_json(graph, Yog.IO.JSON.export_options_for(:d3_force))
# Import from JSON
{:ok, graph} = Yog.IO.JSON.from_json(json_string)
```
#### Libgraph Interoperability
```elixir
# Convert Yog graph to libgraph
libgraph = Yog.IO.Libgraph.to_libgraph(graph)
# Convert libgraph back to Yog
{:ok, yog_graph} = Yog.IO.Libgraph.from_libgraph(libgraph)
```
### Livebook
For livebook, add the following:
```elixir
Mix.install(
{:yog_ex, "~> 0.95.0"}
)
```
There is a [Kino App](https://github.com/code-shoily/kino_yog) that can be used to explore the library and create and render graphs.
### Usage
```elixir
alias Yog.Pathfinding
# Create a directed graph
graph =
Yog.directed()
|> Yog.add_node(1, "Start")
|> Yog.add_node(2, "Middle")
|> Yog.add_node(3, "End")
|> Yog.add_edge_ensure(from: 1, to: 2, with: 5)
|> Yog.add_edge_ensure(from: 2, to: 3, with: 3)
|> Yog.add_edge_ensure(from: 1, to: 3, with: 10)
# Find shortest path using Dijkstra (uses :ok/:error tuples and Path struct)
case Pathfinding.shortest_path(
in: graph,
from: 1,
to: 3
) do
{:ok, path} ->
IO.puts("Found path with weight: #{path.weight}")
:error ->
IO.puts("No path found")
end
# => Found path with weight: 8
```
## Examples
Detailed examples are located in the [examples/](https://github.com/code-shoily/yog_ex/tree/main/examples) directory
### Advent of Code Solutions
YogEx is used to solve [Advent of Code](https://adventofcode.com/) challenges.
See all Advent of Code solutions tagged with `graph` that demonstrate usage of YogEx algorithms in the [Advent of Code repository](https://github.com/code-shoily/advent_of_code).
## Development
### Running Tests
```sh
mix test
```
Run tests for a specific module:
```sh
mix test test/yog/pathfinding/dijkstra_test.exs
```
### Project Structure
- `lib/yog/` — Core graph library modules (pure Elixir)
- `test/` — Unit tests and doctests
- `examples/` — Real-world usage examples
## Property-Based Testing
This library uses property-based testing (PBT) via `StreamData` to ensure that algorithms hold up against a wide range of automatically generated graph structures.
See the [PROPERTIES.md](PROPERTIES.md) for a complete catalog of all algorithmic invariants (hypotheses) verified by the test suite.
## AI Assistance
Parts of this project were developed with the assistance of AI coding tools. All AI-generated code has been reviewed, tested, and validated by the maintainer.