diff --git a/src/SimpleGraphs/generators/randgraphs.jl b/src/SimpleGraphs/generators/randgraphs.jl index 7f7df1067..5c7d82fa0 100644 --- a/src/SimpleGraphs/generators/randgraphs.jl +++ b/src/SimpleGraphs/generators/randgraphs.jl @@ -5,6 +5,23 @@ using Statistics: mean using LightGraphs: getRNG, sample! +""" + SimpleGraph{T}(nv, ne; seed=-1) + +Construct a random `SimpleGraph{T}` with `nv` vertices and `ne` edges. +The graph is sampled uniformly from all such graphs. +If `seed >= 0`, a random generator is seeded with this value. +If not specified, the element type `T` is the type of `nv`. + +### See also +[`erdos_renyi`](@ref) + +## Examples +```jldoctest +julia> SimpleGraph(5, 7) +{5, 7} undirected simple Int64 graph +``` +""" function SimpleGraph{T}(nv::Integer, ne::Integer; seed::Int=-1) where T <: Integer tnv = T(nv) maxe = div(Int(nv) * (nv - 1), 2) @@ -25,6 +42,23 @@ end SimpleGraph(nv::T, ne::Integer; seed::Int=-1) where T <: Integer = SimpleGraph{T}(nv, ne, seed=seed) +""" + SimpleDiGraph{T}(nv, ne; seed=-1) + +Construct a random `SimpleDiGraph{T}` with `nv` vertices and `ne` edges. +The graph is sampled uniformly from all such graphs. +If `seed >= 0`, a random generator is seeded with this value. +If not specified, the element type `T` is the type of `nv`. + +### See also +[`erdos_renyi`](@ref) + +## Examples +```jldoctest +julia> SimpleDiGraph(5, 7) +{5, 7} directed simple Int64 graph +``` +""" function SimpleDiGraph{T}(nv::Integer, ne::Integer; seed::Int=-1) where T <: Integer tnv = T(nv) maxe = Int(nv) * (nv - 1) @@ -878,6 +912,14 @@ function make_edgestream(sbm::StochasticBlockModel) return Channel(edges, ctype=SimpleEdge, csize=32) end +""" + SimpleGraph{T}(nv, ne, edgestream::Channel) + +Construct a `SimpleGraph{T}` with `nv` vertices and `ne` edges from `edgestream`. +Can result in less than `ne` edges if the channel `edgestream` is closed prematurely. +Duplicate edges are only counted once. +The element type is the type of `nv`. +""" function SimpleGraph(nvg::Integer, neg::Integer, edgestream::Channel) g = SimpleGraph(nvg) # println(g) @@ -889,6 +931,13 @@ function SimpleGraph(nvg::Integer, neg::Integer, edgestream::Channel) return g end +""" + SimpleGraph{T}(nv, ne, smb::StochasticBlockModel) + +Construct a random `SimpleGraph{T}` with `nv` vertices and `ne` edges. +The graph is sampled according to the stochastic block model `smb`. +The element type is the type of `nv`. +""" SimpleGraph(nvg::Integer, neg::Integer, sbm::StochasticBlockModel) = SimpleGraph(nvg, neg, make_edgestream(sbm)) diff --git a/src/SimpleGraphs/simpledigraph.jl b/src/SimpleGraphs/simpledigraph.jl index 7057dad8f..1defda9b0 100644 --- a/src/SimpleGraphs/simpledigraph.jl +++ b/src/SimpleGraphs/simpledigraph.jl @@ -15,21 +15,66 @@ end eltype(x::SimpleDiGraph{T}) where T = T # DiGraph{UInt8}(6), DiGraph{Int16}(7), DiGraph{Int8}() +""" + SimpleDiGraph{T}(n=0) + +Construct a `SimpleDiGraph{T}` with `n` vertices and 0 edges. +If not specified, the element type `T` is the type of `n`. + +## Examples +```jldoctest +julia> SimpleDiGraph(UInt8(10)) +{10, 0} directed simple UInt8 graph +``` +""" function SimpleDiGraph{T}(n::Integer=0) where T <: Integer fadjlist = [Vector{T}() for _ = one(T):n] badjlist = [Vector{T}() for _ = one(T):n] return SimpleDiGraph(0, fadjlist, badjlist) end -# SimpleDiGraph() -SimpleDiGraph() = SimpleDiGraph{Int}() - # SimpleDiGraph(6), SimpleDiGraph(0x5) SimpleDiGraph(n::T) where T <: Integer = SimpleDiGraph{T}(n) +# SimpleDiGraph() +SimpleDiGraph() = SimpleDiGraph{Int}() + # SimpleDiGraph(UInt8) +""" + SimpleDiGraph(::Type{T}) + +Construct an empty `SimpleDiGraph{T}` with 0 vertices and 0 edges. + +## Examples +```jldoctest +julia> SimpleDiGraph(UInt8) +{0, 0} directed simple UInt8 graph +``` +""" SimpleDiGraph(::Type{T}) where T <: Integer = SimpleDiGraph{T}(zero(T)) + +# SimpleDiGraph(adjmx) +""" + SimpleDiGraph{T}(adjm::AbstractMatrix) + +Construct a `SimpleDiGraph{T}` from the adjacency matrix `adjm`. +If `adjm[i][j] != 0`, an edge `(i, j)` is inserted. `adjm` must be a square matrix. +The element type `T` can be omitted. + +## Examples +```jldoctest +julia> A1 = [false true; false false] +julia> SimpleDiGraph(A1) +{2, 1} directed simple Int64 graph + +julia> A2 = [2 7; 5 0] +julia> SimpleDiGraph{Int16}(A2) +{2, 3} directed simple Int16 graph +``` +""" +SimpleDiGraph(adjmx::AbstractMatrix) = SimpleDiGraph{Int}(adjmx) + # sparse adjacency matrix constructor: SimpleDiGraph(adjmx) function SimpleDiGraph{T}(adjmx::SparseMatrixCSC{U}) where T <: Integer where U <: Real dima, dimb = size(adjmx) @@ -61,10 +106,21 @@ function SimpleDiGraph{T}(adjmx::AbstractMatrix{U}) where T <: Integer where U < return g end -# SimpleDiGraph(adjmx) -SimpleDiGraph(adjmx::AbstractMatrix) = SimpleDiGraph{Int}(adjmx) - # converts DiGraph{Int} to DiGraph{Int32} +""" + SimpleDiGraph{T}(g::SimpleDiGraph) + +Construct a copy of g. +If the element type `T` is specified, the vertices of `g` are converted to this type. +Otherwise the element type is the same as for `g`. + +## Examples +```jldoctest +julia> g = CompleteDiGraph(5) +julia> SimpleDiGraph{UInt8}(g) +{5, 20} directed simple UInt8 graph +``` +""" function SimpleDiGraph{T}(g::SimpleDiGraph) where T <: Integer h_fadj = [Vector{T}(x) for x in fadj(g)] h_badj = [Vector{T}(x) for x in badj(g)] @@ -74,6 +130,19 @@ end SimpleDiGraph(g::SimpleDiGraph) = copy(g) # constructor from abstract graph: SimpleDiGraph(graph) +""" + SimpleDiGraph(g::AbstractSimpleGraph) + +Construct an directed `SimpleDiGraph` from a graph `g`. +The element type is the same as for `g`. + +## Examples +```jldoctest +julia> g = PathGraph(Int8(5)) +julia> SimpleDiGraph(g) +{5, 8} directed simple Int8 graph +``` +""" function SimpleDiGraph(g::AbstractSimpleGraph) h = SimpleDiGraph(nv(g)) h.ne = ne(g) * 2 - num_self_loops(g) @@ -100,6 +169,28 @@ end return neg end +""" + SimpleDiGraph(edge_list::Vector) + +Construct a `SimpleDiGraph` from a vector of edges. +The element type is taken from the edges in `edge_list`. +The number of vertices is the highest that is used in an edge in `edge_list`. + +### Implementation Notes +This constructor works the fastest when `edge_list` is sorted +by the lexical ordering and does not contain any duplicates. + +### See also +[`SimpleDiGraphFromIterator`](@ref) + +## Examples +```jldoctest + +julia> el = Edge.([ (1, 3), (1, 5), (3, 1) ]) +julia> SimpleDiGraph(el) +{5, 3} directed simple Int64 graph +``` +""" function SimpleDiGraph(edge_list::Vector{SimpleDiGraphEdge{T}}) where T <: Integer nvg = zero(T) @inbounds( diff --git a/src/SimpleGraphs/simplegraph.jl b/src/SimpleGraphs/simplegraph.jl index 05f7dbc0e..32978f208 100644 --- a/src/SimpleGraphs/simplegraph.jl +++ b/src/SimpleGraphs/simplegraph.jl @@ -13,23 +13,64 @@ end eltype(x::SimpleGraph{T}) where T = T # Graph{UInt8}(6), Graph{Int16}(7), Graph{UInt8}() +""" + SimpleGraph{T}(n=0) + +Construct a `SimpleGraph{T}` with `n` vertices and 0 edges. +If not specified, the element type `T` is the type of `n`. + +## Examples +```jldoctest +julia> SimpleGraph(UInt8(10)) +{10, 0} undirected simple UInt8 graph +``` +""" function SimpleGraph{T}(n::Integer=0) where T <: Integer fadjlist = [Vector{T}() for _ = one(T):n] return SimpleGraph{T}(0, fadjlist) end +# SimpleGraph(6), SimpleGraph(0x5) +SimpleGraph(n::T) where T <: Integer = SimpleGraph{T}(n) + # SimpleGraph() SimpleGraph() = SimpleGraph{Int}() -# SimpleGraph of a SimpleGraph -SimpleGraph(g::SimpleGraph) = copy(g) +# SimpleGraph(UInt8) +""" + SimpleGraph(::Type{T}) -# SimpleGraph(6), SimpleGraph(0x5) -SimpleGraph(n::T) where T <: Integer = SimpleGraph{T}(n) +Construct an empty `SimpleGraph{T}` with 0 vertices and 0 edges. -# SimpleGraph(UInt8) +## Examples +```jldoctest +julia> SimpleGraph(UInt8) +{0, 0} undirected simple UInt8 graph +``` +""" SimpleGraph(::Type{T}) where T <: Integer = SimpleGraph{T}(zero(T)) +# SimpleGraph(adjmx) +""" + SimpleGraph{T}(adjm::AbstractMatrix) + +Construct a `SimpleGraph{T}` from the adjacency matrix `adjm`. +If `adjm[i][j] != 0`, an edge `(i, j)` is inserted. `adjm` must be a square and symmetric matrix. +The element type `T` can be omitted. + +## Examples +```jldoctest +julia> A1 = [false true; true false] +julia> SimpleGraph(A1) +{2, 1} undirected simple Int64 graph + +julia> A2 = [2 7; 7 0] +julia> SimpleGraph{Int16}(A2) +{2, 2} undirected simple Int16 graph +``` +""" +SimpleGraph(adjmx::AbstractMatrix) = SimpleGraph{Int}(adjmx) + # Graph{UInt8}(adjmx) function SimpleGraph{T}(adjmx::AbstractMatrix) where T <: Integer dima, dimb = size(adjmx) @@ -43,6 +84,23 @@ function SimpleGraph{T}(adjmx::AbstractMatrix) where T <: Integer return g end +# SimpleGraph of a SimpleGraph +""" + SimpleGraph{T}(g::SimpleGraph) + +Construct a copy of g. +If the element type `T` is specified, the vertices of `g` are converted to this type. +Otherwise the element type is the same as for `g`. + +## Examples +```jldoctest +julia> g = CompleteGraph(5) +julia> SimpleGraph{UInt8}(g) +{5, 10} undirected simple UInt8 graph +``` +""" +SimpleGraph(g::SimpleGraph) = copy(g) + # converts Graph{Int} to Graph{Int32} function SimpleGraph{T}(g::SimpleGraph) where T <: Integer h_fadj = [Vector{T}(x) for x in fadj(g)] @@ -50,10 +108,22 @@ function SimpleGraph{T}(g::SimpleGraph) where T <: Integer end -# SimpleGraph(adjmx) -SimpleGraph(adjmx::AbstractMatrix) = SimpleGraph{Int}(adjmx) # SimpleGraph(digraph) +""" + SimpleGraph(g::SimpleDiGraph) + +Construct an undirected `SimpleGraph` from a directed `SimpleDiGraph`. +Every directed edge in `g` is added as an undirected edge. +The element type is the same as for `g`. + +## Examples +```jldoctest +julia> g = PathDiGraph(Int8(5)) +julia> SimpleGraph(g) +{5, 4} undirected simple Int8 graph +``` +""" function SimpleGraph(g::SimpleDiGraph) gnv = nv(g) edgect = 0 @@ -96,6 +166,28 @@ end return neg รท 2 end +""" + SimpleGraph(edge_list::Vector) + +Construct a `SimpleGraph` from a vector of edges. +The element type is taken from the edges in `edge_list`. +The number of vertices is the highest that is used in an edge in `edge_list`. + +### Implementation Notes +This constructor works the fastest when `edge_list` is sorted +by the lexical ordering and does not contain any duplicates. + +### See also +[`SimpleGraphFromIterator`](@ref) + +## Examples +```jldoctest + +julia> el = Edge.([ (1, 2), (1, 5) ]) +julia> SimpleGraph(el) +{5, 2} undirected simple Int64 graph +``` +""" function SimpleGraph(edge_list::Vector{SimpleGraphEdge{T}}) where T <: Integer nvg = zero(T) @inbounds(