Networks.jl
Networks.jl is a work-in-progress, alternative graph library in Julia. Designed to overcome the limitations of Graphs.jl when custom graphs, hyperedges, multi-edges, or arbitrary vertex types are needed.
Motivation
During the development of Tenet.jl, several requirements arose that are not covered by Graphs.jl:
- Support for hyperedges, open edges, and multi-edges
- Graph types based on the incidence matrix
- Automatic method delegation for wrapping graph types, based on DelegatorTraits.jl
- Allowing vertices of any type, not just integers
- Interfaces that are extensible and better decoupled from concrete implementations
The Edge entity
One of the biggest differences between the AbstractGraph
and Network
interfaces is that for Network
, an edge is its own entity; i.e. an edge can be just an identifier like a UUID instead of a relation between two other objects.
This choice makes a Network
a more abstract interface than AbstractGraph
, where the description of a graph is not forced to be based on adjacency matrices.
Basic Example
Let's start by creating an IncidentNetwork
, which implements a Network
using a incidence matrix representation. The first type parameterizes the vertex type, while the second one parameterizes the edge type.
julia> g = IncidentNetwork{Symbol, Int}()
IncidentNetwork{Symbol, Int64}(Dict{Symbol, Set{Int64}}(), Dict{Int64, Set{Symbol}}())
julia> vertex_type(g)
Symbol
julia> edge_type(g)
Int64
Unlike Graphs.jl, you must explicitly pass the vertex to add it to a network.
julia> addvertex!(g, :a)
IncidentNetwork{Symbol, Int64}(Dict{Symbol, Set{Int64}}(:a => Set()), Dict{Int64, Set{Symbol}}())
julia> addvertex!(g, :b)
IncidentNetwork{Symbol, Int64}(Dict{Symbol, Set{Int64}}(:a => Set(), :b => Set()), Dict{Int64, Set{Symbol}}())
julia> addvertex!(g, :c)
IncidentNetwork{Symbol, Int64}(Dict{Symbol, Set{Int64}}(:a => Set(), :b => Set(), :c => Set()), Dict{Int64, Set{Symbol}}())
julia> vertices(g)
KeySet for a Dict{Symbol, Set{Int64}} with 3 entries. Keys: :a :b :c
Edges are independent entities in an IncidentNetwork
, so you must add it and then relate it to the vertices.
julia> addedge!(g, 1)
IncidentNetwork{Symbol, Int64}(Dict{Symbol, Set{Int64}}(:a => Set(), :b => Set(), :c => Set()), Dict{Int64, Set{Symbol}}(1 => Set()))
julia> edges(g)
KeySet for a Dict{Int64, Set{Symbol}} with 1 entry. Keys: 1
julia> Networks.link!(g, :a, 1)
Set{Symbol} with 1 element: :a
julia> Networks.link!(g, :b, 1)
Set{Symbol} with 2 elements: :a :b
julia> Networks.link!(g, :c, 1)
Set{Symbol} with 3 elements: :a :b :c
In order to query the vertices connected by an edge, use edge_incidents
:
julia> edge_incidents(g, 1)
Set{Symbol} with 3 elements: :a :b :c
... and to query the edges connected to a vertex, use edge_incidents
:
julia> vertex_incidents(g, :a)
Set{Int64} with 1 element: 1