Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Aqua", "Documenter", "Graphs", "JuliaFormatter", "LinearAlgebra", "Test"]
test = ["Aqua", "Documenter", "Graphs", "JuliaFormatter", "LinearAlgebra", "SparseArrays", "Test"]
48 changes: 43 additions & 5 deletions src/overrides.jl
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,50 @@ Compute the weighted subgraph induced by a list of vertices.
Return a tuple containing the new graph and the list of vertices.
"""
function Graphs.induced_subgraph(
g::T, vlist::AbstractVector{U}
) where {T<:AbstractSimpleWeightedGraph,U<:Integer}
E = eltype(g)
g::G, vlist::AbstractVector{U}
) where {G<:AbstractSimpleWeightedGraph,U<:Integer}
T = eltype(g)
allunique(vlist) || throw(ArgumentError("Vertices in subgraph list must be unique"))
new_weights = g.weights[E.(vlist), E.(vlist)]
new_weights = g.weights[T.(vlist), T.(vlist)]
newg = zero(g)
newg.weights = new_weights
return newg, Vector{E}(vlist)
return newg, Vector{T}(vlist)
end

function Graphs.induced_subgraph(
g::G, elist::AbstractVector{E}
) where {G<:AbstractSimpleWeightedGraph} where {E<:AbstractEdge}
allunique(elist) || throw(ArgumentError("Edges in subgraph list must be unique"))
T, U = eltype(g), weighttype(g)
vertex_set = Set{T}()
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 in eachindex(vertex_list))
n = length(vertex_list)
new_weights = spzeros(weighttype(g), T, n, n)
I, J, W = T[], T[], U[]
for e in elist
if has_edge(g, e)
i, j = index_map[src(e)], index_map[dst(e)]
w = get_weight(g, dst(e), src(e))
push!(I, j) # storage is transposed!
push!(J, i)
push!(W, w)
if !is_directed(g)
push!(I, i)
push!(J, j)
push!(W, w)
end
end
end
new_weights = sparse(I, J, W)
newg = G(new_weights)
return newg, vertex_list
end
30 changes: 30 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,33 @@ 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