Skip to content
This repository has been archived by the owner on Oct 21, 2021. It is now read-only.

Commit

Permalink
Merge pull request #106 from JuliaLang/kms/general_vertex_types
Browse files Browse the repository at this point in the history
RFC: Allow general vertex types (fixes #105)
  • Loading branch information
kmsquire committed May 31, 2014
2 parents 675885c + 98db3e3 commit 3231261
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 148 deletions.
7 changes: 3 additions & 4 deletions src/adjacency_list.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,17 @@ is_directed(g::GenericAdjacencyList) = g.is_directed

num_vertices(g::GenericAdjacencyList) = length(g.vertices)
vertices(g::GenericAdjacencyList) = g.vertices
vertex_index{V}(v::V, g::GenericAdjacencyList{V}) = vertex_index(v)
vertex_index{V<:ProvidedVertexType}(v::V, g::GenericAdjacencyList{V}) = vertex_index(v)

num_edges(g::GenericAdjacencyList) = g.nedges

out_degree{V}(v::V, g::GenericAdjacencyList{V}) = length(g.adjlist[vertex_index(v)])
out_neighbors{V}(v::V, g::GenericAdjacencyList{V}) = g.adjlist[vertex_index(v)]
out_degree{V}(v::V, g::GenericAdjacencyList{V}) = length(g.adjlist[vertex_index(v,g)])
out_neighbors{V}(v::V, g::GenericAdjacencyList{V}) = g.adjlist[vertex_index(v,g)]


## mutation

function add_vertex!{V}(g::GenericAdjacencyList{V}, v::V)
@assert vertex_index(v) == num_vertices(g) + 1
push!(g.vertices, v)
push!(g.adjlist, Array(V,0))
v
Expand Down
11 changes: 11 additions & 0 deletions src/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ make_vertex(g::AbstractGraph{ExVertex}, label::String) = ExVertex(num_vertices(g
vertex_index(v::ExVertex) = v.index
attributes(v::ExVertex, g::AbstractGraph) = v.attributes

typealias ProvidedVertexType Union(Integer, KeyVertex, ExVertex)

# vertex_index for (V !<: ProvidedVertexType)

function vertex_index{V}(v::V, g::AbstractGraph{V})
@graph_requires g vertex_list
return vertex_index(v, vertices(g))
end

vertex_index(v, vs::AbstractArray) = findfirst(vs, v)


#################################################
#
Expand Down
12 changes: 6 additions & 6 deletions src/dot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,24 @@ function to_dot{G<:AbstractGraph}(graph::G, stream::IO)
write(stream, "$(graph_type_string(graph)) graphname {\n")
if implements_edge_list(graph)
for edge in edges(graph)
write(stream,"$(vertex_index(source(edge))) $(edge_op(graph)) $(vertex_index(target(edge)))\n")
write(stream,"$(vertex_index(source(edge), graph)) $(edge_op(graph)) $(vertex_index(target(edge), graph))\n")
end
elseif implements_vertex_list(graph) && (implements_incidence_list(graph) || implements_adjacency_list(graph))
for vertex in vertices(graph)
if has_vertex_attrs && !isempty(attributes(vertex, graph))
write(stream, "$(vertex_index(vertex)) $(to_dot(attributes(vertex, graph)))\n")
write(stream, "$(vertex_index(vertex, graph)) $(to_dot(attributes(vertex, graph)))\n")
end
if implements_incidence_list(graph)
for e in out_edges(vertex, graph)
n = target(e, graph)
if is_directed(graph) || vertex_index(n) > vertex_index(vertex)
write(stream,"$(vertex_index(vertex)) $(edge_op(graph)) $(vertex_index(n))$(has_edge_attrs ? string(" ", to_dot(attributes(e, graph))) : "")\n")
if is_directed(graph) || vertex_index(n, graph) > vertex_index(vertex, graph)
write(stream,"$(vertex_index(vertex, graph)) $(edge_op(graph)) $(vertex_index(n, graph))$(has_edge_attrs ? string(" ", to_dot(attributes(e, graph))) : "")\n")
end
end
else # implements_adjacency_list
for n in out_neighbors(vertex, graph)
if is_directed(graph) || vertex_index(n) > vertex_index(vertex)
write(stream,"$(vertex_index(vertex)) $(edge_op(graph)) $(vertex_index(n))\n")
if is_directed(graph) || vertex_index(n, graph) > vertex_index(vertex, graph)
write(stream,"$(vertex_index(vertex, graph)) $(edge_op(graph)) $(vertex_index(n))\n")
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion src/edge_list.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ is_directed(g::GenericEdgeList) = g.is_directed

num_vertices(g::GenericEdgeList) = length(g.vertices)
vertices(g::GenericEdgeList) = g.vertices
vertex_index(v, g::GenericEdgeList) = vertex_index(v)
vertex_index{V<:ProvidedVertexType}(v::V, g::GenericEdgeList{V}) = vertex_index(v)

num_edges(g::GenericEdgeList) = length(g.edges)
edges(g::GenericEdgeList) = g.edges
Expand Down
8 changes: 3 additions & 5 deletions src/graph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,22 +55,21 @@ vertices(g::GenericGraph) = g.vertices
num_edges(g::GenericGraph) = length(g.edges)
edges(g::GenericGraph) = g.edges

vertex_index{V}(v::V, g::GenericGraph{V}) = vertex_index(v)
vertex_index{V<:ProvidedVertexType}(v::V, g::GenericGraph{V}) = vertex_index(v)
edge_index{V,E}(e::E, g::GenericGraph{V,E}) = edge_index(e)

out_edges{V}(v::V, g::GenericGraph{V}) = g.finclist[vertex_index(v)]
out_edges{V}(v::V, g::GenericGraph{V}) = g.finclist[vertex_index(v, g)]
out_degree{V}(v::V, g::GenericGraph{V}) = length(out_edges(v, g))
out_neighbors{V}(v::V, g::GenericGraph{V}) = TargetIterator(g, out_edges(v, g))

in_edges{V}(v::V, g::GenericGraph{V}) = g.binclist[vertex_index(v)]
in_edges{V}(v::V, g::GenericGraph{V}) = g.binclist[vertex_index(v, g)]
in_degree{V}(v::V, g::GenericGraph{V}) = length(in_edges(v, g))
in_neighbors{V}(v::V, g::GenericGraph{V}) = SourceIterator(g, in_edges(v, g))


# mutation

function add_vertex!{V}(g::GenericGraph{V}, v::V)
@assert vertex_index(v) == num_vertices(g) + 1
push!(g.vertices, v)
push!(g.finclist, Int[])
push!(g.binclist, Int[])
Expand All @@ -80,7 +79,6 @@ add_vertex!{V}(g::GenericGraph{V}, x) = add_vertex!(g, make_vertex(g, x))

function add_edge!{V,E}(g::GenericGraph{V,E}, u::V, v::V, e::E)
# add an edge e between u and v
@assert edge_index(e) == num_edges(g) + 1
ui = vertex_index(u, g)::Int
vi = vertex_index(v, g)::Int

Expand Down
10 changes: 3 additions & 7 deletions src/incidence_list.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,16 @@ vertices(g::GenericIncidenceList) = g.vertices

num_edges(g::GenericIncidenceList) = g.nedges

vertex_index{V}(v::V, g::GenericIncidenceList{V}) = vertex_index(v)
vertex_index{V<:ProvidedVertexType}(v::V, g::GenericIncidenceList{V}) = vertex_index(v)
edge_index{V,E}(e::E, g::GenericIncidenceList{V,E}) = edge_index(e)

out_edges{V}(v::V, g::GenericIncidenceList{V}) = g.inclist[vertex_index(v)]
out_edges{V}(v::V, g::GenericIncidenceList{V}) = g.inclist[vertex_index(v, g)]
out_degree{V}(v::V, g::GenericIncidenceList{V}) = length(out_edges(v, g))
out_neighbors{V}(v::V, g::GenericIncidenceList{V}) = TargetIterator(g, g.inclist[vertex_index(v)])
out_neighbors{V}(v::V, g::GenericIncidenceList{V}) = TargetIterator(g, g.inclist[vertex_index(v, g)])

# mutation

function add_vertex!{V,E}(g::GenericIncidenceList{V,E}, v::V)
iv::Int = vertex_index(v)
if iv != num_vertices(g) + 1
throw(ArgumentError("Invalid vertex index."))
end
push!(g.vertices, v)
push!(g.inclist, Array(E,0))
v
Expand Down
44 changes: 23 additions & 21 deletions test/adjlist.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,34 +68,36 @@ end

# adjacency list with key vertices

g = adjlist(KeyVertex{ASCIIString})
for g in [adjlist(KeyVertex{ASCIIString}), adjlist(ASCIIString)]

vs = [ add_vertex!(g, "a"),
add_vertex!(g, "b"),
add_vertex!(g, "c") ]
vs = [ add_vertex!(g, "a"),
add_vertex!(g, "b"),
add_vertex!(g, "c") ]

@test num_vertices(g) == 3

@test num_vertices(g) == 3
for i = 1 : 3
v = vs[i]
@test vertices(g)[i] == v
@test !isa(v, KeyVertex) || v.index == i
@test out_degree(v, g) == 0
end

for i = 1 : 3
v = vs[i]
@test vertices(g)[i] == v
@test v.index == i
@test out_degree(v, g) == 0
end
add_edge!(g, vs[1], vs[2])
add_edge!(g, vs[1], vs[3])
add_edge!(g, vs[2], vs[3])

add_edge!(g, vs[1], vs[2])
add_edge!(g, vs[1], vs[3])
add_edge!(g, vs[2], vs[3])
@test num_edges(g) == 3

@test num_edges(g) == 3
@test out_degree(vs[1], g) == 2
@test out_degree(vs[2], g) == 1
@test out_degree(vs[3], g) == 0

@test out_degree(vs[1], g) == 2
@test out_degree(vs[2], g) == 1
@test out_degree(vs[3], g) == 0
@test out_neighbors(vs[1], g) == [vs[2], vs[3]]
@test out_neighbors(vs[2], g) == [vs[3]]
@test isempty(out_neighbors(vs[3], g))

@test out_neighbors(vs[1], g) == [vs[2], vs[3]]
@test out_neighbors(vs[2], g) == [vs[3]]
@test isempty(out_neighbors(vs[3], g))
end

# # construct via adjacency matrix
# A = [true true true; false false true; false false true]
Expand Down
28 changes: 15 additions & 13 deletions test/edgelist.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,24 @@ gu = simple_edgelist(5, eds; is_directed=false)

## edge list (based on vector of vertices)

g = edgelist(ExVertex[], ExEdge{ExVertex}[])
for T in [ ExVertex, ASCIIString ]
g = edgelist(T[], ExEdge{T}[])

vs = [ add_vertex!(g, "a"),
add_vertex!(g, "b"),
add_vertex!(g, "c") ]
vs = [ add_vertex!(g, "a"),
add_vertex!(g, "b"),
add_vertex!(g, "c") ]

es = [ add_edge!(g, vs[1], vs[2]),
add_edge!(g, vs[1], vs[3]) ]
es = [ add_edge!(g, vs[1], vs[2]),
add_edge!(g, vs[1], vs[3]) ]

@test vertex_type(g) == ExVertex
@test edge_type(g) == ExEdge{ExVertex}
@test is_directed(g)
@test vertex_type(g) == T
@test edge_type(g) == ExEdge{T}
@test is_directed(g)

@test num_vertices(g) == 3
@test vertices(g) == vs
@test num_vertices(g) == 3
@test vertices(g) == vs

@test num_edges(g) == 2
@test edges(g) == es
@test num_edges(g) == 2
@test edges(g) == es
end

Loading

0 comments on commit 3231261

Please sign in to comment.