Closed
Description
I have an application where I need to extend the functionality of IntDisjointSets
. In one use case, I need to handle the following:
- track the min and max element of each set
- track the average of elements in each set
My first thought was to allocate additional arrays for min
, max
, count
, and avg
and then modify root_union!
in the following way, based on 298:
function root_union!(s::IntDisjointSet{T}, x::T, y::T) where {T<:Integer}
parents = s.parents
rks = s.ranks
# start modifications
count = s.count
mn = s.min
mx = s.max
avg = s.avg
# end modifications
@inbounds xrank = rks[x]
@inbounds yrank = rks[y]
if xrank < yrank
x, y = y, x
elseif xrank == yrank
rks[x] += one(T)
end
@inbounds parents[y] = x
# start modifications
cx = count[x]
cy = count[y]
cxy = cx + cy
@inbounds mn[x] = min(mn[x], mn[y])
@inbounds mx[x] = max(mx[x], mx[y])
@inbounds avg[x] = cx/cxy * avg[x] + cy/cxy * avg[y]
@inbounds count[x] = cxy
# end modifications
s.ngroups -= one(T)
return x
end
I was wondering (1) if there might be any optimizations to this code and (2) if it could be useful for having a template indicating how to best modify the functionality of disjoint sets? My actual use case is slightly more complicated than this, but if this is a "good" template for min/max/avg, then I will follow it for my use case.
Metadata
Metadata
Assignees
Labels
No labels
Activity