Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate combinatorial algorithms from GraphsFlows.jl #240

Closed
wants to merge 2 commits into from
Closed
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
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ pages_files = [
"algorithms/traversals.md",
"algorithms/utils.md",
"algorithms/vertexcover.md",
"algorithms/flows.md",
],
"For advanced users" => [
"advanced/errorhandling.md",
Expand Down
76 changes: 76 additions & 0 deletions docs/src/algorithms/flows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# GraphsFlows

[![CI](https://github.com/JuliaGraphs/Graphs.jl/actions/workflows/ci.yml/badge.svg)](https://github.com/JuliaGraphs/Graphs.jl/actions/workflows/ci.yml)
[![codecov.io](http://codecov.io/github/JuliaGraphs/Graphs.jl/coverage.svg?branch=master)](http://codecov.io/github/JuliaGraphs/Graphs.jl?branch=master)
[![](https://img.shields.io/badge/docs-dev-blue.svg)](https://juliagraphs.org/Graphs.jl/dev/)

Flow algorithms on top of [Graphs.jl](https://github.com/JuliaGraphs/Graphs.jl),
including `maximum_flow`, `multiroute_flow` and `mincost_flow`.
See [Maximum flow problem](https://en.wikipedia.org/wiki/Maximum_flow_problem)
for a detailed description of the problem.

Documentation for this package is available [here](https://juliagraphs.github.io/Graphs.jl/latest/). For an overview of JuliaGraphs, see [this page](https://juliagraphs.github.io/).

## Usage

### Maxflow

```julia
julia> using Graphs, Graphs
julia> flow_graph = Graphs.DiGraph(8) # Create a flow graph
julia> flow_edges = [
(1,2,10),(1,3,5),(1,4,15),(2,3,4),(2,5,9),
(2,6,15),(3,4,4),(3,6,8),(4,7,16),(5,6,15),
(5,8,10),(6,7,15),(6,8,10),(7,3,6),(7,8,10)
]

julia> capacity_matrix = zeros(Int, 8, 8) # Create a capacity matrix

julia> for e in flow_edges
u, v, f = e
Graphs.add_edge!(flow_graph, u, v)
capacity_matrix[u,v] = f
end

julia> f, F = maximum_flow(flow_graph, 1, 8) # Run default maximum_flow (push-relabel) without the capacity_matrix

julia> f, F = maximum_flow(flow_graph, 1, 8, capacity_matrix) # Run default maximum_flow with the capacity_matrix

julia> f, F = maximum_flow(flow_graph, 1, 8, capacity_matrix, algorithm=EdmondsKarpAlgorithm()) # Run Edmonds-Karp algorithm

julia> f, F = maximum_flow(flow_graph, 1, 8, capacity_matrix, algorithm=DinicAlgorithm()) # Run Dinic's algorithm

julia> f, F, labels = maximum_flow(flow_graph, 1, 8, capacity_matrix, algorithm=BoykovKolmogorovAlgorithm()) # Run Boykov-Kolmogorov algorithm
```

### Multi-route flow

```julia
julia> using Graphs, Graphs

julia> flow_graph = Graphs.DiGraph(8) # Create a flow graph

julia> flow_edges = [
(1, 2, 10), (1, 3, 5), (1, 4, 15), (2, 3, 4), (2, 5, 9),
(2, 6, 15), (3, 4, 4), (3, 6, 8), (4, 7, 16), (5, 6, 15),
(5, 8, 10), (6, 7, 15), (6, 8, 10), (7, 3, 6), (7, 8, 10)
]

julia> capacity_matrix = zeros(Int, 8, 8) # Create a capacity matrix

julia> for e in flow_edges
u, v, f = e
Graphs.add_edge!(flow_graph, u, v)
capacity_matrix[u, v] = f
end

julia> f, F = multiroute_flow(flow_graph, 1, 8, capacity_matrix, routes = 2) # Run default multiroute_flow with an integer number of routes = 2

julia> f, F = multiroute_flow(flow_graph, 1, 8, capacity_matrix, routes = 1.5) # Run default multiroute_flow with a noninteger number of routes = 1.5

julia> points = multiroute_flow(flow_graph, 1, 8, capacity_matrix) # Run default multiroute_flow for all the breaking points values

julia> f, F = multiroute_flow(points, 1.5) # Then run multiroute flow algorithm for any positive number of routes

julia> f, F, labels = multiroute_flow(flow_graph, 1, 8, capacity_matrix, flow_algorithm = BoykovKolmogorovAlgorithm(), routes = 2) # Run multiroute flow algorithm using Boykov-Kolmogorov algorithm as maximum_flow routine
```
4 changes: 3 additions & 1 deletion src/Experimental/ShortestPaths/ShortestPaths.jl
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,9 @@ algorithm `alg` (one of [`BellmanFord`](@ref) or [`SPFA`](@ref)), return
`true` if any cycle detected in the graph has a negative weight.
# Examples

```jldoctest
```
julia> using Graphs

julia> g = complete_graph(3);

julia> d = [1 -3 1; -3 1 1; 1 1 1];
Expand Down
4 changes: 3 additions & 1 deletion src/Experimental/ShortestPaths/spfa.jl
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ end
Function which returns true if there is any negative weight cycle in the graph.
# Examples

```jldoctest
```
julia> using Graphs

julia> g = complete_graph(3);

julia> d = [1 -3 1; -3 1 1; 1 1 1];
Expand Down
21 changes: 20 additions & 1 deletion src/Graphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ using Random:
seed!,
shuffle,
shuffle!
using SparseArrays: SparseMatrixCSC, nonzeros, nzrange, rowvals
using SparseArrays: SparseMatrixCSC, nonzeros, nzrange, rowvals, spzeros
import SparseArrays: blockdiag, sparse
import Base:
adjoint,
Expand Down Expand Up @@ -261,6 +261,16 @@ export
stress_centrality,
radiality_centrality,

# flows
maximum_flow,
EdmondsKarpAlgorithm,
DinicAlgorithm,
BoykovKolmogorovAlgorithm,
PushRelabelAlgorithm,
multiroute_flow,
KishimotoAlgorithm,
ExtendedMultirouteFlowAlgorithm,

# spectral
adjacency_matrix,
laplacian_matrix,
Expand Down Expand Up @@ -500,6 +510,15 @@ include("shortestpaths/desopo-pape.jl")
include("shortestpaths/floyd-warshall.jl")
include("shortestpaths/yen.jl")
include("shortestpaths/spfa.jl")
include("flows/maximum_flow.jl")
include("flows/boykov_kolmogorov.jl")
include("flows/dinic.jl")
include("flows/edmonds_karp.jl")
include("flows/ext_multiroute_flow.jl")
include("flows/kishimoto.jl")
include("flows/mincut.jl")
include("flows/multiroute_flow.jl")
include("flows/push_relabel.jl")
include("linalg/LinAlg.jl")
include("operators.jl")
include("persistence/common.jl")
Expand Down
8 changes: 6 additions & 2 deletions src/SimpleGraphs/generators/euclideangraphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ and return a Euclidean graph, a map containing the distance on each edge and
a matrix with the points' positions.

## Examples
```jldoctest
```
julia> using Graphs

julia> g, dists = euclidean_graph(5, 2, cutoff=0.3);

julia> g
Expand Down Expand Up @@ -52,7 +54,9 @@ For `p=2` we have the standard Euclidean distance.
Set `bc=:periodic` to impose periodic boundary conditions in the box ``[0,L]^d``.

## Examples
```jldoctest
```
julia> using Graphs

julia> pts = rand(3, 10); # 10 vertices in R^3

julia> g, dists = euclidean_graph(pts, p=1, bc=:periodic) # Taxicab-distance (L^1);
Expand Down
67 changes: 59 additions & 8 deletions src/SimpleGraphs/generators/randgraphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ If not specified, the element type `T` is the type of `nv`.

## Examples
```jldoctest
julia> using Graphs

julia> SimpleGraph(5, 7)
{5, 7} undirected simple Int64 graph
```
Expand Down Expand Up @@ -63,6 +65,8 @@ If not specified, the element type `T` is the type of `nv`.

## Examples
```jldoctest
julia> using Graphs

julia> SimpleDiGraph(5, 7)
{5, 7} directed simple Int64 graph
```
Expand Down Expand Up @@ -135,9 +139,14 @@ probability `p`.
- `seed=nothing`: set the RNG seed.

# Examples
```jldoctest
```
julia> using Graphs

julia> erdos_renyi(10, 0.5)
{10, 20} undirected simple Int64 graph
```
```jldoctest
julia> using Graphs

julia> erdos_renyi(10, 0.5, is_directed=true, seed=123)
{10, 49} directed simple Int64 graph
Expand Down Expand Up @@ -173,6 +182,8 @@ graph with `n` vertices and `ne` edges.

# Examples
```jldoctest
julia> using Graphs

julia> erdos_renyi(10, 30)
{10, 30} undirected simple Int64 graph

Expand Down Expand Up @@ -213,8 +224,10 @@ from the expected values are likely.
- Efficient Generation of Networks with Given Expected Degrees, Joel C. Miller and Aric Hagberg. [https://doi.org/10.1007/978-3-642-21286-4_10](https://doi.org/10.1007/978-3-642-21286-4_10)

# Examples
```jldoctest
```
# 1)
julia> using Graphs

julia> g = expected_degree_graph([3, 1//2, 1//2, 1//2, 1//2])
{5, 3} undirected simple Int64 graph

Expand Down Expand Up @@ -303,6 +316,8 @@ be rewired randomly.

## Examples
```jldoctest
julia> using Graphs

julia> watts_strogatz(10, 4, 0.3)
{10, 20} undirected simple Int64 graph

Expand Down Expand Up @@ -402,11 +417,16 @@ enough `p` and `k`, this should not deviate much from the original model.
### Optional Arguments
- `is_directed=false`: if true, return a directed graph.
- `rng=nothing`: set the Random Number Generator.
- `seed=nothing`: set the RNG seed.

## Examples
```jldoctest
```
julia> using Graphs

julia> newman_watts_strogatz(10, 4, 0.3)
{10, 26} undirected simple Int64 graph
````
```jldoctest

julia> newman_watts_strogatz(Int8(10), 4, 0.8, is_directed=true, seed=123)
{10, 36} directed simple Int8 graph
Expand All @@ -421,8 +441,9 @@ function newman_watts_strogatz(
β::Real;
is_directed::Bool=false,
rng::Union{Nothing,AbstractRNG}=nothing,
seed::Union{Nothing,Integer}=nothing,
)
return watts_strogatz(n, k, β; is_directed=is_directed, remove_edges=false, rng=rng)
return watts_strogatz(n, k, β; is_directed=is_directed, remove_edges=false, rng=rng, seed=seed)
end

function _suitable(edges::Set{SimpleEdge{T}}, potential_edges::Dict{T,T}) where {T<:Integer}
Expand Down Expand Up @@ -494,6 +515,8 @@ Initial graphs are undirected and consist of isolated vertices by default.
- `seed=nothing`: set the RNG seed.
## Examples
```jldoctest
julia> using Graphs

julia> barabasi_albert(50, 3)
{50, 141} undirected simple Int64 graph

Expand All @@ -520,6 +543,8 @@ Initial graphs are undirected and consist of isolated vertices by default.

## Examples
```jldoctest
julia> using Graphs

julia> barabasi_albert(10, 3, 2)
{10, 14} undirected simple Int64 graph

Expand Down Expand Up @@ -559,6 +584,8 @@ already present in the system by preferential attachment.
- `seed=nothing`: set the RNG seed.
## Examples
```jldoctest
julia> using Graphs

julia> g = cycle_graph(4)
{4, 4} undirected simple Int64 graph

Expand Down Expand Up @@ -657,18 +684,32 @@ Time complexity is ``\\mathcal{O}(|V| + |E| log |E|)``.
- Goh K-I, Kahng B, Kim D: Universal behaviour of load distribution in scale-free networks. Phys Rev Lett 87(27):278701, 2001.

## Examples
```jldoctest
```
julia> g = static_fitness_model(5, [1, 1, 0.5, 0.1])
{4, 5} undirected simple Int64 graph

julia> edges(g) |> collect
5-element Array{Graphs.SimpleGraphs.SimpleEdge{Int64},1}:
5-element Vector{Graphs.SimpleGraphs.SimpleEdge{Int64}}:
Edge 1 => 2
Edge 1 => 3
Edge 1 => 4
Edge 2 => 3
Edge 2 => 4
```
```jldoctest
julia> using Graphs

julia> g = static_fitness_model(5, [1, 1, 0.5, 0.1], seed=123)
{4, 5} undirected simple Int64 graph

julia> edges(g) |> collect
5-element Vector{Graphs.SimpleGraphs.SimpleEdge{Int64}}:
Edge 1 => 2
Edge 1 => 3
Edge 2 => 3
Edge 2 => 4
Edge 3 => 4
```
"""
function static_fitness_model(
m::Integer,
Expand Down Expand Up @@ -715,11 +756,13 @@ Time complexity is ``\\mathcal{O}(|V| + |E| log |E|)``.

## Examples
```jldoctest
julia> using Graphs

julia> g = static_fitness_model(6, [1, 0.2, 0.2, 0.2], [0.1, 0.1, 0.1, 0.9]; seed=123)
{4, 6} directed simple Int64 graph

julia> edges(g) |> collect
6-element Array{Graphs.SimpleGraphs.SimpleEdge{Int64},1}:
6-element Vector{Graphs.SimpleGraphs.SimpleEdge{Int64}}:
Edge 1 => 2
Edge 1 => 3
Edge 1 => 4
Expand Down Expand Up @@ -977,6 +1020,8 @@ Generates a random labelled tree, drawn uniformly at random over the ``n^{n-2}``

# Examples
```jldoctest
julia> using Graphs

julia> uniform_tree(10)
{10, 9} undirected simple Int64 graph
```
Expand Down Expand Up @@ -1050,6 +1095,8 @@ with `n` vertices.

# Examples
```jldoctest
julia> using Graphs

julia> random_tournament_digraph(5)
{5, 10} directed simple Int64 graph

Expand Down Expand Up @@ -1423,6 +1470,8 @@ the `t`th stage of this algorithm by accessing the first `t` vertices with `g[1:

# Examples
```jldoctest
julia> using Graphs

julia> dorogovtsev_mendes(10)
{10, 17} undirected simple Int64 graph

Expand Down Expand Up @@ -1472,10 +1521,12 @@ DAG's have a finite topological order; this order is randomly generated via "ord

# Examples
```jldoctest
julia> using Graphs

julia> random_orientation_dag(complete_graph(10))
{10, 45} directed simple Int64 graph

julia> random_orientation_dag(star_graph(Int8(10)), 123)
julia> random_orientation_dag(star_graph(Int8(10)), seed=123)
{10, 9} directed simple Int8 graph
```
"""
Expand Down
Loading