Skip to content

Commit

Permalink
Merge d6f6268 into 99411a7
Browse files Browse the repository at this point in the history
  • Loading branch information
alessant committed Jan 29, 2019
2 parents 99411a7 + d6f6268 commit 7570667
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/SimpleHypergraphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ using LightGraphs
export Hypergraph, getvertices, gethyperedges, hg_load, hg_save
export add_vertex!, add_hyperedge!
export BipartiteView, shortest_path
export TwoSectionView

include("hypergraph.jl")
include("bipartite.jl")
include("io.jl")
include("twosection.jl")

end # module
88 changes: 88 additions & 0 deletions src/twosection.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""
TwoSectionView{T<:Real} <: AbstractGraph{Int64}
Represents a 2-section view of a hypergraph `h`.
Note this is a view - changes to the original hypergraph will be automatically reflected in the view.
**Constructors**
TwoSectionView(::Hypergraph)
The 2-section view of a hypergraph is suitable for processing with the LightGraphs.jl package.
Several LightGraphs methods are provided for the compability.
"""
struct TwoSectionView{T<:Real} <: AbstractGraph{Int}
h::Hypergraph{T}
end

LightGraphs.nv(t::TwoSectionView) = length(t.h.v2he)

LightGraphs.vertices(t::TwoSectionView) = Base.OneTo(nv(t))

function LightGraphs.ne(t::TwoSectionView)
s = 0
for x in t.h.he2v
s += length(x) * (length(x) - 1)
end
div(s, 2)
end

"""
LightGraphs.all_neighbors(t::TwoSectionView, v::Integer)
Returns N(v) (the vertex v is not included in N(v))
"""
function LightGraphs.all_neighbors(t::TwoSectionView, v::Integer)
neighbors = Set{Int}()
for he in keys(t.h.v2he[v])
union!(neighbors, keys(t.h.he2v[he]))
end
delete!(neighbors, v) #remove v from its neighborhood
collect(neighbors) #returns the corresponding array
end

function LightGraphs.has_edge(t::TwoSectionView, s, d)
!isempty(intersect(keys(t.h.v2he[s]), keys(t.h.v2he[d])))
end

LightGraphs.outneighbors(t::TwoSectionView, v::Integer) = LightGraphs.all_neighbors(t::TwoSectionView, v)

LightGraphs.inneighbors(t::TwoSectionView, v::Integer) = LightGraphs.all_neighbors(t::TwoSectionView, v)

"""
LightGraphs.SimpleGraph(t::TwoSectionView)
Creates a `LightGraphs.SimpleGraph` representation of a `TwoSectionView` t.
This creates a copy of the date. Note that the weights information is not stored
in the created `SimpleGraph`.
"""
function LightGraphs.SimpleGraph(t::TwoSectionView)
g = SimpleGraph(nv(t))
for v in LightGraphs.vertices(t)
neighbors_v = LightGraphs.all_neighbors(t, v)
for neighbor in neighbors_v
add_edge!(g, v, neighbor)
end
end
g
end

LightGraphs.is_directed(t::TwoSectionView) = false

"""
shortest_path(t::TwoSectionView,source::Int, target::Int)
Finds a single shortest path in a graph `b` between vertices
`source` and `target`.
Note that if several paths of the same length exist, only one
will be returned.
"""
function shortest_path(t::TwoSectionView, source::Int, target::Int)
checkbounds(t.h.v2he, source)
checkbounds(t.h.v2he, target)
dj = dijkstra_shortest_paths(t, source)
enumerate_paths(dj)[target]
end
30 changes: 30 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,33 @@ h1[5,5] = 1
h1[6,5] = 1

@test shortest_path(b,1,6) == [1,3,5,6]


#TwoSectionView test
t = TwoSectionView(h1)

@test LightGraphs.nv(t) == 6
@test LightGraphs.ne(t) == 8

@test sort(LightGraphs.all_neighbors(t, 1)) == [2,3]
@test sort(LightGraphs.outneighbors(t, 5)) == [3,4,6]
@test sort(LightGraphs.inneighbors(t, 4)) == [2,3,5]
@inferred LightGraphs.all_neighbors(t, 1)

@test LightGraphs.has_edge(t, 1, 2) == true
@test LightGraphs.has_edge(t, 1, 5) == false

@test sum(LightGraphs.adjacency_matrix(LightGraphs.SimpleGraph(t))) == 16
@test shortest_path(t,1,5) == [1,3,5]
@test LightGraphs.is_weakly_connected(t) == true

@test SimpleHypergraphs.add_vertex!(h1) == 7
h1[7,5] = 1

@test shortest_path(t,1,6) == [1,3,5,6]

@test LightGraphs.nv(t) == 7
@test LightGraphs.ne(t) == 10
@test sort(LightGraphs.outneighbors(t, 5)) == [3,4,6,7]

@test sum(LightGraphs.adjacency_matrix(LightGraphs.SimpleGraph(t))) == 20
38 changes: 38 additions & 0 deletions test/twosectiontest.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Test, SimpleHypergraphs
import LightGraphs

h = Hypergraph{Float64}(5,4)
h[1:3,1] .= 1.5
h[3,4] = 2.5
h[2,3] = 3.5
h[4,3:4] .= 4.5
h[5,4] = 5.5
h[5,2] = 6.5

t = TwoSectionView{Float64}(h)

@test LightGraphs.nv(t) == 5
@test LightGraphs.ne(t) == 7

@test sort(LightGraphs.all_neighbors(t, 1)) == [2,3]
@test sort(LightGraphs.outneighbors(t, 5)) == [3,4]
@test sort(LightGraphs.inneighbors(t, 4)) == [2,3,5]

@test sum(LightGraphs.adjacency_matrix(LightGraphs.SimpleGraph(t))) == 14

@test shortest_path(t,1,5) == [1,3,5]

@test LightGraphs.is_weakly_connected(t) == true

@test SimpleHypergraphs.add_vertex!(h) == 6
@test add_hyperedge!(h) == 5
h[5,5] = 1
h[6,5] = 1

@test shortest_path(t,1,6) == [1,3,5,6]

@test LightGraphs.nv(t) == 6
@test LightGraphs.ne(t) == 8
@test sort(LightGraphs.outneighbors(t, 5)) == [3,4,6]

@test sum(LightGraphs.adjacency_matrix(LightGraphs.SimpleGraph(t))) == 16

0 comments on commit 7570667

Please sign in to comment.