diff --git a/Project.toml b/Project.toml index 5743190f..d5dab0f3 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "NamedGraphs" uuid = "678767b0-92e7-4007-89e4-4527a8725b19" -version = "0.11.3" +version = "0.11.4" authors = ["Matthew Fishman , Joseph Tindall and contributors"] [workspace] diff --git a/src/NamedGraphs.jl b/src/NamedGraphs.jl index c3021b1d..5a8bfd5a 100644 --- a/src/NamedGraphs.jl +++ b/src/NamedGraphs.jl @@ -10,6 +10,7 @@ include("abstractnamededge.jl") include("namededge.jl") include("abstractnamedgraph.jl") include("abstractgraphindices.jl") +include("similar_graph.jl") include("decorate.jl") include("simplecycles.jl") include("shortestpaths.jl") diff --git a/src/abstractnamedgraph.jl b/src/abstractnamedgraph.jl index 41fa82d9..6d99927b 100644 --- a/src/abstractnamedgraph.jl +++ b/src/abstractnamedgraph.jl @@ -1,13 +1,12 @@ -using .GraphsExtensions: GraphsExtensions, all_edges, directed_graph, incident_edges, - partition_vertices, rem_edges, rem_edges!, rem_vertices, rename_vertices, - similar_simplegraph, subgraph +using .GraphsExtensions: GraphsExtensions, all_edges, directed_graph, empty_graph, + incident_edges, partition_vertices, rem_edges, rem_edges!, rem_vertices, + rename_vertices, similar_graph, subgraph using Dictionaries: set! -using Graphs.SimpleGraphs: SimpleDiGraph, SimpleEdge -using Graphs: Graphs, AbstractGraph, AbstractSimpleGraph, IsDirected, a_star, add_edge!, - adjacency_matrix, bfs_parents, boruvka_mst, connected_components, degree, edges, - has_path, indegree, induced_subgraph, inneighbors, is_connected, is_cyclic, kruskal_mst, - ne, neighborhood, neighborhood_dists, nv, outdegree, prim_mst, rem_edge!, - spfa_shortest_paths, vertices, weights +using Graphs: Graphs, AbstractGraph, AbstractSimpleGraph, IsDirected, SimpleDiGraph, + SimpleEdge, SimpleGraph, a_star, add_edge!, adjacency_matrix, bfs_parents, boruvka_mst, + connected_components, degree, edges, has_path, indegree, induced_subgraph, inneighbors, + is_connected, is_cyclic, kruskal_mst, ne, neighborhood, neighborhood_dists, nv, + outdegree, prim_mst, rem_edge!, spfa_shortest_paths, vertices, weights using SimpleTraits: SimpleTraits, @traitfn, Not abstract type AbstractNamedGraph{V} <: AbstractGraph{V} end @@ -51,42 +50,6 @@ Graphs.edgetype(::Type{<:AbstractNamedGraph}) = not_implemented() GraphsExtensions.convert_vertextype(::Type{V}, g::AbstractNamedGraph{V}) where {V} = g GraphsExtensions.convert_vertextype(::Type, g::AbstractNamedGraph) = not_implemented() -function similar_graph(graph::AbstractGraph) - newgraph = similar_graph(graph, vertices(graph)) - add_edges!(newgraph, edges(graph)) - return newgraph -end - -# Construct `GenericNamedGraph` as a fallback. -@traitfn function similar_graph( - graph::AbstractGraph::(!IsDirected), - vertices - ) - V = eltype(vertices) - return NamedGraph{V}(vertices) -end -@traitfn function similar_graph( - graph::AbstractGraph::IsDirected, - vertices - ) - V = eltype(vertices) - return NamedDiGraph{V}(vertices) -end - -# Passing a type as a first argument attempts to call a constructor. Should be overloaded -# if the constructor doesnt exist for a given `AbstractGraph` concrete type. -similar_graph(T::Type{<:AbstractGraph}) = similar_graph(T, vertextype(T)[]) -similar_graph(T::Type{<:AbstractGraph}, vertices) = T(vertices) - -# If `T <: AbstractSimpleGraph`, then we defer to `GraphsExtensions.similar_simplegraph`. -function similar_graph(T::Type{<:AbstractSimpleGraph}, vertices = 0) - return similar_simplegraph(T, vertices) -end - -edgeless_graph(graph::AbstractGraph) = rem_edges(graph, edges(graph)) - -empty_graph(graph::AbstractGraph) = rem_vertices(graph, vertices(graph)) - Base.copy(graph::AbstractNamedGraph) = copyto!(similar_graph(graph), graph) function Graphs.merge_vertices!( @@ -585,7 +548,7 @@ end # TODO: Implement an edgelist version function induced_subgraph_from_vertices(graph::AbstractGraph, subvertices) - subgraph = similar_graph(graph, collect(subvertices)) + subgraph = similar_graph(graph, subvertices) add_edges!(subgraph, subgraph_edges(graph, subvertices)) return subgraph, nothing end @@ -613,23 +576,3 @@ function edge_subgraph_namedgraph(graph, edgelist) g = rem_edges!(g, setdiff(edges(g), edgelist)) return g end - -@traitfn function GraphsExtensions.directed_graph(graph::AbstractNamedGraph::(!IsDirected)) - digraph = similar_graph(directed_graph_type(graph), vertices(graph)) - add_edges!(digraph, all_edges(graph)) - return digraph -end - -@traitfn function GraphsExtensions.undirected_graph(graph::AbstractNamedGraph::IsDirected) - undigraph = similar_graph(undirected_graph_type(graph), vertices(graph)) - for e in edges(graph) - has_edge(undigraph, e) && continue - add_edge!(undigraph, e) - end - return undigraph -end - -function GraphsExtensions.forest_cover_edge_sequence(graph::AbstractNamedGraph; kwargs...) - dummy_graph = add_edges!(NamedGraph(vertices(graph)), edges(graph)) - return GraphsExtensions.forest_cover_edge_sequence(dummy_graph; kwargs...) -end diff --git a/src/lib/GraphsExtensions/src/abstractgraph.jl b/src/lib/GraphsExtensions/src/abstractgraph.jl index b5bcc9d7..d8f70e74 100644 --- a/src/lib/GraphsExtensions/src/abstractgraph.jl +++ b/src/lib/GraphsExtensions/src/abstractgraph.jl @@ -26,17 +26,26 @@ convert_vertextype(::Type, ::AbstractGraph) = not_implemented() convert_vertextype(::Type{V}, G::Type{<:AbstractGraph{V}}) where {V} = G convert_vertextype(::Type, ::Type{<:AbstractGraph}) = not_implemented() -# ==================================== similar_simplegraph =============================== # +# ==================================== similar_graph ===================================== # -function similar_simplegraph(graph::AbstractGraph) - newgraph = similar_simplegraph(graph, vertices(graph)) +# Generic for any `AbstractGraph`. +function similar_graph(graph::AbstractGraph) + newgraph = similar_graph(graph, vertices(graph)) add_edges!(newgraph, edges(graph)) return newgraph end +similar_graph(graph::AbstractGraph, vertices) = similar_simplegraph(graph, vertices) + +# Don't know a sensible fallback in `Graphs.jl` for a non-`Base.OneTo` vertex collection. +function similar_simplegraph(graph::AbstractGraph, vertices) + return throw(MethodError(similar_graph, (typeof(graph), typeof(vertices)))) +end + function similar_simplegraph(graph::AbstractGraph, vertices::Base.OneTo) - return similar_simplegraph(graph, length(vertices)) + return similar_graph(graph, length(vertices)) end + # To be specialized (optional, has following fallback) @traitfn function similar_simplegraph( graph::AbstractGraph::(!IsDirected), @@ -55,16 +64,61 @@ end return new_graph end -similar_simplegraph(T::Type{<:AbstractSimpleGraph}) = T() -similar_simplegraph(T::Type{<:AbstractSimpleGraph}, vertices) = T(vertices) -function similar_simplegraph(T::Type{<:AbstractSimpleGraph}, vertices::Base.OneTo) - return similar_simplegraph(T, length(vertices)) +# Type domain versions attempt to call a constructor. +similar_graph(T::Type{<:AbstractGraph}) = T() +similar_graph(T::Type{<:AbstractGraph}, vertices) = T(vertices) +function similar_graph(T::Type{<:AbstractSimpleGraph}, vertices::Base.OneTo) + return similar_graph(T, length(vertices)) +end +similar_graph(T::Type{<:AbstractSimpleGraph}) = similar_graph(T, 0) + +# =============================== `similar_dataless_grap` ================================ # +# This function behaves much the same as `similar_graph`, but should strictly return a +# a similar graph type that has no notion of data (in the abstract sense). + +function similar_dataless_graph(graph::AbstractGraph) + dataless_graph = similar_dataless_graph(graph, vertices(graph)) + add_edges!(dataless_graph, edges(graph)) + return dataless_graph +end + +function similar_dataless_graph(graph::AbstractGraph, vertices) + return similar_dataless_simplegraph(graph, vertices) +end + +function similar_dataless_simplegraph(graph::AbstractGraph, vertices::Base.OneTo) + return similar_dataless_simplegraph(graph, length(vertices)) +end + +# Fallbacks +@traitfn function similar_dataless_simplegraph(graph::AbstractGraph::!(IsDirected), nv::Int) + return SimpleGraph(nv) +end + +@traitfn function similar_dataless_simplegraph(graph::AbstractGraph::IsDirected, nv::Int) + return SimpleDiGraph(nv) end -similar_simplegraph(T::Type{<:AbstractSimpleGraph}, nvertices::Int) = T(nvertices) + +edgeless_graph(graph::AbstractGraph) = rem_edges(graph, edges(graph)) +empty_graph(graph::AbstractGraph) = rem_vertices(graph, vertices(graph)) @traitfn directed_graph(graph::::IsDirected) = graph @traitfn undirected_graph(graph::::(!IsDirected)) = graph +@traitfn function directed_graph(graph::AbstractGraph::(!IsDirected)) + digraph = similar_graph(directed_graph_type(graph), vertices(graph)) + add_edges!(digraph, all_edges(graph)) + return digraph +end +@traitfn function undirected_graph(graph::AbstractGraph::IsDirected) + undigraph = similar_graph(undirected_graph_type(graph), vertices(graph)) + for e in edges(graph) + has_edge(undigraph, e) && continue + add_edge!(undigraph, e) + end + return undigraph +end + # Similar to `eltype`, but `eltype` doesn't work on types vertextype(::Type{<:AbstractGraph{V}}) where {V} = V vertextype(graph::AbstractGraph) = vertextype(typeof(graph)) diff --git a/src/lib/GraphsExtensions/src/simplegraph.jl b/src/lib/GraphsExtensions/src/simplegraph.jl index 4a7b3910..25c17ce9 100644 --- a/src/lib/GraphsExtensions/src/simplegraph.jl +++ b/src/lib/GraphsExtensions/src/simplegraph.jl @@ -20,28 +20,7 @@ function convert_vertextype(vertextype::Type, graph::SimpleDiGraph) end directed_graph_type(G::Type{<:SimpleGraph}) = SimpleDiGraph{vertextype(G)} -# TODO: Use traits to make this more general. undirected_graph_type(G::Type{<:SimpleGraph}) = G -# TODO: Use traits to make this more general. directed_graph_type(G::Type{<:SimpleDiGraph}) = G undirected_graph_type(G::Type{<:SimpleDiGraph}) = SimpleGraph{vertextype(G)} - -@traitfn function directed_graph(graph::AbstractSimpleGraph::(!IsDirected)) - digraph = similar_simplegraph(directed_graph_type(graph), vertices(graph)) - add_edges!(digraph, all_edges(graph)) - return digraph -end - -# Must have the same argument name as: -# @traitfn undirected_graph(graph::::(!IsDirected)) -# to avoid method overwrite warnings, see: -# https://github.com/mauro3/SimpleTraits.jl#method-overwritten-warnings -@traitfn function undirected_graph(graph::AbstractSimpleGraph::IsDirected) - undigraph = similar_simplegraph(undirected_graph_type(graph), vertices(graph)) - for e in edges(graph) - has_edge(undigraph, e) && continue - add_edge!(undigraph, e) - end - return undigraph -end diff --git a/src/lib/GraphsExtensions/src/trees_and_forests.jl b/src/lib/GraphsExtensions/src/trees_and_forests.jl index ac070f0f..1564ab5b 100644 --- a/src/lib/GraphsExtensions/src/trees_and_forests.jl +++ b/src/lib/GraphsExtensions/src/trees_and_forests.jl @@ -1,5 +1,5 @@ using .GraphsExtensions: random_bfs_tree, rem_edges, undirected_graph -using Graphs: IsDirected, bfs_tree, connected_components, edges, edgetype +using Graphs: AbstractGraph, IsDirected, bfs_tree, connected_components, edges, edgetype using SimpleTraits: SimpleTraits, @traitfn, Not abstract type SpanningTreeAlgorithm end @@ -47,9 +47,12 @@ end # Given an undirected graph g with vertex set V, build a set of forests (each with vertex set V) which covers all edges in g # (see https://en.wikipedia.org/wiki/Arboricity) We do not find the minimum but our tests show this algorithm performs well function forest_cover(g::AbstractGraph; spanning_tree = spanning_tree) - edges_collected = edgetype(g)[] + g = similar_dataless_graph(g) + g_reduced = g + remaining_edges = edges(g) - g_reduced = rem_edges(g, edges_collected) + edges_collected = empty(remaining_edges) + forests = typeof(g)[] while !isempty(remaining_edges) g_reduced_spanning_forest = spanning_forest(g_reduced; spanning_tree) diff --git a/src/lib/GraphsExtensions/test/runtests.jl b/src/lib/GraphsExtensions/test/runtests.jl index a6e82140..1192a5aa 100644 --- a/src/lib/GraphsExtensions/test/runtests.jl +++ b/src/lib/GraphsExtensions/test/runtests.jl @@ -9,14 +9,14 @@ using NamedGraphs.GraphGenerators: binary_arborescence using NamedGraphs.GraphsExtensions: TreeGraph, add_edge, add_edges, add_edges!, add_vertices!, all_edges, arrange_edge, arranged_edges, child_edges, child_vertices, convert_vertextype, degrees, directed_graph, directed_graph_type, disjoint_union, - distance_to_leaves, has_edges, has_leaf_neighbor, has_vertices, incident_edges, - indegrees, is_arborescence, is_arranged, is_binary_arborescence, is_cycle_graph, - is_ditree, is_edge_arranged, is_leaf_edge, is_leaf_vertex, is_path_graph, - is_root_vertex, is_rooted, is_self_loop, leaf_vertices, minimum_distance_to_leaves, - next_nearest_neighbors, non_leaf_edges, outdegrees, permute_vertices, rem_edge, - rem_edges, rem_edges!, rename_vertices, root_vertex, similar_simplegraph, subgraph, - tree_graph_node, undirected_graph, undirected_graph_type, vertextype, - vertices_at_distance, ⊔ + distance_to_leaves, forest_cover_edge_sequence, has_edges, has_leaf_neighbor, + has_vertices, incident_edges, indegrees, is_arborescence, is_arranged, + is_binary_arborescence, is_cycle_graph, is_ditree, is_edge_arranged, is_leaf_edge, + is_leaf_vertex, is_path_graph, is_root_vertex, is_rooted, is_self_loop, leaf_vertices, + minimum_distance_to_leaves, next_nearest_neighbors, non_leaf_edges, outdegrees, + permute_vertices, rem_edge, rem_edges, rem_edges!, rename_vertices, root_vertex, + similar_dataless_graph, similar_graph, subgraph, tree_graph_node, undirected_graph, + undirected_graph_type, vertextype, vertices_at_distance, ⊔ using NamedGraphs: NamedDiGraph, NamedEdge, NamedGraph using Test: @test, @test_broken, @test_throws, @testset @@ -482,20 +482,31 @@ using Test: @test, @test_broken, @test_throws, @testset @test_throws ErrorException root_vertex(g) @test_throws MethodError root_vertex(binary_tree(3)) - # similar_simplegraph + # similar_graph g = path_graph(4) - @test similar_simplegraph(g) isa typeof(g) - @test similar_simplegraph(g) == g - @test similar_simplegraph(typeof(g)) isa typeof(g) - @test similar_simplegraph(typeof(g)) == typeof(g)() - @test isempty(edges(similar_simplegraph(typeof(g)))) - @test isempty(vertices(similar_simplegraph(typeof(g)))) + @test similar_graph(g) isa typeof(g) + @test similar_graph(g) == g + @test similar_graph(typeof(g)) isa typeof(g) + @test similar_graph(typeof(g)) == typeof(g)() + @test isempty(edges(similar_graph(typeof(g)))) + @test isempty(vertices(similar_graph(typeof(g)))) - @test similar_simplegraph(g, vertices(g)) == typeof(g)(4) - @test similar_simplegraph(typeof(g), vertices(g)) == typeof(g)(4) - @test isempty(edges(similar_simplegraph(g, vertices(g)))) - @test isempty(edges(similar_simplegraph(typeof(g), vertices(g)))) + @test similar_graph(g, vertices(g)) == typeof(g)(4) + @test similar_graph(typeof(g), vertices(g)) == typeof(g)(4) + @test isempty(edges(similar_graph(g, vertices(g)))) + @test isempty(edges(similar_graph(typeof(g), vertices(g)))) + + # similar_dataless_graph + g = path_graph(4) + + @test similar_dataless_graph(g) isa SimpleGraph + @test similar_dataless_graph(SimpleDiGraph(4)) isa SimpleDiGraph + @test similar_dataless_graph(g) == g + + @test similar_dataless_graph(SimpleDiGraph(4), 2) isa SimpleDiGraph + @test similar_dataless_graph(g, vertices(g)) == typeof(g)(4) + @test isempty(edges(similar_dataless_graph(g, vertices(g)))) # add_edge g = SimpleGraph(4) @@ -539,6 +550,11 @@ using Test: @test, @test_broken, @test_throws, @testset @test only(next_nearest_neighbors(g, 1)) == 3 @test issetequal(vertices_at_distance(g, 5, 3), [2, 8]) + g = NamedGraph(path_graph(2)) + @test forest_cover_edge_sequence(g; root_vertex = (g) -> 1) == + [NamedEdge(2, 1), NamedEdge(1, 2)] + @test forest_cover_edge_sequence(g; root_vertex = (g) -> 2) == + [NamedEdge(1, 2), NamedEdge(2, 1)] @testset "arrange" begin @testset "is_arranged, is_edge_arranged" begin for (a, b) in [ diff --git a/src/lib/PartitionedGraphs/src/partitionedgraph.jl b/src/lib/PartitionedGraphs/src/partitionedgraph.jl index 79278ec7..66c420d8 100644 --- a/src/lib/PartitionedGraphs/src/partitionedgraph.jl +++ b/src/lib/PartitionedGraphs/src/partitionedgraph.jl @@ -122,9 +122,7 @@ function Graphs.rem_vertex!(pg::PartitionedGraph{V}, vertex::V) where {V} rem_vertex!(pg.graph, vertex) # If the super-vertex is now empty, remove it from the quotient graph - if !haskey(pg.partitioned_vertices, qv) - rem_vertex!(pg.quotient_graph, qv) - end + qv ∈ keys(pg.partitioned_vertices) || rem_vertex!(pg.quotient_graph, qv) return pg end diff --git a/src/lib/PartitionedGraphs/src/quotientvertex.jl b/src/lib/PartitionedGraphs/src/quotientvertex.jl index a795cab1..6e74c5a2 100644 --- a/src/lib/PartitionedGraphs/src/quotientvertex.jl +++ b/src/lib/PartitionedGraphs/src/quotientvertex.jl @@ -79,7 +79,9 @@ function Graphs.vertices(g::AbstractGraph, quotientvertex::QuotientVertex) qv = parent(quotientvertex) pvs = partitioned_vertices(g) - haskey(pvs, qv) || throw(ArgumentError("Quotient vertex $quotientvertex not in graph")) + + # Can't use `haskey` since it is not defined on vectors. + qv ∈ keys(pvs) || throw(ArgumentError("Quotient vertex $quotientvertex not in graph")) return pvs[qv] end @@ -88,7 +90,8 @@ function Graphs.vertices(g::AbstractGraph, quotientvertices::QuotientVertices) end function has_quotientvertex(g::AbstractGraph, quotientvertex::QuotientVertex) - return haskey(partitioned_vertices(g), parent(quotientvertex)) + # Can't use `haskey` since it is not defined on vectors. + return parent(quotientvertex) ∈ keys(partitioned_vertices(g)) end Graphs.nv(g::AbstractGraph, sv::QuotientVertex) = length(vertices(g, sv)) diff --git a/src/namedgraph.jl b/src/namedgraph.jl index a20c152f..66e96463 100644 --- a/src/namedgraph.jl +++ b/src/namedgraph.jl @@ -1,5 +1,5 @@ -using .GraphsExtensions: - GraphsExtensions, directed_graph_type, undirected_graph_type, vertextype +using .GraphsExtensions: GraphsExtensions, directed_graph_type, similar_graph, + similar_simplegraph, undirected_graph_type, vertextype using .OrderedDictionaries: OrderedDictionaries, OrderedIndices using .OrdinalIndexing: th using Dictionaries: Dictionary @@ -123,7 +123,7 @@ end # function GenericNamedGraph{V, G}(vertices) where {V, G <: AbstractSimpleGraph{Int}} - return GenericNamedGraph(G(length(to_vertices(vertices))), vertices) + return GenericNamedGraph{V, G}(G(length(to_vertices(vertices))), vertices) end function GenericNamedGraph{V}(vertices) where {V} @@ -209,7 +209,10 @@ end const NamedGraph{V} = GenericNamedGraph{V, SimpleGraph{Int}} const NamedDiGraph{V} = GenericNamedGraph{V, SimpleDiGraph{Int}} -function similar_graph( +function GraphsExtensions.similar_graph(graph::GenericNamedGraph, nv::Int) + return similar_simplegraph(graph, nv) +end +function GraphsExtensions.similar_graph( ::GenericNamedGraph{<:Any, G}, vertices ) where {G} @@ -219,4 +222,6 @@ function similar_graph( return graph::GenericNamedGraph{V, G} end -similar_graph(T::Type{<:GenericNamedGraph}, vertices) = T(vertices) +function GraphsExtensions.similar_graph(T::Type{<:GenericNamedGraph}, vertices) + return T(vertices) +end diff --git a/src/similar_graph.jl b/src/similar_graph.jl new file mode 100644 index 00000000..d91b8b3c --- /dev/null +++ b/src/similar_graph.jl @@ -0,0 +1,58 @@ +using .GraphsExtensions: rem_edges, rem_vertices, similar_graph, similar_simplegraph +using SimpleTraits: SimpleTraits, @traitfn, Not + +# =================================== `similar_graph` ==================================== # + +function GraphsExtensions.similar_graph(graph::AbstractNamedGraph, vertices) + return similar_namedgraph(graph, vertices) +end + +@traitfn function similar_namedgraph( + graph::AbstractGraph::(!IsDirected), + vertices + ) + V = eltype(vertices) + return NamedGraph{V}(vertices) +end +@traitfn function similar_namedgraph( + graph::AbstractGraph::IsDirected, + vertices + ) + V = eltype(vertices) + return NamedDiGraph{V}(vertices) +end + +similar_namedgraph(g::AbstractGraph, nv::Int) = similar_simplegraph(g, nv) +similar_namedgraph(g::AbstractGraph, ::Base.OneTo) = similar_graph(g, collect(vertices)) + +# Passing a type as a first argument attempts to call a constructor. Should be overloaded +# if the constructor doesnt exist for a given `AbstractGraph` concrete type. +function GraphsExtensions.similar_graph(T::Type{<:AbstractNamedGraph}) + return similar_graph(T, vertextype(T)[]) +end + +# =============================== `similar_dataless_graph` =============================== # +# This function behaves much the same as `similar_graph`, but should strictly return a +# a similar graph type that has no notion of data (in the abstract sense). + +function GraphsExtensions.similar_dataless_graph(graph::AbstractNamedGraph, vertices) + return similar_dataless_namedgraph(graph, vertices) +end + +@traitfn function similar_dataless_namedgraph( + graph::AbstractNamedGraph::(!IsDirected), + vertices + ) + return NamedGraph(vertices) +end + +@traitfn function similar_dataless_namedgraph( + graph::AbstractNamedGraph::IsDirected, + vertices + ) + return NamedDiGraph(vertices) +end + +function similar_dataless_namedgraph(graph::AbstractNamedGraph, nv::Int) + return GraphsExtensions.similar_dataless_simplegraph(graph, nv) +end diff --git a/test/test_abstractnamedgraph.jl b/test/test_abstractnamedgraph.jl index ebdb9af2..62f8eed9 100644 --- a/test/test_abstractnamedgraph.jl +++ b/test/test_abstractnamedgraph.jl @@ -1,11 +1,11 @@ @eval module $(gensym()) using Dictionaries: Dictionary -using Graphs: Graphs, AbstractGraph, DiGraph, Graph, a_star, add_edge!, edges, edgetype, - grid, has_edge, has_vertex, ne, nv, rem_edge!, vertices -using NamedGraphs.GraphsExtensions: GraphsExtensions, rename_vertices +using Graphs: Graphs, AbstractGraph, DiGraph, Graph, SimpleDiGraph, SimpleGraph, a_star, + add_edge!, edges, edgetype, grid, has_edge, has_vertex, ne, nv, rem_edge!, vertices +using NamedGraphs.GraphsExtensions: GraphsExtensions, edgeless_graph, empty_graph, + rename_vertices, similar_dataless_graph, similar_graph using NamedGraphs.NamedGraphGenerators: named_grid, named_path_graph -using NamedGraphs: NamedGraphs, AbstractNamedGraph, NamedDiGraph, NamedGraph, - edgeless_graph, empty_graph, position_graph, similar_graph +using NamedGraphs: NamedGraphs, AbstractNamedGraph, NamedDiGraph, NamedGraph, position_graph using Test: @test, @testset struct TestGraph{V} <: AbstractNamedGraph{V} @@ -192,6 +192,11 @@ end @test isempty(edges(similar_graph(g, vertices(g)))) @test isempty(edges(similar_graph(typeof(g), vertices(g)))) + @test similar_graph(g, 2) isa SimpleGraph + @test nv(similar_graph(g, 2)) == 2 + @test similar_graph(NamedDiGraph([1, 2]), 2) isa SimpleDiGraph + @test nv(similar_graph(NamedDiGraph([1, 2]), 2)) == 2 + @test nv(empty_graph(ug)) == 0 @test ne(empty_graph(ug)) == 0 @@ -201,6 +206,24 @@ end # Make sure the TestGraph is unchanged. @test nv(g) == 4 @test ne(g) == 3 + + # similar_dataless_graph + g = named_path_graph(4) + + @test similar_dataless_graph(g) isa NamedGraph + @test similar_dataless_graph(g) == g + @test similar_dataless_graph(NamedDiGraph([1, 2, 3])) isa NamedDiGraph + + @test similar_dataless_graph(g, vertices(g)) == typeof(g)(4) + @test isempty(edges(similar_dataless_graph(g, vertices(g)))) + + sdg = similar_dataless_graph(g, 2) + @test sdg isa SimpleGraph + @test nv(sdg) == 2 + + sdg = similar_dataless_graph(NamedDiGraph([1, 2, 3]), vertices(g)) + @test similar_dataless_graph(sdg, [1, 2]) isa NamedDiGraph + @test similar_dataless_graph(sdg, 2) isa SimpleDiGraph end end diff --git a/test/test_partitionedgraph.jl b/test/test_partitionedgraph.jl index 9d361ce6..3083f879 100644 --- a/test/test_partitionedgraph.jl +++ b/test/test_partitionedgraph.jl @@ -144,6 +144,10 @@ end @testset "Test Partitioned Graph Subgraph Functionality" begin n, z = 12, 4 g = NamedGraph(random_regular_graph(n, z)) + + # test trivial case + @test g[QuotientVertex(1)] == g + partitions = dictionary( [ 1 => [1, 2, 3], 2 => [4, 5, 6], 3 => [7, 8, 9], 4 => [10, 11, 12], diff --git a/test/test_trees_and_forests.jl b/test/test_trees_and_forests.jl index f88b3062..da6cd823 100644 --- a/test/test_trees_and_forests.jl +++ b/test/test_trees_and_forests.jl @@ -1,6 +1,7 @@ @eval module $(gensym()) using Graphs: connected_components, edges, is_tree, vertices -using NamedGraphs.GraphsExtensions: GraphsExtensions, all_edges, forest_cover, spanning_tree +using NamedGraphs.GraphsExtensions: + GraphsExtensions, all_edges, forest_cover, spanning_tree, vertextype using NamedGraphs.NamedGraphGenerators: named_comb_tree, named_grid, named_hexagonal_lattice_graph, named_triangular_lattice_graph using NamedGraphs: NamedGraph, Vertices