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

Mincut #11

Merged
merged 2 commits into from
Feb 7, 2018
Merged
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 @@ -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