Skip to content

Graphs.jl 2.0 #258

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

Closed
wants to merge 11 commits into from
Closed
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
8 changes: 5 additions & 3 deletions src/Graphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ import Base: adjoint, write, ==, <, *, ≈, convert, isless, issubset, union, in

export
# Interface
AbstractGraph, AbstractEdge, AbstractEdgeIter,
AbstractGraph, is_vertex, AbstractVertex, AbstractEdge, AbstractWeightedEdge, AbstractEdgeIter,
Edge, Graph, SimpleGraph, SimpleGraphFromIterator, DiGraph, SimpleDiGraphFromIterator,
SimpleDiGraph, vertices, edges, edgetype, nv, ne, src, dst,
is_directed, IsDirected,
has_vertex, has_edge, inneighbors, outneighbors,
is_directed, IsDirected, is_range_based, IsRangeBased, is_simply_mutable, IsSimplyMutable,
is_mutable, IsMutable, is_weight_mutable, IsWeightMutable, is_vertex_stable, IsVertexStable,
has_vertex, has_edge, inneighbors, outneighbors, outedges, inedges,
weight, get_vertex_container, get_edge_container,

# core
is_ordered, add_vertices!, indegree, outdegree, degree,
Expand Down
22 changes: 20 additions & 2 deletions src/SimpleGraphs/SimpleGraphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import Base:

import Graphs:
_NI, AbstractGraph, AbstractEdge, AbstractEdgeIter,
src, dst, edgetype, nv, ne, vertices, edges, is_directed,
src, dst, edgetype, nv, ne, vertices, edges, outedges, inedges, is_directed,
is_simply_mutable, is_range_based,
has_vertex, has_edge, inneighbors, outneighbors, all_neighbors,
get_vertex_container, get_edge_container,
deepcopy_adjlist, indegree, outdegree, degree, has_self_loops,
num_self_loops, insorted, squash

Expand Down Expand Up @@ -48,7 +50,10 @@ An abstract type representing a simple graph structure.
- `fadjlist::Vector{Vector{Integer}}`
- `ne::Integer`
"""
abstract type AbstractSimpleGraph{T<:Integer} <: AbstractGraph{T} end

abstract type AbstractSimpleEdge{T<:Integer} <: AbstractEdge{T, Int} end

abstract type AbstractSimpleGraph{T<:Integer} <: AbstractGraph{T, AbstractSimpleEdge{T}} end

function show(io::IO, ::MIME"text/plain", g::AbstractSimpleGraph{T}) where T
dir = is_directed(g) ? "directed" : "undirected"
Expand Down Expand Up @@ -85,13 +90,24 @@ badj(x...) = _NI("badj")
# handles single-argument edge constructors such as pairs and tuples
has_edge(g::AbstractSimpleGraph, x) = has_edge(g, edgetype(g)(x))
add_edge!(g::AbstractSimpleGraph, x) = add_edge!(g, edgetype(g)(x))
@traitfn get_edges(g::AbstractSimpleGraph::IsDirected, u, v) = has_edge(g, u, v) ? [Edge(u, v)] : Edge[]
@traitfn function get_edges(g::AbstractSimpleGraph::(!IsDirected), u, v)
!has_edge(g, u, v) && return Edge[]
u < v && return [Edge(u, v)]
return [Edge(v, u)]
end

# handles two-argument edge constructors like src,dst
has_edge(g::AbstractSimpleGraph, x, y) = has_edge(g, edgetype(g)(x, y))
add_edge!(g::AbstractSimpleGraph, x, y) = add_edge!(g, edgetype(g)(x, y))

inneighbors(g::AbstractSimpleGraph, v::Integer) = badj(g, v)
outneighbors(g::AbstractSimpleGraph, v::Integer) = fadj(g, v)
outedges(g::AbstractSimpleGraph, v::Integer) = Edge.(v, outneighbors(g, v))
inedges(g::AbstractSimpleGraph, v::Integer) = Edge.(v, inneighbors(g, v))

get_vertex_container(g::AbstractSimpleGraph, K::Type) = Vector{K}(undef, nv(g))
# get_edge_container(g::AbstractGraph, K::Type) = Array{K, 2}(undef, (nv(g), nv(g))

function issubset(g::T, h::T) where T <: AbstractSimpleGraph
nv(g) <= nv(h) || return false
Expand Down Expand Up @@ -210,6 +226,8 @@ end

zero(::Type{G}) where {G<:AbstractSimpleGraph} = G()

is_range_based(::Type{<:AbstractSimpleGraph}) = true

include("./simpleedge.jl")
include("./simpledigraph.jl")
include("./simplegraph.jl")
Expand Down
34 changes: 20 additions & 14 deletions src/SimpleGraphs/simpledigraph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ function SimpleDiGraph{T}(adjmx::AbstractMatrix{U}) where T <: Integer where U <

g = SimpleDiGraph(T(dima))
@inbounds for i in findall(adjmx .!= zero(U))
add_edge!(g, i[1], i[2])
add_edge!(g, i[1], i[2])
end
return g
end
Expand Down Expand Up @@ -214,9 +214,9 @@ function SimpleDiGraph(edge_list::Vector{SimpleDiGraphEdge{T}}) where T <: Integ
nvg = zero(T)
@inbounds(
for e in edge_list
nvg = max(nvg, src(e), dst(e))
nvg = max(nvg, src(e), dst(e))
end)

list_sizes_out = ones(Int, nvg)
list_sizes_in = ones(Int, nvg)
degs_out = zeros(Int, nvg)
Expand All @@ -228,7 +228,7 @@ function SimpleDiGraph(edge_list::Vector{SimpleDiGraphEdge{T}}) where T <: Integ
degs_out[s] += 1
degs_in[d] += 1
end)

fadjlist = Vector{Vector{T}}(undef, nvg)
badjlist = Vector{Vector{T}}(undef, nvg)
@inbounds(
Expand All @@ -241,9 +241,9 @@ function SimpleDiGraph(edge_list::Vector{SimpleDiGraphEdge{T}}) where T <: Integ
for e in edge_list
s, d = src(e), dst(e)
(s >= 1 && d >= 1) || continue
fadjlist[s][list_sizes_out[s]] = d
fadjlist[s][list_sizes_out[s]] = d
list_sizes_out[s] += 1
badjlist[d][list_sizes_in[d]] = s
badjlist[d][list_sizes_in[d]] = s
list_sizes_in[d] += 1
end)

Expand Down Expand Up @@ -286,8 +286,8 @@ function _SimpleDiGraphFromIterator(iter)::SimpleDiGraph

T = eltype(e)
g = SimpleDiGraph{T}()
fadjlist = Vector{Vector{T}}()
badjlist = Vector{Vector{T}}()
fadjlist = Vector{Vector{T}}()
badjlist = Vector{Vector{T}}()

while next != nothing
(e, state) = next
Expand All @@ -314,8 +314,8 @@ end
function _SimpleDiGraphFromIterator(iter, ::Type{T}) where {T <: Integer}

g = SimpleDiGraph{T}()
fadjlist = Vector{Vector{T}}()
badjlist = Vector{Vector{T}}()
fadjlist = Vector{Vector{T}}()
badjlist = Vector{Vector{T}}()

@inbounds(
for e in iter
Expand Down Expand Up @@ -433,14 +433,14 @@ function rem_edge!(g::SimpleDiGraph{T}, e::SimpleDiGraphEdge{T}) where T
s, d = T.(Tuple(e))
verts = vertices(g)
(s in verts && d in verts) || return false # edge out of bounds
@inbounds list = g.fadjlist[s]
@inbounds list = g.fadjlist[s]
index = searchsortedfirst(list, d)
@inbounds (index <= length(list) && list[index] == d) || return false # edge not in graph
deleteat!(list, index)

g.ne -= 1

@inbounds list = g.badjlist[d]
@inbounds list = g.badjlist[d]
index = searchsortedfirst(list, s)
deleteat!(list, index)
return true # edge successfully removed
Expand Down Expand Up @@ -484,7 +484,7 @@ function rem_vertices!(g::SimpleDiGraph{T},
end
end
else
# traverse the vertex list and replace vertices that get removed
# traverse the vertex list and replace vertices that get removed
# with the furthest one to the back that does not get removed
i = 1
j = length(remove)
Expand Down Expand Up @@ -580,7 +580,7 @@ function all_neighbors(g::SimpleDiGraph{T}, u::Integer) where T
elseif in_nbrs[i] > out_nbrs[j]
union_nbrs[indx] = out_nbrs[j]
j += 1
else
else
union_nbrs[indx] = out_nbrs[j]
i += 1
j += 1
Expand All @@ -600,3 +600,9 @@ function all_neighbors(g::SimpleDiGraph{T}, u::Integer) where T
resize!(union_nbrs, indx-1)
return union_nbrs
end

# defining the Traits
is_simply_mutable(::Type{<:SimpleDiGraph}) = true
is_mutable(::Type{<:SimpleDiGraph}) = true
is_weight_mutable(::Type{<:SimpleDiGraph}) = false
is_vertex_stable(::Type{<:SimpleDiGraph}) = false
5 changes: 2 additions & 3 deletions src/SimpleGraphs/simpleedge.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import Base: Pair, Tuple, show, ==, hash
import Graphs: AbstractEdge, src, dst, reverse

abstract type AbstractSimpleEdge{T<:Integer} <: AbstractEdge{T} end
import Graphs: src, dst, reverse

struct SimpleEdge{T<:Integer} <: AbstractSimpleEdge{T}
src::T
Expand Down Expand Up @@ -30,5 +28,6 @@ SimpleEdge{T}(e::AbstractSimpleEdge) where T <: Integer = SimpleEdge{T}(T(e.src)

# Convenience functions
reverse(e::T) where T<:AbstractSimpleEdge = T(dst(e), src(e))
isless(e1::AbstractSimpleEdge, e2::AbstractSimpleEdge) = isless(Tuple(e1), Tuple(e2))
==(e1::AbstractSimpleEdge, e2::AbstractSimpleEdge) = (src(e1) == src(e2) && dst(e1) == dst(e2))
hash(e::AbstractSimpleEdge, h::UInt) = hash(src(e), hash(dst(e), h))
6 changes: 6 additions & 0 deletions src/SimpleGraphs/simplegraph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -671,3 +671,9 @@ function rem_vertices!(g::SimpleGraph{T},

return reverse_vmap
end

# defining the Traits
is_simply_mutable(::Type{<:SimpleGraph}) = true
is_mutable(::Type{<:SimpleGraph}) = true
is_weight_mutable(::Type{<:SimpleGraph}) = false
is_vertex_stable(::Type{<:SimpleGraph}) = false
Loading