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

Create induced subgraph from edge list #37

Merged
merged 6 commits into from
Apr 28, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/overrides.jl
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,33 @@ function Graphs.induced_subgraph(
newg.weights = new_weights
return newg, Vector{E}(vlist)
end

function induced_subgraph(g::T, elist::AbstractVector{U}) where T <: AbstractSimpleWeightedGraph where U <: AbstractEdge
gdalle marked this conversation as resolved.
Show resolved Hide resolved
allunique(elist) || throw(ArgumentError("Edges in subgraph list must be unique"))
E = eltype(g)
vertex_set = Set{E}()
@inbounds for e in elist
if has_edge(g, e)
push!(vertex_set, src(e), dst(e))
else
@warn "Skipping the edge $(e), since it does not exist in the graph!"
end
end
vertex_list = collect(vertex_set)
sort!(vertex_list)
index_map = Dict(vertex_list[i] => i for i=1:length(vertex_list))
n = length(vertex_list)
new_weights = spzeros(weighttype(g), E, E(n), E(n))
@inbounds for e in elist
if has_edge(g, e)
weights = g.weights[dst(e), src(e)]
new_weights[index_map[dst(e)], index_map[src(e)]] = weights
if !is_directed(g)
new_weights[index_map[src(e)], index_map[dst(e)]] = weights
end
end
end
newg = zero(g)
newg.weights = new_weights
return newg, Vector{edgetype(g)}(collect(edges(newg)))
end
26 changes: 26 additions & 0 deletions test/simpleweightedgraph.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using SimpleWeightedGraphs
using SparseArrays

@testset verbose = true "SimpleWeightedGraphs" begin
@info("Ignore warnings relating to adding and removing vertices and edges")
Expand Down Expand Up @@ -351,4 +352,29 @@ using SimpleWeightedGraphs
@test g[1, 3, Val{:weight}()] ≈ 0
@test g[2, 3, Val{:weight}()] ≈ 0.5
end

# this testset was implemented for https://github.com/JuliaGraphs/SimpleWeightedGraphs.jl/issues/32
@testset "induced_subgraph should preserve weights for edge lists" begin
g = SimpleWeightedGraph([0 2; 2 0])
expected_graph_weights = sparse([0 2; 2 0])
# vertex induced subgraph
vertex_induced_subgraph_weights = weights(first(induced_subgraph(g, [1, 2])))
@test vertex_induced_subgraph_weights == expected_graph_weights
# edge induced subgraph
edge_induced_subgraph_weights = weights(first(induced_subgraph(g, [Edge(1, 2)])))
@test edge_induced_subgraph_weights == expected_graph_weights

# test edge induced graph with one edge removed
# graph isomorphic to C_5
g = SimpleWeightedGraph([0 2 0 0 2; 2 0 2 0 0; 0 2 0 2 0; 0 0 2 0 2; 2 0 0 2 0])
expected_graph_weights = sparse([0 2 0 0 0; 2 0 2 0 0; 0 2 0 2 0; 0 0 2 0 2; 0 0 0 2 0]);
# create edge induced subgraph isomorphic to P_5. The edge (1, 5) is missing and test if weights are correct.
edge_induced_subgraph_weights = weights(first(induced_subgraph(g, [Edge(1, 2), Edge(2, 3), Edge(3, 4), Edge(4, 5)])))
@test edge_induced_subgraph_weights == expected_graph_weights

# test edge induced subgraph which does not contain the whole vertex set, especially remove the first column (vertex 1)
edge_induced_subgraph_weights = weights(first(induced_subgraph(g, [Edge(2, 3)])))
expected_graph_weights = sparse([0 2; 2 0])
@test edge_induced_subgraph_weights == expected_graph_weights
end
end