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
8 changes: 5 additions & 3 deletions src/Graphs.jl
Original file line number Diff line number Diff line change
@@ -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,
22 changes: 20 additions & 2 deletions src/SimpleGraphs/SimpleGraphs.jl
Original file line number Diff line number Diff line change
@@ -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

@@ -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"
@@ -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
@@ -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")
34 changes: 20 additions & 14 deletions src/SimpleGraphs/simpledigraph.jl
Original file line number Diff line number Diff line change
@@ -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
@@ -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)
@@ -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(
@@ -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)

@@ -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
@@ -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
@@ -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
@@ -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)
@@ -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
@@ -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
@@ -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
@@ -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