diff --git a/src/dinic.jl b/src/dinic.jl index f10c1c8..681038d 100644 --- a/src/dinic.jl +++ b/src/dinic.jl @@ -21,7 +21,7 @@ function dinic_impl end while true augment = blocking_flow!(residual_graph, source, target, capacity_matrix, flow_matrix, P) - augment == 0 && break + is_zero(augment) && break flow += augment end return flow, flow_matrix @@ -80,7 +80,7 @@ function blocking_flow! end end end - flow == 0 && continue # Flow cannot be augmented along path + is_zero(flow) && continue # Flow cannot be augmented along path v = target u = bv diff --git a/src/maximum_flow.jl b/src/maximum_flow.jl index 7b0fd1a..093aaad 100644 --- a/src/maximum_flow.jl +++ b/src/maximum_flow.jl @@ -178,3 +178,19 @@ function maximum_flow( end return maximum_flow(flow_graph, source, target, capacity_matrix, algorithm) end + +""" + is_zero(value) + +Test if the value is equal to zero. It handles floating point errors. +""" +function is_zero end +function is_zero( + value::T + ) where {T} + if isa(value,AbstractFloat) + return isapprox(value, 0, atol = sqrt(eps(T))) + else + return value == 0 + end +end diff --git a/src/push_relabel.jl b/src/push_relabel.jl index b4ed27a..88313b1 100644 --- a/src/push_relabel.jl +++ b/src/push_relabel.jl @@ -169,7 +169,6 @@ function relabel! end nothing end - """ discharge!(residual_graph, v, capacity_matrix, flow_matrix, excess, height, active, count, Q) @@ -189,11 +188,11 @@ function discharge! end Q::AbstractVector # FIFO queue ) for to in lg.outneighbors(residual_graph, v) - excess[v] == 0 && break + is_zero(excess[v]) && break push_flow!(residual_graph, v, to, capacity_matrix, flow_matrix, excess, height, active, Q) end - if excess[v] > 0 + if excess[v] ≉ zero(excess[v]) if count[height[v] + 1] == 1 gap!(residual_graph, height[v], excess, height, active, count, Q) else