I wanted to play with some graphs (as in graph theory) and noticed two prominent Julia packages: LightGraphs (and the whole JuliaGraphs ecosystem) and SimpleGraphs. The latter only being available via cloning the github repository, but has been updated for Julia 1.0.
Just wondered if people had thoughts on which is better to use for a short-term project.
Thanks! I just didn’t know if there was a solid reason for preferring SimpleGraphs over the more developed LightGraphs. A doc comparison is sound advice.
One big difference is that SimpleGraphs apparently allows you to index vertices with any type. (I say “apparently” because I haven’t actually tried it.) LightGraphs uses integers for vertex indices. Not only that, but the indices in LightGraphs must be one-based and contiguous.
The benefit of that apparent (in theory, but not generally in practice) drawback is that LightGraphs is significantly faster than other graph packages out there and can scale to very large graphs. We haven’t done explicit testing against SimpleGraphs, but just looking at the data structures that are being used I can tell we scale to larger graphs (since it takes us at most 40 8 bytes to store up to 2^64 vertices, where SimpleGraphs records each vertex in a set) (edit: it’s a bit more complicated than this, and so not accurate - the real space savings comes in when you start adding edges), and when the SimpleGraphs neighborhood optimizations are disabled, our neighbors checks (which are important for things that rely on BFS) are faster (O(deg(v)) vs O(|V|)).
I say “in practice” because there are few applications that can’t actually limit themselves to 1:n vertices; and with MetaGraphs, most of this problem is mooted (at the expense of some more time and space complexity).
Still, it may be that your specific problem requires the combination of advantages that SimpleGraphs provides over LightGraphs. If that turns out to be the case, I’d love to hear about it (via GitHub issue over in LightGraphs) so we can explore how to make LG even better.
Oh wow, I hadn’t seen SimpleGraphs. I had been looking for something compiler-like dependencies. I could use LightGraphs, but then I’d have to worry about tracking the bijective map between Symbols and Ints. There’s no “bimap” package I can find, so this was going to be a big distraction from my main goal.
Depends on what, specifically, you need to do with the metadata. You can filter the graph by any of the vertex properties, for example, and need not concern yourself with the underlying int representation. Here’s a small example:
julia> g = PathDiGraph(5)
{5, 4} directed simple Int64 graph
julia> m = MetaDiGraph(g)
{5, 4} directed Int64 metagraph with Float64 weights defined by :weight (default weight 1.0)
julia> vnames = ["red", "red", "red", "blue", "blue"];
julia> for (i, v) in enumerate(vertices(m)) # technically not needed, but we're trying to avoid using vertices as ints
set_prop!(m, v, :name, vnames[i])
end
julia> redverts = filter_vertices(m, :name, "red");
julia> m2 = m[redverts] # induce the subgraph of only red vertices
{3, 2} directed Int64 metagraph with Float64 weights defined by :weight (default weight 1.0)
julia> for v in vertices(m2)
println(get_prop(m2, v, :name))
end
red
red
red
Biggest thing I need is to “postwalk” a program and add a directed edge when I see an assignment. Something like addedge!(g, :a, :b)
without specifying the number of vertices in advance would be really great.