Immutable graph library with 56+ algorithms, transformers, selectors, and lazy views
Project description
AlgoGraph
Independent graph data structures and algorithms library with optional AlgoTree integration.
Overview
AlgoGraph provides immutable graph data structures with a clean, functional API. It works standalone and optionally integrates with AlgoTree for seamless interoperability between tree and graph representations.
Key Features
- Immutable by default: All operations return new graph objects
- Type-safe: Full type hints for IDE support
- Directed and undirected: Support for both edge types
- Weighted edges: Built-in support for edge weights
- Attributes: Both vertices and edges can carry arbitrary attributes
- Interoperability: Convert between trees (AlgoTree) and graphs (AlgoGraph)
- Interactive shell: VFS-like interface for graph exploration
- Comprehensive algorithms: 56+ graph algorithms across 8 categories
- Fluent builder API: Construct graphs with 82% less code
- Research-based: Algorithms from peer-reviewed literature
Core Classes
Vertex
Immutable graph vertex with attributes:
from AlgoGraph import Vertex
# Create vertex
v = Vertex('A', attrs={'value': 10, 'color': 'red'})
# Immutable updates
v2 = v.with_attrs(value=20)
v3 = v.without_attrs('color')
Edge
Immutable edge connecting two vertices:
from AlgoGraph import Edge
# Directed edge with weight
e1 = Edge('A', 'B', directed=True, weight=5.0)
# Undirected edge
e2 = Edge('A', 'C', directed=False)
# With attributes
e3 = Edge('B', 'C', weight=3.0, attrs={'label': 'highway'})
# Immutable updates
e4 = e1.with_weight(10.0)
e5 = e1.reversed() # B -> A
Graph
Immutable graph container:
from AlgoGraph import Graph, Vertex, Edge
# Build graph
v1, v2, v3 = Vertex('A'), Vertex('B'), Vertex('C')
e1 = Edge('A', 'B', weight=2.0)
e2 = Edge('B', 'C', weight=3.0)
g = Graph({v1, v2, v3}, {e1, e2})
# Query graph
g.has_vertex('A') # True
g.has_edge('A', 'B') # True
g.degree('A') # 1
g.neighbors('B') # {'C'}
# Immutable updates
g2 = g.add_vertex(Vertex('D'))
g3 = g.add_edge(Edge('C', 'D'))
g4 = g.remove_vertex('A')
Interoperability with AlgoTree (Optional)
Note: The interop functions require AlgoTree to be installed or available in PYTHONPATH.
Convert between trees and graphs seamlessly:
from AlgoTree import Node, Tree
from AlgoGraph import tree_to_graph, graph_to_tree
# Tree to Graph
tree = Tree(Node('root',
Node('child1', Node('grandchild')),
Node('child2')
))
graph = tree_to_graph(tree)
# Graph with 4 vertices, 3 edges (root->child1, root->child2, child1->grandchild)
# Graph to Tree (extracts spanning tree)
recovered_tree = graph_to_tree(graph, 'root')
Flat Dictionary Format
Both AlgoTree and AlgoGraph support a flat dictionary interchange format:
from AlgoGraph import graph_to_flat_dict, flat_dict_to_graph
# Graph to flat dict
flat = graph_to_flat_dict(graph)
# {
# 'root': {'.name': 'root', '.edges': [{'target': 'child1', ...}], ...},
# 'child1': {'.name': 'child1', '.edges': [...], ...},
# ...
# }
# Flat dict to graph
recovered = flat_dict_to_graph(flat)
This format is compatible with AlgoTree's flat exporter, enabling easy data exchange.
Graph Algorithms
AlgoGraph includes common graph algorithms (in algorithms/ module):
Traversal
from AlgoGraph.algorithms import dfs, bfs, topological_sort
# Depth-first search
visited = dfs(graph, start_vertex='A')
# Breadth-first search
levels = bfs(graph, start_vertex='A')
# Topological sort (DAG only)
ordered = topological_sort(graph)
Shortest Paths
from AlgoGraph.algorithms import dijkstra, bellman_ford, floyd_warshall
# Single-source shortest path (Dijkstra)
distances = dijkstra(graph, source='A')
# With negative weights (Bellman-Ford)
distances = bellman_ford(graph, source='A')
# All-pairs shortest paths
dist_matrix = floyd_warshall(graph)
Connectivity
from AlgoGraph.algorithms import (
connected_components,
strongly_connected_components,
is_connected,
is_bipartite
)
# Connected components (undirected)
components = connected_components(graph)
# Strongly connected components (directed)
scc = strongly_connected_components(graph)
# Check connectivity
if is_connected(graph):
print("Graph is connected")
# Check bipartiteness
is_bip, coloring = is_bipartite(graph)
Spanning Trees
from AlgoGraph.algorithms import minimum_spanning_tree, kruskal, prim
# Minimum spanning tree
mst = minimum_spanning_tree(graph) # Uses Kruskal by default
mst = kruskal(graph)
mst = prim(graph, start='A')
Centrality (NEW in v1.3.0)
from AlgoGraph.algorithms import (
pagerank, betweenness_centrality, closeness_centrality
)
# Find influencers with PageRank
pr = pagerank(social_network)
top_influencer = max(pr, key=pr.get)
# Find bridge people with betweenness
bc = betweenness_centrality(network)
top_broker = max(bc, key=bc.get)
# Find central nodes with closeness
cc = closeness_centrality(network)
Flow Networks (NEW in v1.3.0)
from AlgoGraph.algorithms import max_flow, min_cut
# Maximum flow from source to sink
flow_value = max_flow(network, 'Source', 'Sink')
# Find bottleneck (minimum cut)
cut_value, source_set, sink_set = min_cut(network, 'Source', 'Sink')
Matching (NEW in v1.3.0)
from AlgoGraph.algorithms import hopcroft_karp, is_perfect_matching
# Maximum bipartite matching (job assignment)
workers = {'Alice', 'Bob', 'Charlie'}
jobs = {'Backend', 'Frontend', 'DevOps'}
matching = hopcroft_karp(assignments, workers, jobs)
# Check if everyone can be matched
if is_perfect_matching(assignments, workers, jobs):
print("Everyone gets a job!")
Graph Coloring (NEW in v1.3.0)
from AlgoGraph.algorithms import welsh_powell, chromatic_number
# Exam scheduling (minimize time slots)
conflicts = build_conflict_graph(exams)
coloring = welsh_powell(conflicts)
num_slots = chromatic_number(conflicts)
print(f"Need {num_slots} exam time slots")
Design Philosophy
AlgoGraph follows the same design principles as AlgoTree:
- Immutability: All operations return new objects
- Composability: Operations chain naturally
- Functional style: Prefer pure functions
- Type safety: Full type hints
- Clean separation: Data structures vs algorithms
Use Cases
- Network analysis: Social networks, computer networks
- Route planning: Transportation, logistics
- Dependency graphs: Build systems, package managers
- State machines: Workflow, game logic
- Knowledge graphs: Semantic networks, ontologies
- Tree structures: When you need bidirectional navigation (use AlgoGraph), unidirectional parent-child (use AlgoTree)
When to Use AlgoGraph vs AlgoTree
| Use AlgoGraph when... | Use AlgoTree when... |
|---|---|
| You have cycles in your structure | Your structure is acyclic (tree) |
| You need bidirectional edges | Parent-child is sufficient |
| Working with networks/graphs | Working with hierarchies |
| Need to track edge weights/labels | Edges are just relationships |
| Multiple paths between nodes | Single path between any two nodes |
Examples
Social Network
from AlgoGraph import Graph, Vertex, Edge
# Create people
alice = Vertex('Alice', attrs={'age': 30})
bob = Vertex('Bob', attrs={'age': 25})
charlie = Vertex('Charlie', attrs={'age': 35})
# Create friendships (undirected)
friend1 = Edge('Alice', 'Bob', directed=False)
friend2 = Edge('Bob', 'Charlie', directed=False)
# Build network
network = Graph(
{alice, bob, charlie},
{friend1, friend2}
)
# Query network
bobs_friends = network.neighbors('Bob')
# {'Alice', 'Charlie'}
Road Network
# Cities
cities = {
Vertex('NYC', attrs={'population': 8000000}),
Vertex('Boston', attrs={'population': 700000}),
Vertex('DC', attrs={'population': 700000})
}
# Roads with distances
roads = {
Edge('NYC', 'Boston', weight=215.0, attrs={'highway': 'I-95'}),
Edge('NYC', 'DC', weight=225.0, attrs={'highway': 'I-95'}),
Edge('Boston', 'DC', weight=440.0)
}
road_network = Graph(cities, roads)
# Find shortest route
from AlgoGraph.algorithms import dijkstra
distances = dijkstra(road_network, 'NYC')
print(f"NYC to DC: {distances['DC']} miles")
Dependency Graph
# Build dependencies
packages = {Vertex(name) for name in ['app', 'lib1', 'lib2', 'utils']}
deps = {
Edge('app', 'lib1'),
Edge('app', 'lib2'),
Edge('lib1', 'utils'),
Edge('lib2', 'utils')
}
dep_graph = Graph(packages, deps)
# Get build order
from AlgoGraph.algorithms import topological_sort
build_order = topological_sort(dep_graph)
# ['utils', 'lib1', 'lib2', 'app'] or ['utils', 'lib2', 'lib1', 'app']
Installation
AlgoGraph is an independent library that can be used standalone:
# For development (when in released/ directory)
export PYTHONPATH=/path/to/released:$PYTHONPATH
# Use AlgoGraph standalone
from AlgoGraph import Graph, Vertex, Edge
from AlgoGraph.algorithms import dijkstra, bfs
# For interop features, also add AlgoTree to PYTHONPATH
export PYTHONPATH=/path/to/released:$PYTHONPATH
from AlgoTree import Node, Tree
from AlgoGraph import tree_to_graph, graph_to_tree
Package structure:
released/
├── AlgoTree/ # Tree data structures
└── AlgoGraph/ # Graph data structures (this library)
AlgoGraph works independently but provides optional interop with AlgoTree when both are available.
Interactive Shell
AlgoGraph includes an interactive shell for exploring graphs with a filesystem-like interface.
Quick Start
cd /home/spinoza/github/released
export PYTHONPATH=.
python -m AlgoGraph.shell.shell
Example Session
graph(5v):/$ ls
Alice/ [2 neighbors]
Bob/ [3 neighbors]
Charlie/ [2 neighbors]
graph(5v):/$ cd Alice
Now at: /Alice
graph(5v):/Alice$ ls
Attributes:
age = 30
city = NYC
neighbors/ [2 vertices]
graph(5v):/Alice$ cd neighbors
Now at: /Alice/neighbors
graph(5v):/Alice/neighbors$ ls
Bob/ <->
Charlie/ <->
graph(5v):/Alice/neighbors$ cd Bob
Now at: /Bob
graph(5v):/Bob$ path Alice Eve
Path found: Alice -> Bob -> Diana -> Eve
Length: 3 edges
Navigation Model
The shell treats graphs like a filesystem:
/- Graph root (lists all vertices)/vertex_id- At a specific vertex (shows attributes + neighbors/)/vertex_id/neighbors- Viewing neighbors you can navigate to
Available Commands
Navigation:
cd <vertex>- Navigate to a vertexcd neighbors- View neighbors of current vertexcd ..- Go up one levells- List contentspwd- Print current path
Information:
info- Show graph or vertex informationneighbors- Show neighbors of current vertexfind <vertex>- Find a vertex
Graph Queries:
path <v1> <v2>- Find path between verticesshortest <v1> <v2>- Find shortest pathcomponents- Show connected componentsbfs [start]- Breadth-first search
See shell/README.md for complete documentation.
Future Enhancements
Potential additions:
- More graph algorithms (matching, flow, coloring)
- Graph visualization export (GraphViz, etc.)
- Serialization formats (JSON, GraphML, etc.)
- Performance optimizations for large graphs
- Shell enhancements (graph modification, bookmarks, history)
Related Projects
- AlgoTree: Tree data structures and algorithms
- NetworkX: Comprehensive Python graph library (mutable)
- graph-tool: High-performance graph analysis
License
Same as AlgoTree (see main repository LICENSE file).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file algograph-2.0.0.tar.gz.
File metadata
- Download URL: algograph-2.0.0.tar.gz
- Upload date:
- Size: 65.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3fe7a3be0288be3ff9f3fc305c4e99b59b79fe507f2b37aabfd79e806d6e3509
|
|
| MD5 |
912147385bd911e2aa1493f475f7def4
|
|
| BLAKE2b-256 |
1251e827a5844e3b31ddf91485c7964365dc45fa5bcd1949731e110c1b18bcfc
|
File details
Details for the file algograph-2.0.0-py3-none-any.whl.
File metadata
- Download URL: algograph-2.0.0-py3-none-any.whl
- Upload date:
- Size: 59.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
568d2ed59319acccf5380a89d6251b5aff2d584abdbd6103008d6207c26475d0
|
|
| MD5 |
568e4b863b94c710feb3e8201054f982
|
|
| BLAKE2b-256 |
eea1b9cf9c522ca71f8bd530053be01e433939bae70beb6671d6fc4ad7df7569
|