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

fix mincut() #325

Merged
merged 6 commits into from
Jan 25, 2024
Merged
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
35 changes: 14 additions & 21 deletions src/traversals/maxadjvisit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
# in which case we'll return immediately.
(nvg > one(U)) || return (Vector{Int8}([1]), zero(T))

# to avoid reallocating lists in fadjlist, we have some already merged vertices
# still appearing in fadjlist. When iterating neighbors, is_merged makes sure we
# don't consider them
is_merged = falses(nvg)
merged_vertices = IntDisjointSets(U(nvg))
graph_size = nvg
Expand All @@ -48,7 +51,6 @@

is_processed = falses(nvg)
@inbounds while graph_size > 1
cutweight = zero(T)
is_processed .= false
is_processed[u] = true
# initialize pq
Expand All @@ -60,32 +62,23 @@
for v in fadjlist[u]
(is_merged[v] || v == u ) && continue
pq[v] = w[u, v]
cutweight += w[u, v]
end
# Minimum cut phase
local cutweight
while true
last_vertex = u
u, adj_cost = first(pq)
dequeue!(pq)
u, cutweight = dequeue_pair!(pq)
isempty(pq) && break
for v in fadjlist[u]
(is_merged[v] || u == v) && continue
# if the target of e is already marked then decrease cutweight
# otherwise, increase it
ew = w[u, v]
if is_processed[v]
cutweight -= ew
else
cutweight += ew
pq[v] += ew
end
(is_processed[v] || is_merged[v] || u == v) && continue

Check warning on line 73 in src/traversals/maxadjvisit.jl

View check run for this annotation

Codecov / codecov/patch

src/traversals/maxadjvisit.jl#L73

Added line #L73 was not covered by tests
pq[v] += w[u, v]
end
is_processed[u] = true
# adj_cost is a lower bound on the cut separating the two last vertices
# encountered, so if adj_cost >= bestweight, we can already merge these
# cutweight is a lower bound on the cut separating the two last vertices
# encountered, so if cutweight >= bestweight, we can already merge these
# vertices to save one phase.
if adj_cost >= bestweight
_merge_vertex!(merged_vertices, fadjlist, is_merged, w, u, last_vertex)
if cutweight >= bestweight
u = _merge_vertex!(merged_vertices, fadjlist, is_merged, w, u, last_vertex)
graph_size -= 1
end
end
Expand All @@ -99,14 +92,14 @@
end

# merge u and last_vertex
root = _merge_vertex!(merged_vertices, fadjlist, is_merged, w, u, last_vertex)
u = _merge_vertex!(merged_vertices, fadjlist, is_merged, w, u, last_vertex)
graph_size -= 1
u = root # we are sure this vertex was not merged, so the next phase start from it
end
return (convert(Vector{Int8}, parities) .+ one(Int8), bestweight)
end

function _merge_vertex!(merged_vertices, fadjlist, is_merged, w, u, v)
# root is kept, non-root is discarded
root = union!(merged_vertices, u, v)
non_root = (root == u) ? v : u
is_merged[non_root] = true
Expand All @@ -116,7 +109,7 @@
w[v2, root] = w[root, v2]
end
# update neighbors
fadjlist[root] = union(fadjlist[root], fadjlist[non_root])
union!(fadjlist[root], fadjlist[non_root])
axsk marked this conversation as resolved.
Show resolved Hide resolved
for v in fadjlist[non_root]
if root ∉ fadjlist[v]
push!(fadjlist[v], root)
Expand Down
Loading