Skip to content

JoeyT1994/NamedGraphs.jl

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NamedGraphs

Stable Dev Build Status Coverage Code Style: Blue

Installation

You can install the package using Julia's package manager:

julia> ] add NamedGraphs

Introduction

This packages introduces graph types with named edges, which are built on top of the Graph/SimpleGraph type in the Graphs.jl package that only have contiguous integer edges (i.e. linear indexing).

There is a supertype AbstractNamedGraph that defines an interface and fallback implementations of standard Graphs.jl operations, and two implementations: NamedGraph and NamedDiGraph.

NamedGraph

NamedGraph simply takes a set of names for the vertices of the graph. For example:

julia> using Graphs

julia> using NamedGraphs

julia> g = NamedGraph(grid((4,)), ["A", "B", "C", "D"])
NamedGraph{String} with 4 vertices:
4-element Vector{String}:
 "A"
 "B"
 "C"
 "D"

and 3 edge(s):
"A" => "B"
"B" => "C"
"C" => "D"


julia> g = NamedGraph(grid((4,)); vertices=["A", "B", "C", "D"]) # Same as above
NamedGraph{String} with 4 vertices:
4-element Vector{String}:
 "A"
 "B"
 "C"
 "D"

and 3 edge(s):
"A" => "B"
"B" => "C"
"C" => "D"

Common operations are defined as you would expect:

julia> has_vertex(g, "A")
true

julia> has_edge(g, "A" => "B")
true

julia> has_edge(g, "A" => "C")
false

julia> neighbors(g, "B")
2-element Vector{String}:
 "A"
 "C"

julia> g[["A", "B"]]
NamedGraph{String} with 2 vertices:
2-element Vector{String}:
 "A"
 "B"

and 1 edge(s):
"A" => "B"

Internally, this type wraps a SimpleGraph, and stores a Dictionary from the Dictionaries.jl package that maps the vertex names to the linear indices of the underlying SimpleGraph.

Graph operations are implemented by mapping back and forth between the generalized named vertices and the linear index vertices of the SimpleGraph.

It is natural to use tuples of integers as the names for the vertices of graphs with grid connectivities. For this, we use the convention that if a tuple is input, it is interpreted as the grid size and the vertex names label cartesian coordinates:

julia> g = NamedGraph(grid((2, 2)); vertices=(2, 2))
NamedGraph{Tuple{Int64, Int64}} with 4 vertices:
4-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (2, 1)
 (1, 2)
 (2, 2)

and 4 edge(s):
(1, 1) => (2, 1)
(1, 1) => (1, 2)
(2, 1) => (2, 2)
(1, 2) => (2, 2)

Internally the vertices are all stored as tuples with a label in each dimension.

Vertices can be referred to by their tuples:

julia> has_vertex(g, (1, 1))
true

julia> has_edge(g, (1, 1) => (2, 1))
true

julia> has_edge(g, (1, 1) => (2, 2))
false

julia> neighbors(g, (2, 2))
2-element Vector{Tuple{Int64, Int64}}:
 (2, 1)
 (1, 2)

You can use vertex names to get induced subgraphs:

julia> subgraph(v -> v[1] == 1, g)
NamedGraph{Tuple{Int64, Int64}} with 2 vertices:
2-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (1, 2)

and 1 edge(s):
(1, 1) => (1, 2)


julia> subgraph(v -> v[2] == 2, g)
NamedGraph{Tuple{Int64, Int64}} with 2 vertices:
2-element Vector{Tuple{Int64, Int64}}:
 (1, 2)
 (2, 2)

and 1 edge(s):
(1, 2) => (2, 2)


julia> g[[(1, 1), (2, 2)]]
NamedGraph{Tuple{Int64, Int64}} with 2 vertices:
2-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (2, 2)

and 0 edge(s):

Note that this is similar to multidimensional array slicing, and we may support syntax like subgraph(v, 1, :) in the future.

You can also take disjoint unions or concatenations of graphs:

julia> g₁ = g
NamedGraph{Tuple{Int64, Int64}} with 4 vertices:
4-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (2, 1)
 (1, 2)
 (2, 2)

and 4 edge(s):
(1, 1) => (2, 1)
(1, 1) => (1, 2)
(2, 1) => (2, 2)
(1, 2) => (2, 2)


julia> g₂ = g
NamedGraph{Tuple{Int64, Int64}} with 4 vertices:
4-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (2, 1)
 (1, 2)
 (2, 2)

and 4 edge(s):
(1, 1) => (2, 1)
(1, 1) => (1, 2)
(2, 1) => (2, 2)
(1, 2) => (2, 2)


julia> disjoint_union(g₁, g₂)
NamedGraph{Tuple{Tuple{Int64, Int64}, Int64}} with 8 vertices:
8-element Vector{Tuple{Tuple{Int64, Int64}, Int64}}:
 ((1, 1), 1)
 ((2, 1), 1)
 ((1, 2), 1)
 ((2, 2), 1)
 ((1, 1), 2)
 ((2, 1), 2)
 ((1, 2), 2)
 ((2, 2), 2)

and 8 edge(s):
((1, 1), 1) => ((2, 1), 1)
((1, 1), 1) => ((1, 2), 1)
((2, 1), 1) => ((2, 2), 1)
((1, 2), 1) => ((2, 2), 1)
((1, 1), 2) => ((2, 1), 2)
((1, 1), 2) => ((1, 2), 2)
((2, 1), 2) => ((2, 2), 2)
((1, 2), 2) => ((2, 2), 2)


julia> g₁  g₂ # Same as above
NamedGraph{Tuple{Tuple{Int64, Int64}, Int64}} with 8 vertices:
8-element Vector{Tuple{Tuple{Int64, Int64}, Int64}}:
 ((1, 1), 1)
 ((2, 1), 1)
 ((1, 2), 1)
 ((2, 2), 1)
 ((1, 1), 2)
 ((2, 1), 2)
 ((1, 2), 2)
 ((2, 2), 2)

and 8 edge(s):
((1, 1), 1) => ((2, 1), 1)
((1, 1), 1) => ((1, 2), 1)
((2, 1), 1) => ((2, 2), 1)
((1, 2), 1) => ((2, 2), 1)
((1, 1), 2) => ((2, 1), 2)
((1, 1), 2) => ((1, 2), 2)
((2, 1), 2) => ((2, 2), 2)
((1, 2), 2) => ((2, 2), 2)

The symbol is just an alias for disjoint_union and can be written in the terminal or in your favorite IDE with the appropriate Julia extension with \sqcup<tab>

By default, this maps the vertices v₁ ∈ vertices(g₁) to (v₁, 1) and the vertices v₂ ∈ vertices(g₂) to (v₂, 2), so the resulting vertices of the unioned graph will always be unique. The resulting graph will have no edges between vertices (v₁, 1) and (v₂, 2), these would have to be added manually.

The original graphs can be obtained from subgraphs:

julia> rename_vertices(v -> v[1], subgraph(v -> v[2] == 1, g₁  g₂))
NamedGraph{Tuple{Int64, Int64}} with 4 vertices:
4-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (2, 1)
 (1, 2)
 (2, 2)

and 4 edge(s):
(1, 1) => (2, 1)
(1, 1) => (1, 2)
(2, 1) => (2, 2)
(1, 2) => (2, 2)


julia> rename_vertices(v -> v[1], subgraph(v -> v[2] == 2, g₁  g₂))
NamedGraph{Tuple{Int64, Int64}} with 4 vertices:
4-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (2, 1)
 (1, 2)
 (2, 2)

and 4 edge(s):
(1, 1) => (2, 1)
(1, 1) => (1, 2)
(2, 1) => (2, 2)
(1, 2) => (2, 2)

Generating this README

This file was generated with Weave.jl with the following commands:

using NamedGraphs, Weave
weave(
  joinpath(pkgdir(NamedGraphs), "examples", "README.jl");
  doctype="github",
  out_path=pkgdir(NamedGraphs),
)

About

Building Extra Features

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Julia 100.0%