Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesign GenericNamedGraph type #73

Merged
merged 16 commits into from
Apr 26, 2024
4 changes: 2 additions & 2 deletions examples/multidimgraph_1d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ using Graphs: grid, has_edge, has_vertex, ne, nv
using NamedGraphs: NamedGraph
using NamedGraphs.GraphsExtensions: ⊔, subgraph

parent_graph = grid((4,))
ordinal_graph = grid((4,))
vs = ["A", "B", "C", "D"]
g = NamedGraph(parent_graph, vs)
g = NamedGraph(ordinal_graph, vs)

@show has_vertex(g, "A")
@show !has_vertex(g, "E")
Expand Down
10 changes: 5 additions & 5 deletions examples/multidimgraph_2d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ using Graphs: grid, has_edge, has_vertex, nv
using NamedGraphs: NamedGraph
using NamedGraphs.GraphsExtensions: ⊔, subgraph

parent_graph = grid((2, 2))
ordinal_graph = grid((2, 2))
vs = [("X", 1), ("X", 2), ("Y", 1), ("Y", 2)]

g = NamedGraph(parent_graph, vs)
g = NamedGraph(ordinal_graph, vs)

@show has_vertex(g, ("X", 1))
@show has_edge(g, ("X", 1) => ("X", 2))
Expand Down Expand Up @@ -42,9 +42,9 @@ g_sub = subgraph(v -> v[2] == 2, g)
@show !has_vertex(g_sub, ("Y", 1))
@show has_vertex(g_sub, ("Y", 2))

parent_graph = grid((2, 2))
g1 = NamedGraph(parent_graph, Tuple.(CartesianIndices((2, 2))))
g2 = NamedGraph(parent_graph, Tuple.(CartesianIndices((2, 2))))
ordinal_graph = grid((2, 2))
g1 = NamedGraph(ordinal_graph, Tuple.(CartesianIndices((2, 2))))
g2 = NamedGraph(ordinal_graph, Tuple.(CartesianIndices((2, 2))))

g_disjoint_union = g1 ⊔ g2

Expand Down
10 changes: 5 additions & 5 deletions ext/NamedGraphsGraphsFlowsExt/NamedGraphsGraphsFlowsExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ using NamedGraphs:
DefaultNamedCapacity,
_symmetrize,
dist_matrix_to_parent_dist_matrix,
parent_graph,
ordinal_graph,
parent_vertices_to_vertices,
vertex_to_parent_vertex
vertex_to_ordinal_vertex
using NamedGraphs.GraphsExtensions: GraphsExtensions, directed_graph
using SimpleTraits: SimpleTraits, @traitfn

Expand All @@ -27,9 +27,9 @@ end
algorithm::GraphsFlows.AbstractFlowAlgorithm=GraphsFlows.PushRelabelAlgorithm(),
)
parent_part1, parent_part2, flow = GraphsFlows.mincut(
directed_graph(parent_graph(graph)),
vertex_to_parent_vertex(graph, source),
vertex_to_parent_vertex(graph, target),
directed_graph(ordinal_graph(graph)),
vertex_to_ordinal_vertex(graph, source),
vertex_to_ordinal_vertex(graph, target),
dist_matrix_to_parent_dist_matrix(graph, capacity_matrix),
algorithm,
)
Expand Down
116 changes: 58 additions & 58 deletions src/abstractnamedgraph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ abstract type AbstractNamedGraph{V} <: AbstractGraph{V} end
#

Graphs.vertices(graph::AbstractNamedGraph) = not_implemented()
parent_graph(graph::AbstractNamedGraph) = not_implemented()
ordinal_graph(graph::AbstractNamedGraph) = not_implemented()

# TODO: Require this for the interface, or implement as:
# typeof(parent_graph(graph))
# typeof(ordinal_graph(graph))
# ?
parent_graph_type(graph::AbstractNamedGraph) = not_implemented()
ordinal_graph_type(graph::AbstractNamedGraph) = not_implemented()

Graphs.rem_vertex!(graph::AbstractNamedGraph, vertex) = not_implemented()
Graphs.add_vertex!(graph::AbstractNamedGraph, vertex) = not_implemented()
Expand All @@ -61,27 +61,27 @@ function GraphsExtensions.permute_vertices(graph::AbstractNamedGraph, permutatio
end

# Convert vertex to parent vertex
# Inverse map of `parent_vertex_to_vertex`.
vertex_to_parent_vertex(graph::AbstractNamedGraph, vertex) = not_implemented()
# Inverse map of `ordered_vertices`.
vertex_to_ordinal_vertex(graph::AbstractNamedGraph, vertex) = not_implemented()

# Convert parent vertex to vertex.
# Use `vertices`, assumes `vertices` is indexed by a parent vertex (a Vector for linear indexed parent vertices, a dictionary in general).
parent_vertex_to_vertex(graph::AbstractNamedGraph, parent_vertex) = not_implemented()
ordered_vertices(graph::AbstractNamedGraph, parent_vertex) = not_implemented()

Graphs.edgetype(graph::AbstractNamedGraph) = not_implemented()

# TODO: Define generic version in `GraphsExtensions`.
GraphsExtensions.directed_graph_type(G::Type{<:AbstractNamedGraph}) = not_implemented()
GraphsExtensions.undirected_graph_type(G::Type{<:AbstractNamedGraph}) = not_implemented()

# In terms of `parent_graph_type`
# In terms of `ordinal_graph_type`
# is_directed(::Type{<:AbstractNamedGraph}) = not_implemented()

GraphsExtensions.convert_vertextype(::Type, ::AbstractNamedGraph) = not_implemented()

# TODO: implement as:
#
# graph = set_parent_graph(graph, copy(parent_graph(graph)))
# graph = set_ordinal_graph(graph, copy(ordinal_graph(graph)))
# graph = set_vertices(graph, copy(vertices(graph)))
#
# or:
Expand All @@ -106,16 +106,16 @@ function Graphs.has_vertex(graph::AbstractNamedGraph, vertex)
return vertex ∈ vertices(graph)
end

parent_vertextype(graph::AbstractNamedGraph) = vertextype(parent_graph(graph))
parent_vertextype(graph::AbstractNamedGraph) = vertextype(ordinal_graph(graph))

Graphs.SimpleDiGraph(graph::AbstractNamedGraph) = SimpleDiGraph(parent_graph(graph))
Graphs.SimpleDiGraph(graph::AbstractNamedGraph) = SimpleDiGraph(ordinal_graph(graph))

# Convenient shorthands for using in higher order functions like `map`.
function vertex_to_parent_vertex(graph::AbstractNamedGraph)
return Base.Fix1(vertex_to_parent_vertex, graph)
function vertex_to_ordinal_vertex(graph::AbstractNamedGraph)
return Base.Fix1(vertex_to_ordinal_vertex, graph)
end
function parent_vertex_to_vertex(graph::AbstractNamedGraph)
return Base.Fix1(parent_vertex_to_vertex, graph)
function ordered_vertices(graph::AbstractNamedGraph)
return Base.Fix1(ordered_vertices, graph)
end

Base.zero(G::Type{<:AbstractNamedGraph}) = G()
Expand All @@ -133,31 +133,31 @@ end
# Default, can overload
Base.eltype(graph::AbstractNamedGraph) = eltype(vertices(graph))

parent_eltype(graph::AbstractNamedGraph) = eltype(parent_graph(graph))
parent_eltype(graph::AbstractNamedGraph) = eltype(ordinal_graph(graph))

function vertices_to_parent_vertices(graph::AbstractNamedGraph, vertices)
return map(vertex_to_parent_vertex(graph), vertices)
return map(vertex_to_ordinal_vertex(graph), vertices)
end

function vertices_to_parent_vertices(graph::AbstractNamedGraph)
return Base.Fix1(vertices_to_parent_vertices, graph)
end

function parent_vertices_to_vertices(graph::AbstractNamedGraph, parent_vertices)
return map(parent_vertex_to_vertex(graph), parent_vertices)
return map(ordered_vertices(graph), parent_vertices)
end

function parent_vertices_to_vertices(graph::AbstractNamedGraph)
return Base.Fix1(parent_vertices_to_vertices, graph)
end

parent_vertices(graph::AbstractNamedGraph) = vertices(parent_graph(graph))
parent_edges(graph::AbstractNamedGraph) = edges(parent_graph(graph))
parent_edgetype(graph::AbstractNamedGraph) = edgetype(parent_graph(graph))
parent_vertices(graph::AbstractNamedGraph) = vertices(ordinal_graph(graph))
parent_edges(graph::AbstractNamedGraph) = edges(ordinal_graph(graph))
parent_edgetype(graph::AbstractNamedGraph) = edgetype(ordinal_graph(graph))

function edge_to_parent_edge(graph::AbstractNamedGraph, edge::AbstractEdge)
parent_src = vertex_to_parent_vertex(graph, src(edge))
parent_dst = vertex_to_parent_vertex(graph, dst(edge))
parent_src = vertex_to_ordinal_vertex(graph, src(edge))
parent_dst = vertex_to_ordinal_vertex(graph, dst(edge))
return parent_edgetype(graph)(parent_src, parent_dst)
end

Expand All @@ -172,8 +172,8 @@ function edges_to_parent_edges(graph::AbstractNamedGraph, edges)
end

function parent_edge_to_edge(graph::AbstractNamedGraph, parent_edge::AbstractEdge)
source = parent_vertex_to_vertex(graph, src(parent_edge))
destination = parent_vertex_to_vertex(graph, dst(parent_edge))
source = ordered_vertices(graph, src(parent_edge))
destination = ordered_vertices(graph, dst(parent_edge))
return edgetype(graph)(source, destination)
end

Expand All @@ -200,13 +200,13 @@ for f in [
]
@eval begin
function $f(graph::AbstractNamedGraph, vertex)
parent_vertices = $f(parent_graph(graph), vertex_to_parent_vertex(graph, vertex))
parent_vertices = $f(ordinal_graph(graph), vertex_to_ordinal_vertex(graph, vertex))
return parent_vertices_to_vertices(graph, parent_vertices)
end

# Ambiguity errors with Graphs.jl
function $f(graph::AbstractNamedGraph, vertex::Integer)
parent_vertices = $f(parent_graph(graph), vertex_to_parent_vertex(graph, vertex))
parent_vertices = $f(ordinal_graph(graph), vertex_to_ordinal_vertex(graph, vertex))
return parent_vertices_to_vertices(graph, parent_vertices)
end
end
Expand Down Expand Up @@ -262,10 +262,10 @@ function namedgraph_neighborhood(
)
parent_distmx = dist_matrix_to_parent_dist_matrix(graph, distmx)
parent_vertices = neighborhood(
parent_graph(graph), vertex_to_parent_vertex(graph, vertex), d, parent_distmx; dir
ordinal_graph(graph), vertex_to_ordinal_vertex(graph, vertex), d, parent_distmx; dir
)
return [
parent_vertex_to_vertex(graph, parent_vertex) for parent_vertex in parent_vertices
ordered_vertices(graph, parent_vertex) for parent_vertex in parent_vertices
]
mtfishman marked this conversation as resolved.
Show resolved Hide resolved
end

Expand All @@ -292,10 +292,10 @@ end
function namedgraph_neighborhood_dists(graph::AbstractNamedGraph, vertex, d, distmx; dir)
parent_distmx = dist_matrix_to_parent_dist_matrix(graph, distmx)
parent_vertices_and_dists = neighborhood_dists(
parent_graph(graph), vertex_to_parent_vertex(graph, vertex), d, parent_distmx; dir
ordinal_graph(graph), vertex_to_ordinal_vertex(graph, vertex), d, parent_distmx; dir
)
return [
(parent_vertex_to_vertex(graph, parent_vertex), dist) for
(ordered_vertices(graph, parent_vertex), dist) for
(parent_vertex, dist) in parent_vertices_and_dists
]
end
Expand All @@ -322,7 +322,7 @@ end

function namedgraph_mincut(graph::AbstractNamedGraph, distmx)
parent_distmx = dist_matrix_to_parent_dist_matrix(graph, distmx)
parent_parity, bestcut = Graphs.mincut(parent_graph(graph), parent_distmx)
parent_parity, bestcut = Graphs.mincut(ordinal_graph(graph), parent_distmx)
return Dictionary(vertices(graph), parent_parity), bestcut
end

Expand All @@ -339,9 +339,9 @@ function GraphsExtensions.partitioned_vertices(
g::AbstractNamedGraph; npartitions=nothing, nvertices_per_partition=nothing, kwargs...
)
vertex_partitions = partitioned_vertices(
parent_graph(g); npartitions, nvertices_per_partition, kwargs...
ordinal_graph(g); npartitions, nvertices_per_partition, kwargs...
)
#[inv(vertex_to_parent_vertex(g))[v] for v in partitions]
#[inv(vertex_to_ordinal_vertex(g))[v] for v in partitions]
# TODO: output the reverse of this dictionary (a Vector of Vector
# of the vertices in each partition).
# return Dictionary(vertices(g), partitions)
Expand All @@ -361,9 +361,9 @@ function namedgraph_a_star(
)
parent_distmx = dist_matrix_to_parent_dist_matrix(graph, distmx)
parent_shortest_path = a_star(
parent_graph(graph),
vertex_to_parent_vertex(graph, source),
vertex_to_parent_vertex(graph, destination),
ordinal_graph(graph),
vertex_to_ordinal_vertex(graph, source),
vertex_to_ordinal_vertex(graph, destination),
dist_matrix_to_parent_dist_matrix(graph, distmx),
heuristic,
SimpleEdge,
Expand All @@ -387,32 +387,32 @@ function Graphs.spfa_shortest_paths(
)
parent_distmx = dist_matrix_to_parent_dist_matrix(graph, distmx)
parent_shortest_paths = spfa_shortest_paths(
parent_graph(graph), vertex_to_parent_vertex(graph, vertex), parent_distmx
ordinal_graph(graph), vertex_to_ordinal_vertex(graph, vertex), parent_distmx
)
return Dictionary(vertices(graph), parent_shortest_paths)
end

function Graphs.boruvka_mst(
g::AbstractNamedGraph, distmx::AbstractMatrix{<:Real}=weights(g); minimize=true
)
parent_mst, weights = boruvka_mst(parent_graph(g), distmx; minimize)
parent_mst, weights = boruvka_mst(ordinal_graph(g), distmx; minimize)
return parent_edges_to_edges(g, parent_mst), weights
end

function Graphs.kruskal_mst(
g::AbstractNamedGraph, distmx::AbstractMatrix{<:Real}=weights(g); minimize=true
)
parent_mst = kruskal_mst(parent_graph(g), distmx; minimize)
parent_mst = kruskal_mst(ordinal_graph(g), distmx; minimize)
return parent_edges_to_edges(g, parent_mst)
end

function Graphs.prim_mst(g::AbstractNamedGraph, distmx::AbstractMatrix{<:Real}=weights(g))
parent_mst = prim_mst(parent_graph(g), distmx)
parent_mst = prim_mst(ordinal_graph(g), distmx)
return parent_edges_to_edges(g, parent_mst)
end

function Graphs.add_edge!(graph::AbstractNamedGraph, edge::AbstractEdge)
add_edge!(parent_graph(graph), edge_to_parent_edge(graph, edge))
add_edge!(ordinal_graph(graph), edge_to_parent_edge(graph, edge))
return graph
end

Expand All @@ -421,12 +421,12 @@ Graphs.add_edge!(g::AbstractNamedGraph, edge) = add_edge!(g, edgetype(g)(edge))
Graphs.add_edge!(g::AbstractNamedGraph, src, dst) = add_edge!(g, edgetype(g)(src, dst))

function Graphs.rem_edge!(graph::AbstractNamedGraph, edge)
rem_edge!(parent_graph(graph), edge_to_parent_edge(graph, edge))
rem_edge!(ordinal_graph(graph), edge_to_parent_edge(graph, edge))
return graph
end

function Graphs.has_edge(graph::AbstractNamedGraph, edge::AbstractNamedEdge)
return has_edge(parent_graph(graph), edge_to_parent_edge(graph, edge))
return has_edge(ordinal_graph(graph), edge_to_parent_edge(graph, edge))
end

# handles two-argument edge constructors like src,dst
Expand All @@ -437,9 +437,9 @@ function Graphs.has_path(
graph::AbstractNamedGraph, source, destination; exclude_vertices=vertextype(graph)[]
)
return has_path(
parent_graph(graph),
vertex_to_parent_vertex(graph, source),
vertex_to_parent_vertex(graph, destination);
ordinal_graph(graph),
vertex_to_ordinal_vertex(graph, source),
vertex_to_ordinal_vertex(graph, destination);
exclude_vertices=vertices_to_parent_vertices(graph, exclude_vertices),
)
end
Expand Down Expand Up @@ -468,16 +468,16 @@ function Base.union(
return union(union(graph1, graph2), graph3, graph_rest...)
end

Graphs.is_directed(G::Type{<:AbstractNamedGraph}) = is_directed(parent_graph_type(G))
Graphs.is_directed(G::Type{<:AbstractNamedGraph}) = is_directed(ordinal_graph_type(G))

Graphs.is_directed(graph::AbstractNamedGraph) = is_directed(parent_graph(graph))
Graphs.is_directed(graph::AbstractNamedGraph) = is_directed(ordinal_graph(graph))

Graphs.is_connected(graph::AbstractNamedGraph) = is_connected(parent_graph(graph))
Graphs.is_connected(graph::AbstractNamedGraph) = is_connected(ordinal_graph(graph))

Graphs.is_cyclic(graph::AbstractNamedGraph) = is_cyclic(parent_graph(graph))
Graphs.is_cyclic(graph::AbstractNamedGraph) = is_cyclic(ordinal_graph(graph))

@traitfn function Base.reverse(graph::AbstractNamedGraph::IsDirected)
reversed_parent_graph = reverse(parent_graph(graph))
reversed_ordinal_graph = reverse(ordinal_graph(graph))
return h
end

Expand All @@ -488,23 +488,23 @@ end

# TODO: Move to `namedgraph.jl`, or make the output generic?
function Graphs.blockdiag(graph1::AbstractNamedGraph, graph2::AbstractNamedGraph)
new_parent_graph = blockdiag(parent_graph(graph1), parent_graph(graph2))
new_ordinal_graph = blockdiag(ordinal_graph(graph1), ordinal_graph(graph2))
new_vertices = vcat(vertices(graph1), vertices(graph2))
@assert allunique(new_vertices)
return GenericNamedGraph(new_parent_graph, new_vertices)
return GenericNamedGraph(new_ordinal_graph, new_vertices)
end

# TODO: What `args` are needed?
Graphs.nv(graph::AbstractNamedGraph, args...) = nv(parent_graph(graph), args...)
Graphs.nv(graph::AbstractNamedGraph, args...) = nv(ordinal_graph(graph), args...)
# TODO: What `args` are needed?
Graphs.ne(graph::AbstractNamedGraph, args...) = ne(parent_graph(graph), args...)
Graphs.ne(graph::AbstractNamedGraph, args...) = ne(ordinal_graph(graph), args...)
# TODO: What `args` are needed?
function Graphs.adjacency_matrix(graph::AbstractNamedGraph, args...)
return adjacency_matrix(parent_graph(graph), args...)
return adjacency_matrix(ordinal_graph(graph), args...)
end

function Graphs.connected_components(graph::AbstractNamedGraph)
parent_connected_components = connected_components(parent_graph(graph))
parent_connected_components = connected_components(ordinal_graph(graph))
return map(parent_vertices_to_vertices(graph), parent_connected_components)
end

Expand Down Expand Up @@ -564,7 +564,7 @@ end
# vertex in the traversal/spanning tree.
function namedgraph_bfs_parents(graph::AbstractNamedGraph, vertex; kwargs...)
parent_bfs_parents = bfs_parents(
parent_graph(graph), vertex_to_parent_vertex(graph, vertex); kwargs...
ordinal_graph(graph), vertex_to_ordinal_vertex(graph, vertex); kwargs...
)
# Works around issue in this `Dictionary` constructor:
# https://github.com/andyferris/Dictionaries.jl/blob/v0.4.1/src/Dictionary.jl#L139-L145
Expand Down
Loading
Loading