From 2cfa5d60f1f9f235917f2b4b9c0c1b2dc26f0dfa Mon Sep 17 00:00:00 2001 From: Ed Scheinerman Date: Sun, 17 Jul 2022 14:32:16 -0400 Subject: [PATCH] Name changes --- src/SimpleGraphs.jl | 2 +- src/abbreviations.jl | 10 ++-- src/bisect.jl | 4 +- src/cache.jl | 14 +++--- src/d_dist.jl | 4 +- src/d_euler.jl | 10 ++-- src/d_ham.jl | 8 +-- src/d_simple_constructors.jl | 4 +- src/d_simple_core.jl | 89 ++++++++++++++++++---------------- src/d_simple_matrices.jl | 4 +- src/embedding/colorize.jl | 2 +- src/embedding/embedding.jl | 24 ++++----- src/embedding/getset.jl | 26 +++++----- src/embedding/graffle.jl | 6 +-- src/embedding/my_spring.jl | 2 +- src/embedding/my_stress.jl | 4 +- src/embedding/spectral.jl | 4 +- src/embedding/tikz.jl | 8 +-- src/embedding/transforms.jl | 4 +- src/embedding/tutte.jl | 4 +- src/hyper/SimpleHypergraphs.jl | 2 +- src/hyper/graph.jl | 6 +-- src/indep_poly.jl | 2 +- src/interlace.jl | 10 ++-- src/matching_poly.jl | 2 +- src/platonic.jl | 2 +- src/prufer.jl | 10 ++-- src/rotation_system.jl | 32 ++++++------ src/simple_coloring.jl | 12 ++--- src/simple_connect.jl | 36 +++++++------- src/simple_constructors.jl | 18 +++---- src/simple_core.jl | 53 ++++++++++---------- src/simple_euler.jl | 8 +-- src/simple_girth.jl | 4 +- src/simple_ham.jl | 4 +- src/simple_matrices.jl | 10 ++-- src/simple_ops.jl | 82 +++++++++++++++---------------- src/trans_orient.jl | 18 +++---- src/twins.jl | 2 +- 39 files changed, 274 insertions(+), 272 deletions(-) diff --git a/src/SimpleGraphs.jl b/src/SimpleGraphs.jl index 4a3f916..3fb5e38 100644 --- a/src/SimpleGraphs.jl +++ b/src/SimpleGraphs.jl @@ -56,6 +56,6 @@ include("embedding/embedding.jl") include("hyper/SimpleHypergraphs.jl") -include("abbreviations.jl") +# include("abbreviations.jl") end # module SimpleGraphs diff --git a/src/abbreviations.jl b/src/abbreviations.jl index 8840eb8..e15b8b7 100644 --- a/src/abbreviations.jl +++ b/src/abbreviations.jl @@ -1,13 +1,9 @@ -const UG = SimpleGraph -const DG = SimpleDigraph -# const HG = SimpleHypergraph -export UG, DG + # These names will not be necessary in versions 0.8.1 and on -const UndirectedGraph = SimpleGraph -const DirectedGraph = SimpleDigraph +const DirectedGraph = DirectedGraph const HyperGraph = HyperGraph -export UndirectedGraph, DirectedGraph, HyperGraph \ No newline at end of file +export DirectedGraph, HyperGraph \ No newline at end of file diff --git a/src/bisect.jl b/src/bisect.jl index 4ab6a6c..913e079 100644 --- a/src/bisect.jl +++ b/src/bisect.jl @@ -21,7 +21,7 @@ This can be invoked as follows: A plain call to `bisect(G)` is equivalent to `bisect(G,"zero")` (which is the same as `bisect(G,"user", 0.0)`). """ -function bisect(G::SimpleGraph, where::AbstractString = "zero", pivot::Real = 0.0) +function bisect(G::UndirectedGraph, where::AbstractString = "zero", pivot::Real = 0.0) verbose = false @@ -100,7 +100,7 @@ end one end in `A` and one end in `B`. Here `A` and `B` are collections of vertices of `G`. """ -function cross_edges(G::SimpleGraph, A, B) +function cross_edges(G::UndirectedGraph, A, B) AB = Base.Iterators.product(A, B) diff --git a/src/cache.jl b/src/cache.jl index 8bea60c..940d715 100644 --- a/src/cache.jl +++ b/src/cache.jl @@ -13,19 +13,19 @@ export cache_clear, cache_on, cache_off, cache_recall, cache_check, cache_save `cache_clear(G,item)` clears just that item. """ -function cache_clear(G::SimpleGraph) +function cache_clear(G::UndirectedGraph) if length(G.cache) > 0 G.cache = Dict{Symbol,Any}() end nothing end -cache_clear(G::SimpleGraph, item::Symbol) = delete!(G.cache, item) +cache_clear(G::UndirectedGraph, item::Symbol) = delete!(G.cache, item) """ `cache_check(G,item)` checks if the symbol `item` is a valid key. """ -cache_check(G::SimpleGraph, item::Symbol)::Bool = G.cache_flag && haskey(G.cache, item) +cache_check(G::UndirectedGraph, item::Symbol)::Bool = G.cache_flag && haskey(G.cache, item) """ `cache_recall(G,item)` retreives the value associated with `item`. @@ -33,7 +33,7 @@ cache_check(G::SimpleGraph, item::Symbol)::Bool = G.cache_flag && haskey(G.cache **WARNING**: No check is done to see if this value is defined. Be sure to use `cache_check` first! """ -cache_recall(G::SimpleGraph, item::Symbol) = G.cache[item] +cache_recall(G::UndirectedGraph, item::Symbol) = G.cache[item] @@ -41,7 +41,7 @@ cache_recall(G::SimpleGraph, item::Symbol) = G.cache[item] `cache_save(G,item,value)` saves `value` associated with the symbol (key) `item` in the cache for this graph. """ -function cache_save(G::SimpleGraph, item::Symbol, value) +function cache_save(G::UndirectedGraph, item::Symbol, value) if G.cache_flag G.cache[item] = value end @@ -51,7 +51,7 @@ end """ `cache_on(G)` activates results caching for this graph. See also: `cache_off`. """ -cache_on(G::SimpleGraph) = G.cache_flag = true +cache_on(G::UndirectedGraph) = G.cache_flag = true """ `cache_off(G)` deactivates cache checking. You may also wish to call @@ -59,6 +59,6 @@ cache_on(G::SimpleGraph) = G.cache_flag = true See also: `cache_on`. """ -function cache_off(G::SimpleGraph) +function cache_off(G::UndirectedGraph) G.cache_flag = false end diff --git a/src/d_dist.jl b/src/d_dist.jl index d3d31c5..3b75818 100644 --- a/src/d_dist.jl +++ b/src/d_dist.jl @@ -1,5 +1,5 @@ -function dist_matrix(G::SimpleDigraph) +function dist_matrix(G::DirectedGraph) VV = vlist(G) n = length(VV) A = zeros(Int, n, n) @@ -12,7 +12,7 @@ function dist_matrix(G::SimpleDigraph) return A end -function diam(G::SimpleDigraph) +function diam(G::DirectedGraph) A = dist_matrix(G) if minimum(A) < 0 return -1 diff --git a/src/d_euler.jl b/src/d_euler.jl index 58c6727..38710f8 100644 --- a/src/d_euler.jl +++ b/src/d_euler.jl @@ -1,6 +1,6 @@ export euler, is_cut_edge -function euler(G::SimpleDigraph{T}, u::T, v::T) where {T} +function euler(G::DirectedGraph{T}, u::T, v::T) where {T} notrail = T[] #check in_degrees and out_degrees of start and end vertex first if u == v @@ -25,12 +25,12 @@ function euler(G::SimpleDigraph{T}, u::T, v::T) where {T} return euler_work!(GG, u) end -euler(G::SimpleDigraph, u) = euler(G, u, u) -euler(G::SimpleDigraph) = euler(G, first(G.V)) +euler(G::DirectedGraph, u) = euler(G, u, u) +euler(G::DirectedGraph) = euler(G, first(G.V)) # determine if an edge in a directed graph is a cut edge -function is_cut_edge(G::SimpleDigraph{T}, u::T, v::T) where {T} +function is_cut_edge(G::DirectedGraph{T}, u::T, v::T) where {T} if !has(G, u, v) error("No such edge in this graph") end @@ -48,7 +48,7 @@ end # helper function to determine if there is euler path # function euler_work!(G::SimpleDigraph{T}, u::T) where {T} -function euler_work!(G::SimpleDigraph{T}, u::T) where {T} +function euler_work!(G::DirectedGraph{T}, u::T) where {T} trail = T[] while true Nu = out_neighbors(G, u) diff --git a/src/d_ham.jl b/src/d_ham.jl index 5bd3428..ee74d07 100644 --- a/src/d_ham.jl +++ b/src/d_ham.jl @@ -1,7 +1,7 @@ export hamiltonian_cycle #check if it is safe to add vertex v to the path -function isSafe(v::T, G::SimpleDigraph{T}, path::Deque{T}) where {T} +function isSafe(v::T, G::DirectedGraph{T}, path::Deque{T}) where {T} prev = last(path) #check if the added vertex is an out_neighbor of the previous vertex @@ -21,7 +21,7 @@ function isSafe(v::T, G::SimpleDigraph{T}, path::Deque{T}) where {T} return true end -function hamCycle(G::SimpleDigraph{T}, path::Deque{T}) where {T} +function hamCycle(G::DirectedGraph{T}, path::Deque{T}) where {T} #if all vertices are included in the cycle if length(path) == NV(G) #check if last vertex is connected to first vertex in path @@ -49,7 +49,7 @@ function hamCycle(G::SimpleDigraph{T}, path::Deque{T}) where {T} end #check if a directed graph contains a hamiltonian cycle -function directed_ham_cycle(G::SimpleDigraph{T}) where {T} +function directed_ham_cycle(G::DirectedGraph{T}) where {T} result = Deque{T}() vlist = collect(G.V) @@ -72,6 +72,6 @@ function directed_ham_cycle(G::SimpleDigraph{T}) where {T} end #export the result as an array -function hamiltonian_cycle(G::SimpleDigraph{T}) where {T} +function hamiltonian_cycle(G::DirectedGraph{T}) where {T} return collect(directed_ham_cycle(G)) end diff --git a/src/d_simple_constructors.jl b/src/d_simple_constructors.jl index 18aebe9..a20af90 100644 --- a/src/d_simple_constructors.jl +++ b/src/d_simple_constructors.jl @@ -118,7 +118,7 @@ function ShiftDigraph(alphabet = [0, 1], n::Int = 3) vertex_iter = all_tuples(alphabet, n) vlist = collect(vertex_iter) T = typeof(vlist[1]) - G = SimpleDigraph{T}() + G = DirectedGraph{T}() for v in vlist add!(G, v) end @@ -143,7 +143,7 @@ function for creating a Torus Graph function TorusDigraph(n::Int = 4, m::Int = 3) T = Tuple{Int,Int} - G = SimpleDigraph{T}() + G = DirectedGraph{T}() #create vertices vlist = Tuple{Int,Int}[] diff --git a/src/d_simple_core.jl b/src/d_simple_core.jl index c88cdb8..be273ad 100644 --- a/src/d_simple_core.jl +++ b/src/d_simple_core.jl @@ -1,6 +1,6 @@ # Core definitions for directed graphs -export SimpleDigraph, IntDigraph, StringDigraph +export DirectedGraph, IntDigraph, StringDigraph export is_looped, allow_loops!, forbid_loops!, remove_loops!, loops export out_deg, in_deg, deg, dual_deg export in_neighbors, out_neighbors, simplify, vertex_split @@ -11,12 +11,12 @@ export is_strongly_connected type. This can be restricted to vertics of type `T` with `SimpleDigraph{T}()`. """ -mutable struct SimpleDigraph{T} <: AbstractSimpleGraph +mutable struct DirectedGraph{T} <: AbstractSimpleGraph V::Set{T} # vertex set of this graph N::Dict{T,Set{T}} # map vertices to out-neighbors NN::Dict{T,Set{T}} # map vertices to in-neighbors looped::Bool # flag to indicate if loops are allowed - function SimpleDigraph{T}() where {T} + function DirectedGraph{T}() where {T} V = Set{T}() N = Dict{T,Set{T}}() NN = Dict{T,Set{T}}() @@ -24,11 +24,14 @@ mutable struct SimpleDigraph{T} <: AbstractSimpleGraph end end -SimpleDigraph() = SimpleDigraph{Any}() -IntDigraph() = SimpleDigraph{Int}() +const DG = DirectedGraph +export DG +DirectedGraph() = DirectedGraph{Any}() +IntDigraph() = DirectedGraph{Int}() -function show(io::IO, G::SimpleDigraph) + +function show(io::IO, G::DirectedGraph) print(io, "DirectedGraph{$(eltype(G))} (n=$(NV(G)), m=$(NE(G)))") end @@ -37,9 +40,9 @@ end `StringDigraph()` creates a new directe graph with vertices of type `String`. """ -StringDigraph() = SimpleDigraph{String}() +StringDigraph() = DirectedGraph{String}() -eltype(G::SimpleDigraph{T}) where {T} = T +eltype(G::DirectedGraph{T}) where {T} = T """ `IntDigraph()` creates a new directed graph with vertices of type @@ -62,14 +65,14 @@ end having loops. Returning `true` does not mean that digraph actually has loops. """ -is_looped(G::SimpleDigraph) = G.looped +is_looped(G::DirectedGraph) = G.looped # Grant permission for loops """ `allow_loops!(G)` enables `G` to have loops`. """ -function allow_loops!(G::SimpleDigraph) +function allow_loops!(G::DirectedGraph) G.looped = true nothing end @@ -81,7 +84,7 @@ end `remove_loops!(G)` removes all loops (if any) in the digraph, but does *not* alter the `G`'s ability to have loops. """ -function remove_loops!(G::SimpleDigraph) +function remove_loops!(G::DirectedGraph) if !G.looped return nothing end @@ -96,7 +99,7 @@ end `forbid_loops!(G)` disables the digraph's ability to have loops. It also removes any loops it may already have. """ -function forbid_loops!(G::SimpleDigraph) +function forbid_loops!(G::DirectedGraph) remove_loops!(G) G.looped = false nothing @@ -106,7 +109,7 @@ end """ `loops(G)` returns a list of vertices at which a loop is present. """ -function loops(G::SimpleDigraph{T}) where {T} +function loops(G::DirectedGraph{T}) where {T} if !is_looped(G) return T[] end @@ -132,8 +135,8 @@ end `out_deg(G)` is a sorted list of the out degrees of all vertices in the directed graph. """ -out_deg(G::SimpleDigraph, v) = length(G.N[v]) -out_deg(G::SimpleDigraph) = sort([out_deg(G, v) for v in G.V], rev = true) +out_deg(G::DirectedGraph, v) = length(G.N[v]) +out_deg(G::DirectedGraph) = sort([out_deg(G, v) for v in G.V], rev = true) # Likewise for indegrees @@ -143,12 +146,12 @@ out_deg(G::SimpleDigraph) = sort([out_deg(G, v) for v in G.V], rev = true) `in_deg(G)` is a sorted list of the in degrees of all vertices in the directed graph. """ -in_deg(G::SimpleDigraph, v) = length(G.NN[v]) -in_deg(G::SimpleDigraph) = sort([in_deg(G, v) for v in G.V], rev = true) +in_deg(G::DirectedGraph, v) = length(G.NN[v]) +in_deg(G::DirectedGraph) = sort([in_deg(G, v) for v in G.V], rev = true) # The degree of a vertex is the sum of in and out degrees -deg(G::SimpleDigraph, v) = in_deg(G, v) + out_deg(G, v) -deg(G::SimpleDigraph) = sort([deg(G, v) for v in G.V], rev = true) +deg(G::DirectedGraph, v) = in_deg(G, v) + out_deg(G, v) +deg(G::DirectedGraph) = sort([deg(G, v) for v in G.V], rev = true) # dual_deg gives the two-tuple (out,in)-degrees @@ -158,15 +161,15 @@ in degree of the vertex `v`. `dual_deg(G)` gives a list of all the dual degrees. """ -dual_deg(G::SimpleDigraph, v) = (out_deg(G, v), in_deg(G, v)) -dual_deg(G::SimpleDigraph) = sort([dual_deg(G, v) for v in G.V], rev = true) +dual_deg(G::DirectedGraph, v) = (out_deg(G, v), in_deg(G, v)) +dual_deg(G::DirectedGraph) = sort([dual_deg(G, v) for v in G.V], rev = true) # out neighbors of a vertex """ `out_neighbors(G,v)` gives a list of all `v`'s out neighbors. """ -function out_neighbors(G::SimpleDigraph, v) +function out_neighbors(G::DirectedGraph, v) result = collect(G.N[v]) try sort!(result) @@ -179,7 +182,7 @@ end """ `in_neighbors(G,v)` gives a list of all of `v`'s in neighbors. """ -function in_neighbors(G::SimpleDigraph, v) +function in_neighbors(G::DirectedGraph, v) result = collect(G.NN[v]) try sort!(result) @@ -189,7 +192,7 @@ function in_neighbors(G::SimpleDigraph, v) end # Number of edges -function NE(G::SimpleDigraph) +function NE(G::DirectedGraph) total::Int = 0 for v in G.V total += out_deg(G, v) @@ -198,10 +201,10 @@ function NE(G::SimpleDigraph) end # Check if this digraph has a given edge -has(G::SimpleDigraph, v, w) = has(G, v) && in(w, G.N[v]) +has(G::DirectedGraph, v, w) = has(G, v) && in(w, G.N[v]) # Add a vertex to a digraph -function add!(G::SimpleDigraph{T}, v) where {T} +function add!(G::DirectedGraph{T}, v) where {T} if has(G, v) return false end @@ -212,7 +215,7 @@ function add!(G::SimpleDigraph{T}, v) where {T} end # Add an edge to a digraph -function add!(G::SimpleDigraph{T}, v, w) where {T} +function add!(G::DirectedGraph{T}, v, w) where {T} if !G.looped && v == w return false end @@ -231,7 +234,7 @@ function add!(G::SimpleDigraph{T}, v, w) where {T} end # Delete an edge from this digraph -function SimpleGraphs.delete!(G::SimpleDigraph, v, w) +function SimpleGraphs.delete!(G::DirectedGraph, v, w) if !has(G, v, w) return false end @@ -241,7 +244,7 @@ function SimpleGraphs.delete!(G::SimpleDigraph, v, w) end # Delete a vertex from this digraph -function SimpleGraphs.delete!(G::SimpleDigraph, v) +function SimpleGraphs.delete!(G::DirectedGraph, v) if !has(G, v) return false end @@ -258,7 +261,7 @@ function SimpleGraphs.delete!(G::SimpleDigraph, v) end # Create a list of all edges in the digraph -function elist(G::SimpleDigraph{T}) where {T} +function elist(G::DirectedGraph{T}) where {T} E = Set{Tuple{T,T}}() for v in G.V for w in G.N[v] @@ -280,8 +283,8 @@ end `simplify(G::SimpleDigraph)` converts a directed graph into a `SimpleGraph` by removing directions and loops. """ -function simplify(D::SimpleDigraph{T}) where {T} - G = SimpleGraph{T}() +function simplify(D::DirectedGraph{T}) where {T} + G = UndirectedGraph{T}() for v in D.V add!(G, v) end @@ -292,7 +295,7 @@ function simplify(D::SimpleDigraph{T}) where {T} end # Equality check -function SimpleGraphs.isequal(G::SimpleDigraph, H::SimpleDigraph) +function SimpleGraphs.isequal(G::DirectedGraph, H::DirectedGraph) if G.V != H.V || NE(G) != NE(H) return false end @@ -305,11 +308,11 @@ function SimpleGraphs.isequal(G::SimpleDigraph, H::SimpleDigraph) return true end -function ==(G::SimpleDigraph, H::SimpleDigraph) +function ==(G::DirectedGraph, H::DirectedGraph) return isequal(G, H) end -function hash(G::SimpleDigraph, h::UInt64 = UInt64(0)) +function hash(G::DirectedGraph, h::UInt64 = UInt64(0)) return hash(G.V, h) + hash(G.N, h) end @@ -319,8 +322,8 @@ end # Relabel the vertics of a graph based on a dictionary mapping old # vertex names to new -function relabel(G::SimpleDigraph{S}, label::Dict{S,T}) where {S,T} - H = SimpleDigraph{T}() +function relabel(G::DirectedGraph{S}, label::Dict{S,T}) where {S,T} + H = DirectedGraph{T}() for v in G.V add!(H, label[v]) end @@ -335,7 +338,7 @@ function relabel(G::SimpleDigraph{S}, label::Dict{S,T}) where {S,T} end # Relabel the vertices with the integers 1:n -function relabel(G::SimpleDigraph{S}) where {S} +function relabel(G::DirectedGraph{S}) where {S} verts = vlist(G) n = length(verts) label = Dict{S,Int}() @@ -357,8 +360,8 @@ bipartite graph. For each vertex `v` in `G`, the output graph has two vertices `(v,1)` and `(v,2)`. Each edge `(v,w)` of `G` is rendered as an edge between `(v,1)` and `(w,2)` in the output graph. """ -function vertex_split(G::SimpleDigraph{S}) where {S} - H = SimpleGraph{Tuple{S,Int}}() +function vertex_split(G::DirectedGraph{S}) where {S} + H = UndirectedGraph{Tuple{S,Int}}() for v in vlist(G) add!(H, (v, 1)) @@ -378,7 +381,7 @@ end """ test if a directed graph is strongly connected by using DFS """ -function is_strongly_connected(G::SimpleDigraph{S}) where {S} +function is_strongly_connected(G::DirectedGraph{S}) where {S} vlist = collect(G.V) start = vlist[1] visited = zeros(Int, length(vlist)) @@ -387,7 +390,7 @@ function is_strongly_connected(G::SimpleDigraph{S}) where {S} end #reverse directions of the graph - reverseG = SimpleDigraph{S}() + reverseG = DirectedGraph{S}() for v in vlist add!(reverseG, v) end @@ -405,7 +408,7 @@ end """ perform a depth first search on graph G starting at vertex v """ -function DFS(G::SimpleDigraph{S}, v, visited::Array{Int,1}) where {S} +function DFS(G::DirectedGraph{S}, v, visited::Array{Int,1}) where {S} vlist = collect(G.V) visited[findfirst(isequal(v), vlist)] = 1 for i in G.N[v] diff --git a/src/d_simple_matrices.jl b/src/d_simple_matrices.jl index 538e198..2f02b50 100644 --- a/src/d_simple_matrices.jl +++ b/src/d_simple_matrices.jl @@ -1,7 +1,7 @@ # Functions to create standard digraph matrices # Adjaceny Matrix -function adjacency(G::SimpleDigraph) +function adjacency(G::DirectedGraph) n = NV(G) A = zeros(Int, (n, n)) @@ -20,7 +20,7 @@ end # incidence matrix -function incidence(G::SimpleDigraph) +function incidence(G::DirectedGraph) n = NV(G) m = NE(G) M = spzeros(Int, n, m) diff --git a/src/embedding/colorize.jl b/src/embedding/colorize.jl index f708270..db50865 100644 --- a/src/embedding/colorize.jl +++ b/src/embedding/colorize.jl @@ -9,7 +9,7 @@ const colorize_hues = """ This is the code used by `set_vertex_color(G,d,palette)`. Not exported. """ -function colorize(G::SimpleGraph{T}, d::Dict{T,S}, palette) where {T,S<:Integer} +function colorize(G::UndirectedGraph{T}, d::Dict{T,S}, palette) where {T,S<:Integer} nh = length(palette) for v in G.V diff --git a/src/embedding/embedding.jl b/src/embedding/embedding.jl index b2032d9..0fd9d26 100644 --- a/src/embedding/embedding.jl +++ b/src/embedding/embedding.jl @@ -26,7 +26,7 @@ const DEFAULT_MARKER_SIZE = 6 * :vsize is set to DEFAULT_MARKER_SIZE * :xy is set to a circular embedding """ -function _new_embed(G::SimpleGraph{T}) where {T} +function _new_embed(G::UndirectedGraph{T}) where {T} cache_save(G, :vsize, DEFAULT_MARKER_SIZE) G.cache[:vcolor] = Dict{T,Any}() @@ -46,14 +46,14 @@ end `ensure_embed(G)` gives `G` a default embedding if it doesn't already have an embedding. """ -function ensure_embed(G::SimpleGraph) +function ensure_embed(G::UndirectedGraph) if !cache_check(G, :xy) _new_embed(G) end end -function private_adj(G::SimpleGraph) +function private_adj(G::UndirectedGraph) n = NV(G) A = zeros(Int, n, n) vv = vlist(G) @@ -99,7 +99,7 @@ The `algorithm` defaults to `:circular` and may be one of the following: Note that if the graph already has (say) an embedding, that embedding may be used as the starting point for one of the algorithms. """ -function embed(G::SimpleGraph, algorithm::Symbol = :circular; args...) +function embed(G::UndirectedGraph, algorithm::Symbol = :circular; args...) arg_dict = list2dict(collect(args)) n = NV(G) m = NE(G) @@ -212,7 +212,7 @@ end a dictionary `d` that maps vertices to coordinates (as two dimensional vectors `[x,y]`). """ -function embed(G::SimpleGraph, xy::Dict) +function embed(G::UndirectedGraph, xy::Dict) ensure_embed(G) G.cache[:xy] = deepcopy(xy) nothing @@ -238,7 +238,7 @@ end """ `_circular_xy(G)` creates a standard circular embedding. """ -function _circular_xy(G::SimpleGraph{T})::Dict where {T} +function _circular_xy(G::UndirectedGraph{T})::Dict where {T} n = NV(G) xy = Dict{T,Vector{Float64}}() if n == 0 @@ -261,7 +261,7 @@ end """ `_random_xy(G)` creates a random xy-embedding for `G` """ -function _random_xy(G::SimpleGraph{T})::Dict where {T} +function _random_xy(G::UndirectedGraph{T})::Dict where {T} rootn = sqrt(NV(G)) xy = Dict{T,Vector{Float64}}() for v in G.V @@ -278,18 +278,18 @@ end `edge_length(G)` returns an array containing the lengths of the edges in the current embedding of `G`. """ -edge_length(G::SimpleGraph) = [edge_length(G, ee) for ee in G.E] +edge_length(G::UndirectedGraph) = [edge_length(G, ee) for ee in G.E] """ `edge_length(G,e)` gives the distance between the embedded endpoints of the edge `e` in the drawing `G`. """ -function edge_length(G::SimpleGraph{T}, v, w) where {T} +function edge_length(G::UndirectedGraph{T}, v, w) where {T} p1 = getxy(G, v) p2 = getxy(G, w) return norm(p1 - p2) end -edge_length(G::SimpleGraph, ee) = edge_length(G, ee[1], ee[2]) +edge_length(G::UndirectedGraph, ee) = edge_length(G, ee[1], ee[2]) """ @@ -297,12 +297,12 @@ edge_length(G::SimpleGraph, ee) = edge_length(G, ee[1], ee[2]) `m`. If `m` is omitted, the drawing is rescaled so that the average length of an edge equals 1. """ -function scale(G::SimpleGraph, m::T) where {T<:Real} +function scale(G::UndirectedGraph, m::T) where {T<:Real} ensure_embed(G) _scale(G.cache[:xy], m) end -function scale(G::SimpleGraph) +function scale(G::UndirectedGraph) if NE(G) == 0 return end diff --git a/src/embedding/getset.jl b/src/embedding/getset.jl index 392f708..36f7ae1 100644 --- a/src/embedding/getset.jl +++ b/src/embedding/getset.jl @@ -10,12 +10,12 @@ export set_vertex_size, get_vertex_size `getxy(G,v)` returns the `xy`-coordinates of the vertex `v`. """ -function getxy(G::SimpleGraph) +function getxy(G::UndirectedGraph) ensure_embed(G) return (deepcopy(G.cache[:xy])) end -function getxy(G::SimpleGraph, v) +function getxy(G::UndirectedGraph, v) ensure_embed(G) return G.cache[:xy][v] end @@ -24,13 +24,13 @@ end `hasxy(G::SimpleGraph)` returns `true` if an embedding has been given to this graph. """ -hasxy(G::SimpleGraph)::Bool = cache_check(G, :xy) +hasxy(G::UndirectedGraph)::Bool = cache_check(G, :xy) """ `get_line_color(G)` returns the color for edges and vertex boundaries """ -function get_line_color(G::SimpleGraph) +function get_line_color(G::UndirectedGraph) ensure_embed(G) return G.cache[:line_color] end @@ -39,7 +39,7 @@ end `set_line_color(G::SimpleGraph, hue=:black)` sets the color of the graph's edges and vertex boundaries. """ -function set_line_color(G::SimpleGraph, hue = :black) +function set_line_color(G::UndirectedGraph, hue = :black) ensure_embed(G) G.cache[:line_color] = hue end @@ -51,12 +51,12 @@ end `get_vertex_color(G)` returns a copy of the dictionary mapping vertices to colors. """ -function get_vertex_color(G::SimpleGraph, v) +function get_vertex_color(G::UndirectedGraph, v) ensure_embed(G) return G.cache[:vcolor][v] end -function get_vertex_color(G::SimpleGraph) +function get_vertex_color(G::UndirectedGraph) ensure_embed(G) return deepcopy(G.cache[:vcolor]) end @@ -68,12 +68,12 @@ end `set_vertex_color(G,hue)` sets the color of all vertices to `hue`. If `hue` is omitted, we use `:white`. """ -function set_vertex_color(G::SimpleGraph, v, hue) +function set_vertex_color(G::UndirectedGraph, v, hue) ensure_embed(G) G.cache[:vcolor][v] = hue end -function set_vertex_color(G::SimpleGraph, hue) +function set_vertex_color(G::UndirectedGraph, hue) ensure_embed(G) d = G.cache[:vcolor] for v in G.V @@ -81,7 +81,7 @@ function set_vertex_color(G::SimpleGraph, hue) end end -set_vertex_color(G::SimpleGraph) = set_vertex_color(G, :white) +set_vertex_color(G::UndirectedGraph) = set_vertex_color(G, :white) """ @@ -95,7 +95,7 @@ where `k=d[v]`. If `palette` is omitted, use the constant global variable `colorize_hues`. """ function set_vertex_color( - G::SimpleGraph, + G::UndirectedGraph, d::Dict{S,T}, palette = colorize_hues, ) where {S,T<:Integer} @@ -107,12 +107,12 @@ end `set_vertex_size(G)` restores the radius to the default value. """ -function set_vertex_size(G::SimpleGraph, s::Int = DEFAULT_MARKER_SIZE) +function set_vertex_size(G::UndirectedGraph, s::Int = DEFAULT_MARKER_SIZE) ensure_embed(G) G.cache[:vsize] = s end -function get_vertex_size(G::SimpleGraph) +function get_vertex_size(G::UndirectedGraph) ensure_embed(G) return G.cache[:vsize] end diff --git a/src/embedding/graffle.jl b/src/embedding/graffle.jl index acf32b8..5dd1a27 100644 --- a/src/embedding/graffle.jl +++ b/src/embedding/graffle.jl @@ -2,7 +2,7 @@ using LightXML export graffle -function bounds(G::SimpleGraph) +function bounds(G::UndirectedGraph) ensure_embed(G) xmin = Inf ymin = Inf @@ -33,7 +33,7 @@ function bounds(G::SimpleGraph) return (xmin, xmax, ymin, ymax) end -function make_scaler(G::SimpleGraph) +function make_scaler(G::UndirectedGraph) (xmin, xmax, ymin, ymax) = bounds(G) f(x, y) = (round(Int, 72 * (x - xmin + 0.5)), round(Int, 72 * (ymax - y + 0.5))) @@ -81,7 +81,7 @@ an OmniGraffle document of this drawing. * `filename` is the name of the OmniGraffle document (be sure to end with `.graffle`) * `rad` is the radius of the circles representing the vertices """ -function graffle(G::SimpleGraph, filename = "julia.graffle", rad::Int = 9) +function graffle(G::UndirectedGraph, filename = "julia.graffle", rad::Int = 9) # X = get_embedding_direct(G) diff --git a/src/embedding/my_spring.jl b/src/embedding/my_spring.jl index 138f577..eca815d 100644 --- a/src/embedding/my_spring.jl +++ b/src/embedding/my_spring.jl @@ -99,7 +99,7 @@ end -function _spring(G::SimpleGraph{T}, nits::Int = 1000) where {T} +function _spring(G::UndirectedGraph{T}, nits::Int = 1000) where {T} n = NV(G) A, vv = private_adj(G) diff --git a/src/embedding/my_stress.jl b/src/embedding/my_stress.jl index 13f0ab4..b3fb704 100644 --- a/src/embedding/my_stress.jl +++ b/src/embedding/my_stress.jl @@ -183,7 +183,7 @@ end -function private_dist(G::SimpleGraph) +function private_dist(G::UndirectedGraph) n = NV(G) d = dist(G) @@ -207,7 +207,7 @@ end -function _stress(G::SimpleGraph{T}) where {T} +function _stress(G::UndirectedGraph{T}) where {T} n = NV(G) A, vv = private_dist(G) diff --git a/src/embedding/spectral.jl b/src/embedding/spectral.jl index 7c302db..e3f33ef 100644 --- a/src/embedding/spectral.jl +++ b/src/embedding/spectral.jl @@ -10,7 +10,7 @@ smallest. This may also be invoked as `_spectral(G,xcol,ycol)` to choose other eigenvectors to use for the x and y coordinates of the embedding. """ -function _spectral(G::SimpleGraph, xcol::Int = 2, ycol::Int = 3) +function _spectral(G::UndirectedGraph, xcol::Int = 2, ycol::Int = 3) L = laplace(G) EV = eigvecs(L) x = EV[:, xcol] @@ -30,7 +30,7 @@ end _normalized_spectral(G::SimpleGraph, xcol::Int = 2, ycol::Int = 3) Same as `_spectral`, but use the normalized Laplacian matrix. """ -function _normalized_spectral(G::SimpleGraph, xcol::Int = 2, ycol::Int = 3) +function _normalized_spectral(G::UndirectedGraph, xcol::Int = 2, ycol::Int = 3) L = normalized_laplace(G) EV = eigvecs(L) x = EV[:, xcol] diff --git a/src/embedding/tikz.jl b/src/embedding/tikz.jl index 6635463..2372033 100644 --- a/src/embedding/tikz.jl +++ b/src/embedding/tikz.jl @@ -2,7 +2,7 @@ export tikz_file, tikz_print # Code developed by Tara Abrishami -function tikz_string(G::SimpleGraph, label::Bool = false) +function tikz_string(G::UndirectedGraph, label::Bool = false) #Outputs a string of tikz code to draw graph G. #Label = true if nodes should be labeled in the drawing, false otherwise. s = "\\begin{tikzpicture}\n" @@ -39,7 +39,7 @@ end `tikz_print(G)` prints tikz code to draw `G`. `tikz_print(G,true)` does likewise, with vertex labels drawn. """ -function tikz_print(G::SimpleGraph, label::Bool = false) +function tikz_print(G::UndirectedGraph, label::Bool = false) print(tikz_string(G, label)) end @@ -48,10 +48,10 @@ end into `filename`. If `label` is omitted (or `false`) vertex labels are not drawn. If `filename` is omitted, it defaults to `graph.tex`. """ -function tikz_file(G::SimpleGraph, label::Bool, filename::String = "graph.tex") +function tikz_file(G::UndirectedGraph, label::Bool, filename::String = "graph.tex") FILE = open(filename, "w") print(FILE, tikz_string(G, label)) close(FILE) end -tikz_file(G::SimpleGraph, filename::String = "graph.tex") = tikz_file(G, false, filename) +tikz_file(G::UndirectedGraph, filename::String = "graph.tex") = tikz_file(G, false, filename) diff --git a/src/embedding/transforms.jl b/src/embedding/transforms.jl index b68aaab..fc26306 100644 --- a/src/embedding/transforms.jl +++ b/src/embedding/transforms.jl @@ -69,7 +69,7 @@ end `recenter(G)` translates the graph's drawing so that the center of mass of the vertices is at the origin. """ -function recenter(G::SimpleGraph) +function recenter(G::UndirectedGraph) ensure_embed(G) _recenter(G.cache[:xy]) end @@ -79,7 +79,7 @@ end in the graph's drawing. Here `A` is 2-by-2 matrix and `b` is a 2-vector. Each point `p` is mapped to `A*p+b`. """ -function transform(G::SimpleGraph, A::Array{S,2}, b::Vector{T}) where {S<:Real,T<:Real} +function transform(G::UndirectedGraph, A::Array{S,2}, b::Vector{T}) where {S<:Real,T<:Real} ensure_embed(G) _transform(G.cache[:xy], A, b) end diff --git a/src/embedding/tutte.jl b/src/embedding/tutte.jl index 033f817..4984bba 100644 --- a/src/embedding/tutte.jl +++ b/src/embedding/tutte.jl @@ -9,7 +9,7 @@ defines a face, the embedding will be crossing free. `tutte(G::SimpleGraph)` assumes `G` has a rotation system in which case a largest face will be selected to be `outside`. """ -function _tutte(G::SimpleGraph{T}, outside::Vector{T}) where {T} +function _tutte(G::UndirectedGraph{T}, outside::Vector{T}) where {T} if !issubset(outside, G.V) error("Some of the proposed outer vertices are not in this graph") end @@ -61,7 +61,7 @@ function _tutte(G::SimpleGraph{T}, outside::Vector{T}) where {T} end -function _tutte(G::SimpleGraph) +function _tutte(G::UndirectedGraph) FF = faces(G) Fmax = first(FF) for F in FF diff --git a/src/hyper/SimpleHypergraphs.jl b/src/hyper/SimpleHypergraphs.jl index 5515cb1..141939a 100644 --- a/src/hyper/SimpleHypergraphs.jl +++ b/src/hyper/SimpleHypergraphs.jl @@ -55,7 +55,7 @@ The vertices of `G` are the same as those in `H`. Two vertices of `G` are adjace iff they lie in a common edge of `H`. """ function simplify(H::HyperGraph{T}) where {T} - G = SimpleGraph{T}() + G = UndirectedGraph{T}() # copy the vertices into G for v in H.V diff --git a/src/hyper/graph.jl b/src/hyper/graph.jl index 81c55d4..be57bf4 100644 --- a/src/hyper/graph.jl +++ b/src/hyper/graph.jl @@ -2,8 +2,8 @@ `SimpleGraph(H::HG)` demotes a hypergraph to a simple graph. """ -function SimpleGraph(H::HG{T})::SimpleGraph{T} where {T} - G = SimpleGraph{T}() +function UndirectedGraph(H::HG{T})::UndirectedGraph{T} where {T} + G = UndirectedGraph{T}() # copy all vertices for v in H.V @@ -37,7 +37,7 @@ type `T`. **Warning**: Do not use `T=Any`. `HG(G::SimpleGraph)` converts a graph to the equivalent two-uniform hypergraph. """ -function HG(G::SimpleGraph{T}) where {T} +function HG(G::UndirectedGraph{T}) where {T} H = HG{T}() for v in G.V add!(H, v) diff --git a/src/indep_poly.jl b/src/indep_poly.jl index 0754e07..56cc4a9 100644 --- a/src/indep_poly.jl +++ b/src/indep_poly.jl @@ -4,7 +4,7 @@ export indep_poly `indep_poly(G)` returns the independence polynomial of the `SimpleGraph` `G`. """ -function indep_poly(G::SimpleGraph, cache_flag::Bool = true) +function indep_poly(G::UndirectedGraph, cache_flag::Bool = true) if cache_flag && cache_check(G, :indep_poly) return cache_recall(G, :indep_poly) end diff --git a/src/interlace.jl b/src/interlace.jl index 71be7a7..6a5c70c 100644 --- a/src/interlace.jl +++ b/src/interlace.jl @@ -4,7 +4,7 @@ export toggle!, local_complement!, interlace `toggle!(G,x,y)` deletes edge `xy` if present or adds edge `xy` if absent. **No error checking is done**. """ -function toggle!(G::SimpleGraph, x, y) +function toggle!(G::UndirectedGraph, x, y) if has(G, x, y) SimpleGraphs.delete!(G, x, y) else @@ -18,7 +18,7 @@ end where `a` is in `A` and `b` is in `B`. **No error checking is done**. """ -function super_toggle!(G::SimpleGraph, A::Set, B::Set) +function super_toggle!(G::UndirectedGraph, A::Set, B::Set) for a in A for b in B toggle!(G, a, b) @@ -33,7 +33,7 @@ end That is, if `u` and `w` are neighbors of `v` then we toggle the edge/nonedge `uw`, modifying the graph. """ -function local_complement!(G::SimpleGraph, v) +function local_complement!(G::UndirectedGraph, v) if !has(G, v) error("Vertex $v is not in this graph") end @@ -51,7 +51,7 @@ function local_complement!(G::SimpleGraph, v) end -function pivot!(G::SimpleGraph, a, b, debug::Bool = false) +function pivot!(G::UndirectedGraph, a, b, debug::Bool = false) if !has(G, a, b) error("Edge ($a,$b) is not in this graph") end @@ -83,7 +83,7 @@ end """ `interlace(G)` returns the interlace polynomial of the graph `G`. """ -function interlace(G::SimpleGraph, saver::Bool = true) +function interlace(G::UndirectedGraph, saver::Bool = true) if saver && cache_check(G, :interlace) return cache_recall(G, :interlace) end diff --git a/src/matching_poly.jl b/src/matching_poly.jl index 936b79d..57ed304 100644 --- a/src/matching_poly.jl +++ b/src/matching_poly.jl @@ -4,7 +4,7 @@ export matching_poly `matching_poly(G)` returns the matching polynomial of the `SimpleGraph` `G`. """ -function matching_poly(G::SimpleGraph, cache_flag::Bool = true) +function matching_poly(G::UndirectedGraph, cache_flag::Bool = true) if cache_flag && cache_check(G, :matching_poly) return cache_recall(G, :matching_poly) end diff --git a/src/platonic.jl b/src/platonic.jl index 982ad87..6b96311 100644 --- a/src/platonic.jl +++ b/src/platonic.jl @@ -1,6 +1,6 @@ export Tetrahedron, Dodecahedron, Icosahedron, Octahedron -function add_edge_matrix!(G::SimpleGraph, edges::Array{Int,2}) +function add_edge_matrix!(G::UndirectedGraph, edges::Array{Int,2}) ne = size(edges, 1) for j = 1:ne e = edges[j, :] diff --git a/src/prufer.jl b/src/prufer.jl index 338e2f9..4773f66 100644 --- a/src/prufer.jl +++ b/src/prufer.jl @@ -4,7 +4,7 @@ export prufer_code, is_tree, prufer_restore is_tree(G) Determines if the `SimpleGraph` is a tree. """ -function is_tree(G::SimpleGraph) +function is_tree(G::UndirectedGraph) return is_connected(G) && (NE(G) == NV(G) - 1) end @@ -13,7 +13,7 @@ end lowest_leaf(G) Return the leaf of the `SimpleGraph` with the smallest label. """ -function lowest_leaf(G::SimpleGraph) +function lowest_leaf(G::UndirectedGraph) leaves = [v for v ∈ G.V if deg(G, v) == 1] return findmin(leaves)[1] end @@ -23,7 +23,7 @@ end lowest_leaf_neighbor(G::SimpleGraph) Return the unique neighbor of `lowest_leaf(G)`. """ -function lowest_leaf_neighbor(G::SimpleGraph) +function lowest_leaf_neighbor(G::UndirectedGraph) v = lowest_leaf(G) return G[v][1] end @@ -34,7 +34,7 @@ Return the Prufer code of the `SimpleGraph` which must be a tree. The vertices must be `<`-comparable and preferrably are the integers `{1,2,...,n}` (otherwise we cannot decode the sequence generated). """ -function prufer_code(G::SimpleGraph{T})::Vector{T} where {T} +function prufer_code(G::UndirectedGraph{T})::Vector{T} where {T} if !is_tree(G) error("Graph must be a tree") end @@ -57,7 +57,7 @@ function prufer_code(G::SimpleGraph{T})::Vector{T} where {T} end -function prufer_work(G::SimpleGraph{T})::Vector{T} where {T} +function prufer_work(G::UndirectedGraph{T})::Vector{T} where {T} if NV(G) <= 2 return T[] end diff --git a/src/rotation_system.jl b/src/rotation_system.jl index 4c2d891..04f0f73 100644 --- a/src/rotation_system.jl +++ b/src/rotation_system.jl @@ -6,7 +6,7 @@ export embed_rot, NF, dual `rand_rot(G::SimpleGraph)` creates a random rotation system for the graph. """ -function rand_rot(G::SimpleGraph{T}) where {T} +function rand_rot(G::UndirectedGraph{T}) where {T} d = Dict{T,RingList{T}}() for v in G.V a = shuffle(RingList(G[v])) @@ -19,7 +19,7 @@ end `_default_rot(G::SimpleGraph)` creates a default rotation system for the graph. """ -function _default_rot(G::SimpleGraph{T}) where {T} +function _default_rot(G::UndirectedGraph{T}) where {T} d = Dict{T,RingList{T}}() for v in G.V d[v] = RingList(G[v]) @@ -33,7 +33,7 @@ for this graph (held in the graph's cache). If `d` is omitted, the a default rotation is used. """ -function set_rot(G::SimpleGraph, d) +function set_rot(G::UndirectedGraph, d) if !check_rot(G, d) error("Not a valid rotation system for this graph") end @@ -42,7 +42,7 @@ function set_rot(G::SimpleGraph, d) end -function set_rot(G::SimpleGraph) +function set_rot(G::UndirectedGraph) if hasxy(G) embed_rot(G) return @@ -60,14 +60,14 @@ associated with `G`. If there is none, a rotation system will be created for this graph. If the graph has an embedding, that will be used to create the rotation system. """ -function get_rot(G::SimpleGraph, v) +function get_rot(G::UndirectedGraph, v) if !has(G, v) error("No such vertex $v in this graph") end d = get_rot(G) return d[v] end -function get_rot(G::SimpleGraph) +function get_rot(G::UndirectedGraph) if cache_check(G, :RotationSystem) return cache_recall(G, :RotationSystem) end @@ -81,7 +81,7 @@ end `embed_rot(G::SimpleGraph)` assigns a rotation system to `G` corresponding to its current `xy` embedding. """ -function embed_rot(G::SimpleGraph{T}) where {T} +function embed_rot(G::UndirectedGraph{T}) where {T} xy = getxy(G) d = Dict{T,RingList{T}}() for v in G.V @@ -101,7 +101,7 @@ end `check_rot(G::SimpleGraph,d::Dict)` checks if `d` is a valid rotation system for `G`. """ -function check_rot(G::SimpleGraph{T}, d::Dict{T,RingList{T}}) where {T} +function check_rot(G::UndirectedGraph{T}, d::Dict{T,RingList{T}}) where {T} for v in G.V if !haskey(d, v) return false @@ -115,7 +115,7 @@ end -function _next_edge(G::SimpleGraph{T}, uv::Tuple{T,T}) where {T} +function _next_edge(G::UndirectedGraph{T}, uv::Tuple{T,T}) where {T} u, v = uv r = get_rot(G, v) w = r(u) @@ -128,7 +128,7 @@ end face starting with the edge `(u,v)` (in that order). Also may be called by `_trace_face(G,(u,v))`. """ -function _trace_face(G::SimpleGraph{T}, uv::Tuple{T,T}) where {T} +function _trace_face(G::UndirectedGraph{T}, uv::Tuple{T,T}) where {T} data = T[] u, v = uv push!(data, u) @@ -147,7 +147,7 @@ function _trace_face(G::SimpleGraph{T}, uv::Tuple{T,T}) where {T} return RingList(boundary) end -_trace_face(G::SimpleGraph{T}, u::T, v::T) where {T} = _trace_face(G, (u, v)) +_trace_face(G::UndirectedGraph{T}, u::T, v::T) where {T} = _trace_face(G, (u, v)) """ @@ -159,7 +159,7 @@ Each face is a `RingList` of the (directed) edges bordering the face. *Requires that the graph is connected and has at least one edge.* """ -function faces(G::SimpleGraph{T}) where {T} +function faces(G::UndirectedGraph{T}) where {T} FT = RingList{Tuple{T,T}} # type of an oriented face result = Set{FT}() @@ -180,7 +180,7 @@ given its current rotation system. *Requires that the graph is connected and has at least one edge.* """ -NF(G::SimpleGraph) = length(faces(G)) +NF(G::UndirectedGraph) = length(faces(G)) """ `euler_char(G::SimpleGraph)` computes the Euler characteristic @@ -189,7 +189,7 @@ Specifically, `euler_char(G)` returns `NV(G) - NE(G) + NF(G)`. *Requires that the graph is connected and has at least one edge.* """ -euler_char(G::SimpleGraph) = NV(G) - NE(G) + NF(G) +euler_char(G::UndirectedGraph) = NV(G) - NE(G) + NF(G) _shorten(F::RingList) = first.(F) @@ -201,11 +201,11 @@ adjacent if and only if they share a common edge. *Requires that the graph is connected and has at least one edge.* """ -function dual(G::SimpleGraph{T}) where {T} +function dual(G::UndirectedGraph{T}) where {T} Flist = collect(faces(G)) # list of faces of the graph FT = RingList{Tuple{T,T}} # data type of faces VT = Vector{T} # data type of shortened faces - GG = SimpleGraph{VT}() # graph to return + GG = UndirectedGraph{VT}() # graph to return # the faces of G are the vertices of GG for f in Flist diff --git a/src/simple_coloring.jl b/src/simple_coloring.jl index 1eb2494..9d66ac1 100644 --- a/src/simple_coloring.jl +++ b/src/simple_coloring.jl @@ -10,7 +10,7 @@ export bipartition, two_color, greedy_color, random_greedy_color if the graph is not bipartite. The output is a `Dict` mapping the vertex set to the values 1 and 2. """ -function two_color(G::SimpleGraph{T}) where {T} +function two_color(G::UndirectedGraph{T}) where {T} if cache_check(G, :two_color) return cache_recall(G, :two_color) end @@ -47,7 +47,7 @@ using SimplePartitions `bipartition(G)` creates a bipartition of the graph (or returns an error if the graph is not bipartite. Output is a `Partition`. """ -function bipartition(G::SimpleGraph{T}) where {T} +function bipartition(G::UndirectedGraph{T}) where {T} f = two_color(G) return Partition(f) end @@ -66,7 +66,7 @@ is returned to you as a `Dict` mapping vertices to positive integers If `seq` is omitted, a random permutation of the vertices is used. """ -function greedy_color(G::SimpleGraph{T}, seq::Array{T,1}) where {T} +function greedy_color(G::UndirectedGraph{T}, seq::Array{T,1}) where {T} f = Dict{T,Int}() # this is the mapping from V to colors maxf::Int = 0 # largest color used @@ -97,7 +97,7 @@ end # order by degree. The order of vertices of the same degree is # indeterminate. NOTE: This is not exported from this module. Should # it be? -function deg_sorted_vlist(G::SimpleGraph) +function deg_sorted_vlist(G::UndirectedGraph) bye = x -> -x[1] list = [(deg(G, v), v) for v in G.V] sort!(list, by = bye) @@ -107,7 +107,7 @@ end # Apply greedy_color to the graph visiting the vertices in decreasing # order of degree. -function greedy_color(G::SimpleGraph{T}) where {T} +function greedy_color(G::UndirectedGraph{T}) where {T} seq = deg_sorted_vlist(G) return greedy_color(G, seq) end @@ -122,7 +122,7 @@ end random permutations of the vertex set. After `reps` iterations, the best coloring found is returned. """ -function random_greedy_color(G::SimpleGraph{T}, reps::Int = 1) where {T} +function random_greedy_color(G::UndirectedGraph{T}, reps::Int = 1) where {T} n = NV(G) bestf = greedy_color(G) # degree order default start best = maximum(values(bestf)) diff --git a/src/simple_connect.jl b/src/simple_connect.jl index 0991fd2..e238c63 100644 --- a/src/simple_connect.jl +++ b/src/simple_connect.jl @@ -9,7 +9,7 @@ export eccentricity, radius, graph_center `components(G)` returns the vertex sets of the connected components of `G` (as a `Partition`). """ -function components(G::SimpleGraph{T}) where {T} +function components(G::UndirectedGraph{T}) where {T} if cache_check(G, :components) return cache_recall(G, :components) end @@ -26,7 +26,7 @@ end """ `num_components(G)` returns the number of connected components in `G`. """ -function num_components(G::SimpleGraph{T})::Int where {T} +function num_components(G::UndirectedGraph{T})::Int where {T} if cache_check(G, :num_components) return cache_recall(G, :num_components) end @@ -41,7 +41,7 @@ end max_component(G::SimpleGraph) Return the vertex set of a largest component of `G`. """ -function max_component(G::SimpleGraph{T})::Set{T} where {T} +function max_component(G::UndirectedGraph{T})::Set{T} where {T} comps = components(G) sets = collect(parts(comps)) (_, idx) = findmax(length, sets) @@ -54,7 +54,7 @@ end """ `is_connected(G)` determines if `G` is connected. """ -function is_connected(G::SimpleGraph{T}) where {T} +function is_connected(G::UndirectedGraph{T}) where {T} return num_components(G) <= 1 end @@ -64,11 +64,11 @@ end """ `spanning_forest(G)` creates a maximal acyclic subgraph of `G`. """ -function spanning_forest(G::SimpleGraph{T}) where {T} +function spanning_forest(G::UndirectedGraph{T}) where {T} if cache_check(G, :spanning_forest) return cache_recall(G, :spanning_forest) end - H = SimpleGraph{T}() + H = UndirectedGraph{T}() if NV(G) == 0 return H end @@ -102,11 +102,11 @@ Each component of the result spans a component of `G`. This differs from `spanning_forest` in that repeated invocations of this function can return different results. """ -function random_spanning_forest(G::SimpleGraph) +function random_spanning_forest(G::UndirectedGraph) VT = eltype(G) ET = Tuple{VT,VT} - T = SimpleGraph{VT}() # output + T = UndirectedGraph{VT}() # output VV = vlist(G) EE = elist(G) @@ -211,7 +211,7 @@ function dist(G::AbstractSimpleGraph, u, v) if !has(G, u) || !has(G, v) error("One or both of $u and $v are not vertices of this graph") end - if typeof(G) <: SimpleGraph && cache_check(G, :dist) + if typeof(G) <: UndirectedGraph && cache_check(G, :dist) d = cache_recall(G, :dist) return d[u, v] end @@ -279,7 +279,7 @@ end in the graph `G`. This is the maximum distance from `v` to another vertex (or -1 if the graph is not connected). """ -function eccentricity(G::SimpleGraph, v) +function eccentricity(G::UndirectedGraph, v) if !has(G, v) error("$v is not a vertex of this graph") end @@ -294,7 +294,7 @@ end `graph_center(G)` returns the set of vertices of a `SimpleGraph` with minimum eccentricities. """ -function graph_center(G::SimpleGraph)::Set +function graph_center(G::UndirectedGraph)::Set if cache_check(G, :graph_center) return cache_recall(G, :graph_center) end @@ -321,7 +321,7 @@ end minimum `eccentricity` of a vertex of `G` (or -1 if the graph is not connected). """ -function radius(G::SimpleGraph) +function radius(G::UndirectedGraph) if cache_check(G, :radius) return cache_recall(G, :radius) end @@ -340,7 +340,7 @@ end `wiener_index(G)` is the sum of the distances between vertices in `G`. Returns -1 if `G` is not connected. """ -function wiener_index(G::SimpleGraph)::Int +function wiener_index(G::UndirectedGraph)::Int if is_connected(G) return div(sum(values(dist(G))), 2) end @@ -352,7 +352,7 @@ end """ `diam(G)` returns the diameter of `G` or `-1` if `G` is not connected. """ -function diam(G::SimpleGraph)::Int +function diam(G::UndirectedGraph)::Int if cache_check(G, :diam) return cache_recall(G, :diam) end @@ -371,7 +371,7 @@ end `is_cut_edge(G,u,v)` [or `is_cut_edge(G,e)`] determins if `(u,v)` [or `e`] is a cut edge of `G`. """ -function is_cut_edge(G::SimpleGraph{T}, u::T, v::T)::Bool where {T} +function is_cut_edge(G::UndirectedGraph{T}, u::T, v::T)::Bool where {T} if !has(G, u, v) error("No such edge {$u,$v} in this graph") end @@ -391,7 +391,7 @@ end # When called as is_cut_edge(G,e), we assume e is a tuple or list # whose first two entries are the end points of the edge -function is_cut_edge(G::SimpleGraph{T}, e::Tuple{T,T})::Bool where {T} +function is_cut_edge(G::UndirectedGraph{T}, e::Tuple{T,T})::Bool where {T} return is_cut_edge(G, e[1], e[2]) end @@ -399,7 +399,7 @@ end is_cut_vertex(G::SimpleGraph, v) Determine if `v` is a cut vertex of `G`. """ -function is_cut_vertex(G::SimpleGraph{T}, v::T)::Bool where {T} +function is_cut_vertex(G::UndirectedGraph{T}, v::T)::Bool where {T} if !has(G, v) error("This graph does not have a vertex $v") end @@ -433,7 +433,7 @@ end `is_acyclic(G)` returns `true` if `G` has no cycles and `false` otherwise. """ -function is_acyclic(G::SimpleGraph) +function is_acyclic(G::UndirectedGraph) n = NV(G) m = NE(G) c = num_components(G) diff --git a/src/simple_constructors.jl b/src/simple_constructors.jl index 5ccfe5f..ac39f1f 100644 --- a/src/simple_constructors.jl +++ b/src/simple_constructors.jl @@ -113,7 +113,7 @@ end # Create a path graph from a list of vertices function Path(verts::Array{T}) where {T} - G = SimpleGraph{T}() + G = UndirectedGraph{T}() n = length(verts) if n == 1 @@ -171,7 +171,7 @@ suggest `Path(n1)*Path(n2)*Path(n3)` optionally wrapped in `relabel`. See also: `Cube`. """ function Grid(n::Int, m::Int) - G = SimpleGraph{Tuple{Int,Int}}() + G = UndirectedGraph{Tuple{Int,Int}}() # add the vertices for u = 1:n @@ -445,7 +445,7 @@ they are disjoint. function Kneser(n::Int, k::Int) A = collect(1:n) vtcs = [Set(v) for v in IterTools.subsets(A, k)] - G = SimpleGraph{Set{Int}}() + G = UndirectedGraph{Set{Int}}() for v in vtcs add!(G, v) @@ -482,7 +482,7 @@ function Johnson(n::Int, k::Int) A = collect(1:n) vtcs = [Set{Int}(v) for v in IterTools.subsets(A, k)] - G = SimpleGraph{Set{Int}}() + G = UndirectedGraph{Set{Int}}() for v in vtcs add!(G, v) @@ -704,7 +704,7 @@ can go from one of these squares to the other in a single move. """ function Knight(r::Int = 8, c::Int = 8) vtcs = collect(Base.Iterators.product(1:r, 1:c)) - G = SimpleGraph{Tuple{Int64,Int64}}() + G = UndirectedGraph{Tuple{Int64,Int64}}() d = Dict{Tuple{Int,Int},Vector{Float64}}() for v in vtcs @@ -796,7 +796,7 @@ function Hoffman() A = [0*D D; D' 0*D] - G = SimpleGraph(A) + G = UndirectedGraph(A) name(G, "Hoffman") return G end @@ -810,7 +810,7 @@ See article on [Mathworld](http://mathworld.wolfram.com/DoyleGraph.html) """ function Doyle() T = Tuple{Int,Int} - G = SimpleGraph{T}() + G = UndirectedGraph{T}() for a = 0:8 for b = 0:2 v = (a, b) @@ -884,7 +884,7 @@ end Create the Golomb graph. This is a unit-distance graph with chromatic number 4. It has 10 vertices and 18 edges. """ -function Golomb()::SimpleGraph{Int} +function Golomb()::UndirectedGraph{Int} G = Cycle(6) for v = 1:6 add!(G, 0, v) @@ -927,7 +927,7 @@ Check to see if the embedded graph `G` is a unit-distance graph. That is, two ve should be distance 1 apart if and only if they are adjacent. The optional `tol` gives some tolerance to this assessment to deal with roundoff. """ -function is_unit_distance(G::SimpleGraph{T}, tol = 1e-10)::Bool where {T} +function is_unit_distance(G::UndirectedGraph{T}, tol = 1e-10)::Bool where {T} xy = getxy(G) VV = vlist(G) n = NV(G) diff --git a/src/simple_core.jl b/src/simple_core.jl index 1211af9..9c7a3ef 100644 --- a/src/simple_core.jl +++ b/src/simple_core.jl @@ -2,7 +2,7 @@ import Base.show, Base.==, Base.adjoint, Base.*, Base.eltype import Base.getindex import LightXML.name -export SimpleGraph, IntGraph, StringGraph +export UndirectedGraph, IntGraph, StringGraph export show, NV, NE, has, typ, fastN!, name, get_edge export vlist, elist, neighbors, getindex, deg, deg_hist @@ -15,14 +15,14 @@ Use `SimpleGraph()` to create a new graph in which the vertices may be vertices are of type `T`. See `IntGraph` and `StringGraph` as special cases. """ -mutable struct SimpleGraph{T} <: AbstractSimpleGraph +mutable struct UndirectedGraph{T} <: AbstractSimpleGraph V::Set{T} # Vertex set E::Set{Tuple{T,T}} # Edge set N::Dict{T,Set{T}} # Optional neighbor sets Nflag::Bool # Tells if N is used or not (default on) cache::Dict{Symbol,Any} # save previous expensive results cache_flag::Bool # decide if we use cache or no - function SimpleGraph{T}(Nflag::Bool = true) where {T} + function UndirectedGraph{T}(Nflag::Bool = true) where {T} V = Set{T}() E = Set{Tuple{T,T}}() N = Dict{T,Set{T}}() @@ -31,6 +31,9 @@ mutable struct SimpleGraph{T} <: AbstractSimpleGraph end end +const UG = UndirectedGraph +export UG + """ `name(G)` returns the graph's name. @@ -38,14 +41,14 @@ end empty, then the name is set to the default `SimpleGraph{T}` where `T` is the vertex type. """ -function name(G::SimpleGraph) +function name(G::UndirectedGraph) if cache_check(G, :name) return cache_recall(G, :name) end return "UndirectedGraph{$(eltype(G))}" end -function name(G::SimpleGraph, the_name::String) +function name(G::UndirectedGraph, the_name::String) G.cache[:name] = the_name if length(the_name) == 0 cache_clear(G, :name) @@ -55,13 +58,13 @@ end -function show(io::IO, G::SimpleGraph) +function show(io::IO, G::UndirectedGraph) suffix = " (n=$(NV(G)), m=$(NE(G)))" print(io, name(G) * suffix) end # Default constructor uses Any type vertices -SimpleGraph(Nflag::Bool = true) = SimpleGraph{Any}(Nflag) +UndirectedGraph(Nflag::Bool = true) = UndirectedGraph{Any}(Nflag) # A StringGraph has vertices of type String. """ @@ -80,7 +83,7 @@ more) tokens, then the first two tokens are taken as vertex names and extra tokens on the line are ignored. Lines that begin with a # are ignored. """ -StringGraph() = SimpleGraph{String}() +StringGraph() = UndirectedGraph{String}() function StringGraph(file::AbstractString) G = StringGraph() @@ -91,7 +94,7 @@ end # Helper function for StrinGraph(file), and can be used to add # vertices and edges to a graph (assuming its vertex type can # accomodate strings). -function load!(G::SimpleGraph, file::AbstractString) +function load!(G::UndirectedGraph, file::AbstractString) f = open(file, "r") while (~eof(f)) line = chomp(readline(f)) @@ -120,7 +123,7 @@ vertices `1:n`. `IntGraph(A)` where `A` is an adjacency matrix creates a graph for which `A` is the adjacency matrix. """ -IntGraph() = SimpleGraph{Int}() +IntGraph() = UndirectedGraph{Int}() # With a postive integer argument, adds 1:n as vertex set, but no # edges. @@ -153,7 +156,7 @@ end `1:n` where `A` is an `n`-by-`n` symmetric matrix specifying the graph's adjacency matrix. """ -SimpleGraph(A::AbstractMatrix) = IntGraph(A) +UndirectedGraph(A::AbstractMatrix) = IntGraph(A) """ @@ -162,7 +165,7 @@ SimpleGraph(A::AbstractMatrix) = IntGraph(A) Returns the data type of the vertices this graph may hold. For example, if `G=IntGraph()` then this returns `Int64`.` """ -eltype(G::SimpleGraph{T}) where {T} = T +eltype(G::UndirectedGraph{T}) where {T} = T @deprecate vertex_type eltype @@ -177,7 +180,7 @@ NV(G::AbstractSimpleGraph) = length(G.V) """ `NE(G)` returns the number of edges in `G`. """ -NE(G::SimpleGraph) = length(G.E) +NE(G::UndirectedGraph) = length(G.E) """ @@ -186,7 +189,7 @@ NE(G::SimpleGraph) = length(G.E) `has(G,v,w)` returns `true` iff `(v,w)` is an edge of `G`. """ has(G::AbstractSimpleGraph, v) = in(v, G.V) -has(G::SimpleGraph, v, w) = in((v, w), G.E) || in((w, v), G.E) +has(G::UndirectedGraph, v, w) = in((v, w), G.E) || in((w, v), G.E) """ @@ -194,7 +197,7 @@ has(G::SimpleGraph, v, w) = in((v, w), G.E) || in((w, v), G.E) the edge joining `u` and `v` is stored in the edge set of `G`. An error is thrown if `u` and `v` are not adjacent vertices of `G`. """ -function get_edge(G::SimpleGraph{T}, u, v)::Tuple{T,T} where {T} +function get_edge(G::UndirectedGraph{T}, u, v)::Tuple{T,T} where {T} if !has(G, u, v) error("($u,$v) is not an edge of this graph") end @@ -215,7 +218,7 @@ structure holding the graph, but slows down look up of edges. **Note**: Fast neighborhood look up is on by default. """ -function fastN!(G::SimpleGraph{T}, flg::Bool = true) where {T} +function fastN!(G::UndirectedGraph{T}, flg::Bool = true) where {T} # if no change, do nothing if flg == G.Nflag return flg @@ -276,7 +279,7 @@ end """ `elist(G)` returns the edges of `G` as a list (array). """ -function elist(G::SimpleGraph) +function elist(G::UndirectedGraph) result = collect(G.E) try sort!(result) @@ -291,7 +294,7 @@ end May also be invoked as `G[v]`. """ -function neighbors(G::SimpleGraph{T}, v) where {T} +function neighbors(G::UndirectedGraph{T}, v) where {T} if ~has(G, v) error("Graph does not contain requested vertex") end @@ -315,11 +318,11 @@ function neighbors(G::SimpleGraph{T}, v) where {T} end # Here is another way to access the neighbors of a vertex: G[v] -getindex(G::SimpleGraph, v) = neighbors(G, v) +getindex(G::UndirectedGraph, v) = neighbors(G, v) # And here's a getindex way to check for edges: G[u,v] is a shortcut # for has(G,u,v). -getindex(G::SimpleGraph, v, w) = has(G, v, w) +getindex(G::UndirectedGraph, v, w) = has(G, v, w) # Degree of a vertex """ @@ -327,7 +330,7 @@ getindex(G::SimpleGraph, v, w) = has(G, v, w) `deg(G)` gives the degree sequence (sorted). """ -function deg(G::SimpleGraph, v) +function deg(G::UndirectedGraph, v) if ~has(G, v) error("Graph does not contain requested vertex") end @@ -338,7 +341,7 @@ function deg(G::SimpleGraph, v) end # Degree sequence -function deg(G::SimpleGraph{T}) where {T} +function deg(G::UndirectedGraph{T}) where {T} if G.Nflag ds = [deg(G, v) for v in G.V] else @@ -368,7 +371,7 @@ present in the graph. Because Julia arrays are 1-based, the indexing is a bit off. Specifically, entry `k` in the returned array is the number of vertices of degree `k-1`. """ -function deg_hist(G::SimpleGraph{T}) where {T} +function deg_hist(G::UndirectedGraph{T}) where {T} n = NV(G) degs = deg(G) result = zeros(Int, n) @@ -381,8 +384,8 @@ end import Base.hash -function hash(G::SimpleGraph, h::UInt64 = UInt64(0)) +function hash(G::UndirectedGraph, h::UInt64 = UInt64(0)) return hash(G.V, h) + hash(G.E, h) end -simplify(G::SimpleGraph) = deepcopy(G) +simplify(G::UndirectedGraph) = deepcopy(G) diff --git a/src/simple_euler.jl b/src/simple_euler.jl index 200c766..a7b74fc 100644 --- a/src/simple_euler.jl +++ b/src/simple_euler.jl @@ -19,7 +19,7 @@ in the graph (just don't choose an isolated vertex as the first/last). If no Euler trail/tour exists, an empty list is returned. """ -function euler(G::SimpleGraph{T}, u::T, v::T) where {T} +function euler(G::UndirectedGraph{T}, u::T, v::T) where {T} notrail = T[] # perform basic checks: @@ -74,14 +74,14 @@ function euler(G::SimpleGraph{T}, u::T, v::T) where {T} end # special case: find an Euler tour from a specified vertex -function euler(G::SimpleGraph{T}, u::T) where {T} +function euler(G::UndirectedGraph{T}, u::T) where {T} return euler(G, u, u) end # special case: find any Euler tour. If the graph is connected, any # vertex will do but if there are isolated vertices, we don't want to # pick one of those! -function euler(G::SimpleGraph{T}) where {T} +function euler(G::UndirectedGraph{T}) where {T} if cache_check(G, :euler) return cache_recall(G, :euler) end @@ -107,7 +107,7 @@ function euler(G::SimpleGraph{T}) where {T} end # private helper function for euler() -function euler_work!(G::SimpleGraph{T}, u::T) where {T} +function euler_work!(G::UndirectedGraph{T}, u::T) where {T} trail = T[] while true diff --git a/src/simple_girth.jl b/src/simple_girth.jl index 3529e46..5ecb791 100644 --- a/src/simple_girth.jl +++ b/src/simple_girth.jl @@ -6,7 +6,7 @@ the vertices on that cycle, or an empty array if `G` is acyclic. *Warning*: This implementation is quite inefficient. """ -function girth_cycle(G::SimpleGraph{T}) where {T} +function girth_cycle(G::UndirectedGraph{T}) where {T} if cache_check(G, :girth_cycle) return cache_recall(G, :girth_cycle) end @@ -41,7 +41,7 @@ if `G` is acyclic. **Warning**: This implementation is quite inefficient. """ -function girth(G::SimpleGraph) +function girth(G::UndirectedGraph) if cache_check(G, :girth) return cache_recall(G, :girth) end diff --git a/src/simple_ham.jl b/src/simple_ham.jl index 41bd60b..2f65afc 100644 --- a/src/simple_ham.jl +++ b/src/simple_ham.jl @@ -5,7 +5,7 @@ export hamiltonian_cycle graph (if one exists) or an empty array (otherwise). This works reasonably well for small graphs. """ -function hamiltonian_cycle(G::SimpleGraph) +function hamiltonian_cycle(G::UndirectedGraph) if cache_check(G, :hamiltonian_cycle) return cache_recall(G, :hamiltonian_cycle) end @@ -41,7 +41,7 @@ function hamiltonian_cycle(G::SimpleGraph) end -function ham_extend(G::SimpleGraph, VV::Array, idx::Int, used::Dict, path::Array) +function ham_extend(G::UndirectedGraph, VV::Array, idx::Int, used::Dict, path::Array) # println(path[1:idx]) # debug n = NV(G) v = path[idx] diff --git a/src/simple_matrices.jl b/src/simple_matrices.jl index fcdb4af..3193e4f 100644 --- a/src/simple_matrices.jl +++ b/src/simple_matrices.jl @@ -14,7 +14,7 @@ and so forth. However, if the vertices are not sortable in this way, the mapping between vertices and rows/columns of the matrix is unpredictable. """ -function adjacency(G::SimpleGraph) +function adjacency(G::UndirectedGraph) n = NV(G) A = zeros(Int, (n, n)) @@ -39,7 +39,7 @@ adjacency matrix minus the (diagonal) degree matrix. See `adjacency` to understand how vertices correspond to rows/columns of the resulting matrix. """ -function laplace(G::SimpleGraph) +function laplace(G::UndirectedGraph) A = adjacency(G) d = collect(sum(A, dims = 1))[:] D = Matrix(Diagonal(d)) @@ -52,7 +52,7 @@ end normalized_laplace(G::SimpleGraph) Return the normalized Laplacian matrix of `G`. """ -function normalized_laplace(G::SimpleGraph)::Matrix{Float64} +function normalized_laplace(G::UndirectedGraph)::Matrix{Float64} n = NV(G) NL = zeros(Float64, (n, n)) d = vertex2idx(G) @@ -87,7 +87,7 @@ Notes: is undirected and an unsigned incidence matrix is desired, use `incidence(G,false)`. """ -function incidence(G::SimpleGraph, signed::Bool = true) +function incidence(G::UndirectedGraph, signed::Bool = true) n = NV(G) m = NE(G) M = spzeros(Int, n, m) @@ -174,6 +174,6 @@ adjacency matrix. More generally, `eigvals(G,mat)` returns the eigenvalues of `mat(G)` where `mat` is a matrix-valued function of `G`. In particular, one can use `mat(G,laplace)` to find the eigenvalues of `G`'s Laplacian. """ -function LinearAlgebra.eigvals(G::SimpleGraph, mat::Function = adjacency) +function LinearAlgebra.eigvals(G::UndirectedGraph, mat::Function = adjacency) return eigvals(mat(G)) end diff --git a/src/simple_ops.jl b/src/simple_ops.jl index 34b1f6d..bf6df75 100644 --- a/src/simple_ops.jl +++ b/src/simple_ops.jl @@ -6,7 +6,7 @@ export cartesian, lex, relabel, trim export disjoint_union, union, join, subdivide # check for graph equality -function SimpleGraphs.delete!(G::SimpleGraph, H::SimpleGraph) +function SimpleGraphs.delete!(G::UndirectedGraph, H::UndirectedGraph) if G.V != H.V || NE(G) != NE(H) return false end @@ -25,12 +25,12 @@ function SimpleGraphs.delete!(G::SimpleGraph, H::SimpleGraph) return G.E == H.E end -function SimpleGraphs.isequal(G::SimpleGraph, H::SimpleGraph) +function SimpleGraphs.isequal(G::UndirectedGraph, H::UndirectedGraph) return G.V == H.V && G.E == H.E end -function ==(G::SimpleGraph, H::SimpleGraph) +function ==(G::UndirectedGraph, H::UndirectedGraph) return isequal(G, H) end @@ -42,7 +42,7 @@ end of those vertices is not already in the graph, it is added to the vertex set. """ -function add!(G::SimpleGraph{T}, v) where {T} +function add!(G::UndirectedGraph{T}, v) where {T} if has(G, v) return false end @@ -55,7 +55,7 @@ function add!(G::SimpleGraph{T}, v) where {T} end # adding edges -function add!(G::SimpleGraph{T}, v, w) where {T} +function add!(G::UndirectedGraph{T}, v, w) where {T} if v == w return false end @@ -112,7 +112,7 @@ from the graph. `delete!(G,v,w)` deletes the edge `(v,w)` from `G`. """ -function SimpleGraphs.delete!(G::SimpleGraph, v, w) +function SimpleGraphs.delete!(G::UndirectedGraph, v, w) flag = false if has(G, v, w) cache_clear(G) @@ -128,7 +128,7 @@ function SimpleGraphs.delete!(G::SimpleGraph, v, w) end # vertex deletion -function SimpleGraphs.delete!(G::SimpleGraph, v) +function SimpleGraphs.delete!(G::UndirectedGraph, v) flag = false if has(G, v) cache_clear(G) @@ -159,7 +159,7 @@ Note: The edge `(u,v)` need not be present in the graph. If missing, this is equivalent to first adding the edge to the graph and then contracting it. """ -function contract!(G::SimpleGraph, u, v) +function contract!(G::UndirectedGraph, u, v) if !has(G, u) || !has(G, v) || u == v return false end @@ -178,14 +178,14 @@ end `induce(G,A)` creates the induced subgraph of `G` with vertices in the set `A`. The graph may be either a `SimpleGraph` or a `SimpleDigraph`. """ -function induce(G::SimpleGraph{T}, A::Set) where {T} +function induce(G::UndirectedGraph{T}, A::Set) where {T} # Check that A is a subset of V(G) for v in A if ~has(G, v) error("The set A must be a subset of V(G)") end end - H = SimpleGraph{T}() # place to hold the answer + H = UndirectedGraph{T}() # place to hold the answer # add all the vertices in A to H for v in A @@ -225,14 +225,14 @@ function induce(G::SimpleGraph{T}, A::Set) where {T} end # Digraph version -function induce(G::SimpleDigraph{T}, A::Set) where {T} +function induce(G::DirectedGraph{T}, A::Set) where {T} # Check that A is a subset of V(G) for v in A if ~has(G, v) error("The set A must be a subset of V(G)") end end - H = SimpleDigraph{T}() # place to hold the answer + H = DirectedGraph{T}() # place to hold the answer # add all the vertices in A to H for v in A @@ -256,8 +256,8 @@ end """ `line_graph(G)` creates the line graph of `G`. """ -function line_graph(G::SimpleGraph{T}) where {T} - H = SimpleGraph{Tuple{T,T}}() +function line_graph(G::UndirectedGraph{T}) where {T} + H = UndirectedGraph{Tuple{T,T}}() m = NE(G) E = elist(G) @@ -282,8 +282,8 @@ end `complement(G)` creates (as a new graph) the complement of `G`. Note that `G'` is a short cut for `complement(G)`. """ -function complement(G::SimpleGraph{T}) where {T} - H = SimpleGraph{T}() +function complement(G::UndirectedGraph{T}) where {T} + H = UndirectedGraph{T}() V = vlist(G) n = NV(G) @@ -310,13 +310,13 @@ end """ `G'` is equivalent to `complement(G)`. """ -adjoint(G::SimpleGraph) = complement(G) +adjoint(G::UndirectedGraph) = complement(G) # complement in place. Returns None. """ `complement!(G)` replaces `G` with its complement. """ -function complement!(G::SimpleGraph) +function complement!(G::UndirectedGraph) name_flag = cache_check(G, :name) name_hold = "" if name_flag @@ -347,8 +347,8 @@ end `cartesian(G,H)` creates the Cartesian product of the two graphs. This can be abbreviated as `G*H`. """ -function cartesian(G::SimpleGraph{S}, H::SimpleGraph{T}) where {S,T} - K = SimpleGraph{Tuple{S,T}}() +function cartesian(G::UndirectedGraph{S}, H::UndirectedGraph{T}) where {S,T} + K = UndirectedGraph{Tuple{S,T}}() for v in G.V for w in H.V add!(K, (v, w)) @@ -376,7 +376,7 @@ end """ For `SimpleGraph`s: `G*H` is equivalent to `cartesian(G,H)`. """ -function *(G::SimpleGraph{S}, H::SimpleGraph{T}) where {S,T} +function *(G::UndirectedGraph{S}, H::UndirectedGraph{T}) where {S,T} return cartesian(G, H) end @@ -389,7 +389,7 @@ end This may also be invoked as `G ∨ H`. """ -function join(G::SimpleGraph{S}, H::SimpleGraph{T}) where {S,T} +function join(G::UndirectedGraph{S}, H::UndirectedGraph{T}) where {S,T} K = disjoint_union(G, H) for v in G.V for w in H.V @@ -399,7 +399,7 @@ function join(G::SimpleGraph{S}, H::SimpleGraph{T}) where {S,T} return K end -(∨)(G::SimpleGraph, H::SimpleGraph) = join(G, H) +(∨)(G::UndirectedGraph, H::UndirectedGraph) = join(G, H) export (∨) # Create the union of two graphs. If they have vertices or edges in @@ -409,11 +409,11 @@ export (∨) `union(G,H)` creates the union of the graphs `G` and `H`. The graphs may (and typically do) have common vertices or edges. """ -function union(G::SimpleGraph{S}, H::SimpleGraph{T}) where {S,T} +function union(G::UndirectedGraph{S}, H::UndirectedGraph{T}) where {S,T} if S == T - K = SimpleGraph{S}() + K = UndirectedGraph{S}() else - K = SimpleGraph{Any}() + K = UndirectedGraph{Any}() end for v in G.V @@ -436,7 +436,7 @@ end # a new graph in which the name of each vertex has an integer # appended. For example, if the vertex type is String in the original # graph, the new vertices are type (String, Int). -function label_append(G::SimpleGraph{S}, a::Int) where {S} +function label_append(G::UndirectedGraph{S}, a::Int) where {S} mapper = Dict{S,Tuple{S,Int}}() for v in G.V mapper[v] = (v, a) @@ -451,12 +451,12 @@ end `disjoint_union(G,H)` is a new graph formed by taking disjoint copies of `G` and `H` (and no additional edges). """ -function disjoint_union(G::SimpleGraph{S}, H::SimpleGraph{T}) where {S,T} +function disjoint_union(G::UndirectedGraph{S}, H::UndirectedGraph{T}) where {S,T} GG = label_append(G, 1) HH = label_append(H, 2) ST = typejoin(S, T) - K = SimpleGraph{Tuple{ST,Int}}() + K = UndirectedGraph{Tuple{ST,Int}}() for v in GG.V add!(K, v) @@ -476,13 +476,13 @@ end # G+H is an abbreviation for disjoint_union(G,H) -(+)(G::SimpleGraph, H::SimpleGraph) = disjoint_union(G, H) +(+)(G::UndirectedGraph, H::UndirectedGraph) = disjoint_union(G, H) -function (*)(k::Integer, G::SimpleGraph{T}) where {T} +function (*)(k::Integer, G::UndirectedGraph{T}) where {T} @assert k >= 0 "In k*G for integer k and graph G, k must be nonnegative" TT = Tuple{T,Int} - GG = SimpleGraph{TT}() + GG = UndirectedGraph{TT}() for i = 1:k for v in G.V @@ -513,7 +513,7 @@ end vertices of degree `d` or smaller. For example, if `G` is a tree, `trim(G,1)` will eventually remove all vertices. """ -function trim(G::SimpleGraph, d::Int = 0) +function trim(G::UndirectedGraph, d::Int = 0) H = deepcopy(G) while NV(H) > 0 && minimum(deg(H)) <= d for v in H.V @@ -535,8 +535,8 @@ end `relabel(G,d)` (where `d` is a `Dict`) returns a copy of `G` in which vertex `v` is renamed `d[v]`. """ -function relabel(G::SimpleGraph{S}, label::Dict{S,T}) where {S,T} - H = SimpleGraph{T}() +function relabel(G::UndirectedGraph{S}, label::Dict{S,T}) where {S,T} + H = UndirectedGraph{T}() for v in G.V add!(H, label[v]) end @@ -550,7 +550,7 @@ function relabel(G::SimpleGraph{S}, label::Dict{S,T}) where {S,T} end # Relabel the vertices with the integers 1:n -function relabel(G::SimpleGraph{S}) where {S} +function relabel(G::UndirectedGraph{S}) where {S} verts = vlist(G) n = length(verts) label = Dict{S,Int}() @@ -574,9 +574,9 @@ and `h~h'`. We can use the notation `G[H]` also to create `lex(G,H)`. """ -function lex(G::SimpleGraph{S}, H::SimpleGraph{T}) where {S,T} +function lex(G::UndirectedGraph{S}, H::UndirectedGraph{T}) where {S,T} VT = Tuple{S,T} - K = SimpleGraph{VT}() + K = UndirectedGraph{VT}() # Create vertex set for a in G.V for b in H.V @@ -611,16 +611,16 @@ end """ Abbreviation for `lex(G,H)` for `SimpleGraph`s. """ -getindex(G::SimpleGraph, H::SimpleGraph) = lex(G, H) +getindex(G::UndirectedGraph, H::UndirectedGraph) = lex(G, H) """ `subdivide(G::SimpleGraph)` creates a new `SimpleGraph` by replacing every edge with a path of length two. """ -function subdivide(G::SimpleGraph{T}) where {T} +function subdivide(G::UndirectedGraph{T}) where {T} TT = Tuple{T,T} - H = SimpleGraph{TT}() + H = UndirectedGraph{TT}() for v in G.V add!(H, (v, v)) diff --git a/src/trans_orient.jl b/src/trans_orient.jl index 271ad2b..c74a812 100644 --- a/src/trans_orient.jl +++ b/src/trans_orient.jl @@ -8,13 +8,13 @@ export transitive_orientation simple graph `G`. The result is a `SimpleDigraph`. An error is raised if `G` does not have a transitive orientation. """ -function transitive_orientation(G::SimpleGraph) +function transitive_orientation(G::UndirectedGraph) err_msg = "This graph does not have a transitive orientation" vertices = deepcopy(vlist(G)) edges = deepcopy(elist(G)) V = eltype(G) diredges = Tuple{V,V}[] - D = SimpleDigraph{V}() + D = DirectedGraph{V}() while length(diredges) != 0 || length(edges) != 0 if length(diredges) == 0 e = popfirst!(edges) @@ -62,7 +62,7 @@ export num_trans_orientations `num_trans_orientations(G)` returns the number of transitive orientations of the graph `G`. """ -function num_trans_orientations(G2::SimpleGraph) +function num_trans_orientations(G2::UndirectedGraph) if cache_check(G2, :num_trans_orientations) return cache_recall(G2, :num_trans_orientations) end @@ -86,7 +86,7 @@ function num_trans_orientations(G2::SimpleGraph) return ans end -function makeSimplex!(G::SimpleGraph, multiplexes::Array, col::Dict) +function makeSimplex!(G::UndirectedGraph, multiplexes::Array, col::Dict) edge = elist(G)[1] vert1 = edge[1] vert2 = edge[2] @@ -127,21 +127,21 @@ function makeSimplex!(G::SimpleGraph, multiplexes::Array, col::Dict) end end -function makeColorClass(G1::SimpleGraph) +function makeColorClass(G1::UndirectedGraph) err_msg = "error" G = deepcopy(G1) vertices = deepcopy(vlist(G)) edge = deepcopy(elist(G)) V = eltype(G) diredge = Tuple{V,V}[] - D = SimpleDigraph{V}() - E = SimpleGraph{V}() - classes = SimpleGraph{V}[] + D = DirectedGraph{V}() + E = UndirectedGraph{V}() + classes = UndirectedGraph{V}[] while length(diredge) != 0 || length(edge) != 0 if length(diredge) == 0 if length(elist(E)) != 0 pushfirst!(classes, E) - E1 = SimpleGraph{V}() + E1 = UndirectedGraph{V}() E = E1 end e = popfirst!(edge) diff --git a/src/twins.jl b/src/twins.jl index 1aeafcc..c850041 100644 --- a/src/twins.jl +++ b/src/twins.jl @@ -7,7 +7,7 @@ That is, if `G[u]-v == G[v]-u`. This is an equivalence relation. `twins(G)` returns a partition of the graph's vertex set into twin equivalence classes. """ -function twins(G::SimpleGraph, u, v)::Bool +function twins(G::UndirectedGraph, u, v)::Bool @assert has(G, u) "vertex $u not in the graph" @assert has(G, v) "vertex $v not in the graph"