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

Commit

Permalink
Mincut (#11)
Browse files Browse the repository at this point in the history
* added mincut + tests

* added doc
  • Loading branch information
matbesancon authored Feb 7, 2018
1 parent 2158d81 commit f22cee5
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ makedocs(
"Maxflow algorithms" => "maxflow.md",
"Multiroute flows" => "multiroute.md",
"Min-cost flows" => "mincost.md",
"Min-cut" => "mincut.md",
]
)
7 changes: 7 additions & 0 deletions docs/src/mincut.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## Min-cut

```@autodocs
Modules = [LightGraphsFlows]
Pages = ["mincut.jl"]
Order = [:function, :type]
```
3 changes: 2 additions & 1 deletion src/LightGraphsFlows.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ include("multiroute_flow.jl")
include("kishimoto.jl")
include("ext_multiroute_flow.jl")
include("mincost.jl")
include("mincut.jl")

export
maximum_flow, EdmondsKarpAlgorithm, DinicAlgorithm, BoykovKolmogorovAlgorithm, PushRelabelAlgorithm,
multiroute_flow, KishimotoAlgorithm, ExtendedMultirouteFlowAlgorithm, mincost_flow
multiroute_flow, KishimotoAlgorithm, ExtendedMultirouteFlowAlgorithm, mincost_flow, mincut

end
30 changes: 30 additions & 0 deletions src/mincut.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""
mincut(flow_graph::lg.IsDirected, source::Integer, target::Integer, capacity_matrix::AbstractMatrix, algorithm::AbstractFlowAlgorithm)
Compute the min-cut between `source` and `target` for the given graph.
First computes the maxflow using `algorithm` and then builds the partition of the residual graph
Returns a triplet `(part1, part2, flow)` with the partition containing the source, the partition containing the target (the rest) and the min-cut(max-flow) value
"""
function mincut(
flow_graph::lg.DiGraph, # the input graph
source::Integer, # the source vertex
target::Integer, # the target vertex
capacity_matrix::AbstractMatrix, # edge flow capacities
algorithm::AbstractFlowAlgorithm # keyword argument for algorithm
)
flow, flow_matrix = maximum_flow(flow_graph, source, target, capacity_matrix, algorithm)
residual_matrix = spzeros(lg.nv(flow_graph),lg.nv(flow_graph))
for edge in lg.edges(flow_graph)
residual_matrix[edge.src,edge.dst] = max(0.0, capacity_matrix[edge.src,edge.dst] - flow_matrix[edge.src,edge.dst])
end
part1 = typeof(source)[]
queue = [source]
while !isempty(queue)
node = pop!(queue)
push!(part1, node)
dests = [dst for dst in 1:lg.nv(flow_graph) if residual_matrix[node,dst]>0.0 && dst part1]
append!(queue, dests)
end
part2 = [node for node in 1:lg.nv(flow_graph) if node part1]
return (part1, part2, flow)
end
39 changes: 39 additions & 0 deletions test/mincut.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
@testset "Mincut" begin

g = lg.CompleteDiGraph(5)
cap1 = [
0.0 2.0 2.0 0.0 0.0
0.0 0.0 0.0 0.0 3.0
0.0 1.0 0.0 3.0 0.0
0.0 0.0 0.0 0.0 1.0
0.0 0.0 0.0 0.0 0.0
];
(part1, part2, value) = LightGraphsFlows.mincut(g,1,5,cap1,LightGraphsFlows.PushRelabelAlgorithm())
@test value 4.0
@test part1 == [1]
@test sort(part2) == collect(2:5)
cap2 = [
0.0 3.0 2.0 0.0 0.0
0.0 0.0 0.0 0.0 3.0
0.0 1.0 0.0 3.0 0.0
0.0 0.0 0.0 0.0 1.5
0.0 0.0 0.0 0.0 0.0
];
(part1, part2, value) = LightGraphsFlows.mincut(g,1,5,cap2,LightGraphsFlows.PushRelabelAlgorithm())
@test value 4.5
@test sort(part1) == collect(1:4)
@test part2 == [5]

g2 = lg.DiGraph(5)
lg.add_edge!(g2,1,2)
lg.add_edge!(g2,1,3)
lg.add_edge!(g2,3,4)
lg.add_edge!(g2,3,2)
lg.add_edge!(g2,2,5)

(part1, part2, value) = LightGraphsFlows.mincut(g2,1,5,cap1,LightGraphsFlows.PushRelabelAlgorithm())
@test value 3.0
@test sort(part1) == [1,3,4]
@test sort(part2) == [2,5]

end
4 changes: 3 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ for t in [
"push_relabel",
"maximum_flow",
"multiroute_flow",
"mincost"]
"mincost",
"mincut",
]
tp = joinpath(testdir, "$(t).jl")
include(tp)
end

0 comments on commit f22cee5

Please sign in to comment.