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

Docs #567

Merged
merged 2 commits into from
Mar 27, 2017
Merged

Docs #567

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 34 additions & 91 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ better-optimized mechanisms.

Additional functionality may be found in the companion package [LightGraphsExtras.jl](https://github.com/JuliaGraphs/LightGraphsExtras.jl).


## Documentation
Full documentation is available at [GitHub Pages](https://juliagraphs.github.io/LightGraphs.jl/latest).
Documentation for methods is also available via the Julia REPL help system.
Expand All @@ -38,91 +39,26 @@ A graph *G* is described by a set of vertices *V* and edges *E*:
*G = {V, E}*. *V* is an integer range `1:n`; *E* is represented as forward
(and, for directed graphs, backward) adjacency lists indexed by vertices. Edges
may also be accessed via an iterator that yields `Edge` types containing
`(src::Int, dst::Int)` values.
`(src<:Integer, dst<:Integer)` values. Both vertices and edges may be integers
of any type, and the smallest type that fits the data is recommended in order
to save memory.

*LightGraphs.jl* provides two graph types: `Graph` is an undirected graph, and
`DiGraph` is its directed counterpart.

Graphs are created using `Graph()` or `DiGraph()`; there are several options
(see below for examples).

Edges are added to a graph using `add_edge!(g, e)`. Instead of an edge type
integers may be passed denoting the source and destination vertices (e.g.,
`add_edge!(g, 1, 2)`).
(see the tutorials for examples).

Multiple edges between two given vertices are not allowed: an attempt to
add an edge that already exists in a graph will result in a silent failure.

Edges may be removed using `rem_edge!(g, e)`. Alternately, integers may be passed
denoting the source and destination vertices (e.g., `rem_edge!(g, 1, 2)`). Note
that, particularly for very large graphs, edge removal is a (relatively)
expensive operation. An attempt to remove an edge that does not exist in the graph will result in an
error.

Use `nv(g)` and `ne(g)` to compute the number of vertices and edges respectively.

`rem_vertex!(g, v)` alters the vertex identifiers. In particular, calling `n=nv(g)`, it swaps `v` and `n` and then removes `n`.

`edges(g)` returns an iterator to the edge set. Use `collect(edge(set))` to fill
an array with all edges in the graph.

## Installation
Installation is straightforward:
```julia
julia> Pkg.add("LightGraphs")
```

## Usage Examples
(all examples apply equally to `DiGraph` unless otherwise noted):

```julia
# create an empty undirected graph
g = Graph()

# create a 10-node undirected graph with no edges
g = Graph(10)
@assert nv(g) == 10

# create a 10-node undirected graph with 30 randomly-selected edges
g = Graph(10,30)

# add an edge between vertices 4 and 5
add_edge!(g, 4, 5)

# remove an edge between vertices 9 and 10
rem_edge!(g, 9, 10)

# create vertex 11
add_vertex!(g)

# remove vertex 2
# attention: this changes the id of vertex nv(g) to 2
rem_vertex!(g, 2)

# get the neighbors of vertex 4
neighbors(g, 4)

# iterate over the edges
m = 0
for e in edges(g)
m += 1
end
@assert m == ne(g)

# show distances between vertex 4 and all other vertices
dijkstra_shortest_paths(g, 4).dists

# as above, but with non-default edge distances
distmx = zeros(10,10)
distmx[4,5] = 2.5
distmx[5,4] = 2.5
dijkstra_shortest_paths(g, 4, distmx).dists

# graph I/O
g = loadgraph("mygraph.jgz", :lg)
savegraph("mygraph.gml", g, :gml)
```

## Current functionality
- **core functions:** vertices and edges addition and removal, degree (in/out/histogram), neighbors (in/out/all/common)

Expand Down Expand Up @@ -155,37 +91,43 @@ symmetric difference, blkdiag, induced subgraphs, products (cartesian/scalar)

- **community:** modularity, community detection, core-periphery, clustering coefficients

- **persistence formats:** proprietary compressed, [GraphML](http://en.wikipedia.org/wiki/GraphML), [GML](https://en.wikipedia.org/wiki/Graph_Modelling_Language), [Gexf](http://gexf.net/format), [DOT](https://en.wikipedia.org/wiki/DOT_(graph_description_language)), [Pajek NET](http://gephi.org/users/supported-graph-formats/pajek-net-format/)
- **persistence formats:** proprietary compressed, [GraphML](http://en.wikipedia.org/wiki/GraphML), [GML](https://en.wikipedia.org/wiki/Graph_Modelling_Language), [Gexf](http://gexf.net/format), [DOT](https://en.wikipedia.org/wiki/DOT_(graph_description_language)), [Pajek NET](http://gephi.org/users/supported-graph-formats/pajek-net-format/), [Graph6](http://users.cecs.anu.edu.au/~bdm/data/formats.html)

- **visualization:** integration with [GraphLayout](https://github.com/IainNZ/GraphLayout.jl), [TikzGraphs](https://github.com/sisl/TikzGraphs.jl), [GraphPlot](https://github.com/JuliaGraphs/GraphPlot.jl), [NetworkViz](https://github.com/abhijithanilkumar/NetworkViz.jl/)
- **visualization:** integration with
[GraphPlot](https://github.com/JuliaGraphs/GraphPlot.jl),
[Plots](https://github.com/JuliaPlots/Plots.jl) via [PlotRecipes](https://github.com/JuliaPlots/PlotRecipes.jl), [GraphLayout](https://github.com/IainNZ/GraphLayout.jl), [TikzGraphs](https://github.com/sisl/TikzGraphs.jl), [NetworkViz](https://github.com/abhijithanilkumar/NetworkViz.jl/)


## Core API
These functions are defined as the public contract of the LightGraphs.AbstractGraph interface.
These functions are defined as the public contract of the `LightGraphs.AbstractGraph` interface.

### Constructing and modifying the graph

- add_edge!
- rem_edge!
- add_vertex!
- add_vertices!
- rem_vertex!
- `Graph`
- `DiGraph`
- `add_edge!`
- `rem_edge!`
- `add_vertex!`, `add_vertices!`
- `rem_vertex!`
- `zero`

### Edge/Arc interface
- src
- dst
- `src`
- `dst`
- `reverse`
- `==`
- Pair / Tuple conversion

### Accessing state
- nv::Int
- ne::Int
- vertices (Iterable)
- edges (Iterable)
- neighbors
- in_edges
- out_edges
- has_vertex
- has_edge
- has_self_loops (though this might be a trait or an abstract graph type)
- `nv`
- `ne`
- `vertices` (Iterable)
- `edges` (Iterable)
- `neighbors`, `in_neighbors`, `out_neighbors`
- `in_edges`
- `out_edges`
- `has_vertex`
- `has_edge`
- `has_self_loops` (though this might be a trait or an abstract graph type)


### Non-Core APIs
Expand All @@ -202,7 +144,8 @@ This can be computed from neighbors by default `degree(g,v) = length(neighbors(g
* Julia 0.3: LightGraphs v0.3.7 is the last version guaranteed to work with Julia 0.3.
* Julia 0.4: LightGraphs versions in the 0.6 series are designed to work with Julia 0.4.
* Julia 0.5: LightGraphs versions in the 0.7 series are designed to work with Julia 0.5.
* Julia 0.6: Some functionality might not work with prerelease / unstable / nightly versions of Julia. If you run into a problem on 0.6, please file an issue.
* Julia 0.6: LightGraphs versions in the 1.0 series are designed to work with Julia 0.6.
* Later versions: Some functionality might not work with prerelease / unstable / nightly versions of Julia. If you run into a problem, please file an issue.

# Contributing and Reporting Bugs
We welcome contributions and bug reports! Please see [CONTRIBUTING.md](https://github.com/JuliaGraphs/LightGraphs.jl/blob/master/CONTRIBUTING.md)
Expand Down
9 changes: 8 additions & 1 deletion src/LightGraphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ kruskal_mst, prim_mst,
#biconnectivity and articulation points
articulation, biconnected_components

"""An optimized graphs package.
"""
LightGraphs

An optimized graphs package.

Simple graphs (not multi- or hypergraphs) are represented in a memory- and
time-efficient manner with adjacency lists and edge sets. Both directed and
Expand All @@ -131,6 +134,10 @@ explicit design decision that any data not required for graph manipulation
(attributes and other information, for example) is expected to be stored
outside of the graph structure itself. Such data lends itself to storage in
more traditional and better-optimized mechanisms.

[Full documentation](http://codecov.io/github/JuliaGraphs/LightGraphs.jl) is available,
and tutorials are available at the
[JuliaGraphsTutorials repository](https://github.com/JuliaGraphs/JuliaGraphsTutorials).
"""
LightGraphs
include("interface.jl")
Expand Down
39 changes: 23 additions & 16 deletions src/biconnectivity/articulation.jl
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
"""
Computes the articulation points(https://en.wikipedia.org/wiki/Biconnected_component)
of a connected graph `g` and returns an array containing all cut vertices.
"""
function articulation(g::AbstractGraph)
state = Articulations(g)
for u in vertices(g)
if state.depth[u] == 0
visit!(state, g, u, u)
end
end
return find(state.articulation_points)
end
Articulations{T}

"""
Articulations: a state type for the Depth first search that finds the articulation points in a graph.
A state type for the depth-first search that finds the articulation points in a graph.
"""
mutable struct Articulations{T<:Integer}
low::Vector{T}
Expand All @@ -29,8 +17,11 @@ function Articulations(g::AbstractGraph)
end

"""
Does a depth first search storing the depth (in `depth`) and low-points (in `low`) of each vertex.
Call this function repeatedly to complete the DFS see `articulation` for usage.
visit!(state, g, u, v)

Perform a depth first search storing the depth (in `depth`) and low-points
(in `low`) of each vertex.
Call this function repeatedly to complete the DFS (see [`articulation`](@ref) for usage).
"""
function visit!(state::Articulations, g::AbstractGraph, u::Integer, v::Integer)
children = 0
Expand All @@ -56,3 +47,19 @@ function visit!(state::Articulations, g::AbstractGraph, u::Integer, v::Integer)
state.articulation_points[v] = true
end
end

"""
articulation(g)

Compute the [articulation points](https://en.wikipedia.org/wiki/Biconnected_component)
of a connected graph `g` and return an array containing all cut vertices.
"""
function articulation(g::AbstractGraph)
state = Articulations(g)
for u in vertices(g)
if state.depth[u] == 0
visit!(state, g, u, u)
end
end
return find(state.articulation_points)
end
54 changes: 32 additions & 22 deletions src/biconnectivity/biconnect.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""
Biconnections: A state type for Depth First Search that finds the biconnected components
Biconnections

A state type for depth-first search that finds the biconnected components.
"""
mutable struct Biconnections
low::Vector{Int}
Expand All @@ -14,29 +16,11 @@ end
return Biconnections(zeros(Int, n), zeros(Int, n), Vector{Edge}(), Vector{Vector{Edge}}(), 0)
end

"""
Computes the biconnected components of an undirected graph `g`
and returns a Vector of vectors containing each biconnected component.
(https://en.wikipedia.org/wiki/Biconnected_component).It's a DFS based linear time algorithm.
"""
function biconnected_components end
@traitfn function biconnected_components(g::::(!IsDirected))
state = Biconnections(g)
for u in vertices(g)
if state.depth[u] == 0
visit!(g, state, u, u)
end

if !isempty(state.stack)
push!(state.biconnected_comps, reverse(state.stack))
empty!(state.stack)
end
end
return state.biconnected_comps
end

"""
Does a DFS visit and stores the depth and low-points of each vertex
visit!(g, state, u, v)

Perform a DFS visit storing the depth and low-points of each vertex.
"""
function visit!(g::AbstractGraph, state::Biconnections, u::Integer, v::Integer)
children = 0
Expand Down Expand Up @@ -68,3 +52,29 @@ function visit!(g::AbstractGraph, state::Biconnections, u::Integer, v::Integer)
end
end
end

@doc_str """
biconnected_components(g)

Compute the [biconnected components](https://en.wikipedia.org/wiki/Biconnected_component)
of an undirected graph `g`and return a vector of vectors containing each
biconnected component.

Performance:
Time complexity is ``\\mathcal{O}(|V|)``.
"""
function biconnected_components end
@traitfn function biconnected_components(g::::(!IsDirected))
state = Biconnections(g)
for u in vertices(g)
if state.depth[u] == 0
visit!(g, state, u, u)
end

if !isempty(state.stack)
push!(state.biconnected_comps, reverse(state.stack))
empty!(state.stack)
end
end
return state.biconnected_comps
end
Loading