Skip to content

DisjointSets: template for extension? #911

Closed
@jacob-roth

Description

@jacob-roth

I have an application where I need to extend the functionality of IntDisjointSets. In one use case, I need to handle the following:

  1. track the min and max element of each set
  2. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions