Skip to content
This repository has been archived by the owner on Oct 8, 2021. It is now read-only.

Commit

Permalink
Merge pull request #36 from JuliaGraphs/sbromberger/reverse
Browse files Browse the repository at this point in the history
adds reverse() for MetaDiGraphs
  • Loading branch information
sbromberger authored Apr 6, 2018
2 parents d706aa9 + 9eb70ed commit 13974b0
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 7 deletions.
17 changes: 10 additions & 7 deletions src/MetaGraphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import LightGraphs:
has_vertex, has_edge, inneighbors, outneighbors,
weights, indegree, outdegree, degree,
induced_subgraph,
loadgraph, savegraph, AbstractGraphFormat
loadgraph, savegraph, AbstractGraphFormat,
reverse

import LightGraphs.SimpleGraphs:
AbstractSimpleGraph, SimpleGraph, SimpleDiGraph,
Expand All @@ -41,7 +42,8 @@ export
filter_edges,
filter_vertices,
MGFormat,
set_indexing_prop!
set_indexing_prop!,
reverse

const PropDict = Dict{Symbol,Any}
const MetaDict = Dict{Symbol,Dict{Any,Integer}}
Expand Down Expand Up @@ -318,7 +320,7 @@ rem_prop!(g::AbstractMetaGraph{T}, u::Integer, v::Integer, prop::Symbol) where T
Provides a default index value for a vertex if no value currently exists. The default is a string: "\$prop\$i" where `prop` is the property name and `i` is the vertex number. If some other vertex already has this name, a randomized string is generated (though the way it is generated is deterministic).
"""
function default_index_value(v::Integer, prop::Symbol, index_values::Set{Any}; exclude = nothing)
function default_index_value(v::Integer, prop::Symbol, index_values::Set{Any}; exclude=nothing)
val = string(prop) * string(v)
if in(val, index_values) || val == exclude
srand(v + hash(prop))
Expand All @@ -337,16 +339,16 @@ are already set, each vertex must have unique values. Optionally, set the index
`val` for vertex `v`. Any vertices without values will be set to a default
("(prop)(v)").
"""
function set_indexing_prop!(g::AbstractMetaGraph, prop::Symbol; exclude = nothing)
function set_indexing_prop!(g::AbstractMetaGraph, prop::Symbol; exclude=nothing)
in(prop, g.indices) && return g.indices
index_values = [g.vprops[v][prop] for v in keys(g.vprops) if haskey(g.vprops[v], prop)]
length(index_values) != length(union(index_values)) && error("Cannot make $prop an index, duplicate values detected")
index_values = Set(index_values)

g.metaindex[prop] = Dict{Any,Integer}()
for v in 1:size(g)[1]
for v in vertices(g)
if !haskey(g.vprops, v) || !haskey(g.vprops[v], prop)
val = default_index_value(v, prop, index_values, exclude = exclude)
val = default_index_value(v, prop, index_values, exclude=exclude)
set_prop!(g, v, prop, val)
end
g.metaindex[prop][g.vprops[v][prop]] = v
Expand All @@ -356,7 +358,7 @@ function set_indexing_prop!(g::AbstractMetaGraph, prop::Symbol; exclude = nothin
end

function set_indexing_prop!(g::AbstractMetaGraph, v::Integer, prop::Symbol, val::Any)
!in(prop, g.indices) && set_indexing_prop!(g, prop, exclude = val)
!in(prop, g.indices) && set_indexing_prop!(g, prop, exclude=val)
(haskey(g.metaindex[prop], val) && g.vprops[v][prop] == val) && return g.indices
haskey(g.metaindex[prop], val) && error("':$prop' index already contains $val")

Expand Down Expand Up @@ -508,4 +510,5 @@ copy(g::T) where T <: AbstractMetaGraph = deepcopy(g)
include("metagraph.jl")
include("metadigraph.jl")
include("persistence.jl")
include("overrides.jl")
end # module
32 changes: 32 additions & 0 deletions src/overrides.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
function reverse(mg::MetaDiGraph{T,U}) where T <: Integer where U <: Real
rg = reverse(mg.graph)
map = nv(mg):-1:1
rvprops = Dict{T,PropDict}()
reprops = Dict{SimpleEdge{T},PropDict}()
rgprops = mg.gprops
rweightfield = mg.weightfield
rdefaultweight = mg.defaultweight
rindices = mg.indices

for v in keys(mg.vprops)
rvprops[map[v]] = mg.vprops[v]
end

for e in keys(mg.eprops)
reprops[reverse(e)] = mg.eprops[e]
end

rmg = MetaDiGraph(rg,
rvprops,
reprops,
rgprops,
rweightfield,
rdefaultweight,
MetaDict(),
Set{Symbol}())
for p in mg.indices
set_indexing_prop!(rmg, p)
end

return rmg
end
19 changes: 19 additions & 0 deletions test/metagraphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -401,5 +401,24 @@ end

@test_throws ErrorException G[:not_a_key]
@test_throws ErrorException dG[:not_a_key]
end

@testset "Overrides" begin
mga = MetaDiGraph(PathDiGraph(4), 8)
set_prop!(mga, 1, 2, :name, "1, 2")
set_prop!(mga, 2, 3, :name, "2, 3")
set_prop!(mga, 3, 4, :name, "3, 4")
set_indexing_prop!(mga, 1, :foo, "v1")
set_indexing_prop!(mga, 2, :foo, "v2")
set_indexing_prop!(mga, 3, :foo, "v3")
set_indexing_prop!(mga, 4, :foo, "v4")

rmg = reverse(mga)
@test props(rmg, 1)[:foo] == rmg[1, :foo] == mga[4, :foo] == "v4"
@test props(rmg, 2, 1) == props(mga, 1, 2)
@test props(rmg, 3, 2) == props(mga, 2, 3)
@test weightfield(rmg) == weightfield(mga) == :weight
@test defaultweight(rmg) == defaultweight(mga) == 8
end


0 comments on commit 13974b0

Please sign in to comment.