
| Current Path : /var/www/web-klick.de/dsh/50_dev2017/1310__algorithms/Julia/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : /var/www/web-klick.de/dsh/50_dev2017/1310__algorithms/Julia/DStructure.jl |
module DStructure
export
# types
IntegerDisjointSets, DisjointSets,
# functions
length, num_groups, find_root, merge!, push!
import Base: length, push!
#
# IntegerDisjointSets
#
# since each element is an integer, we can use arrays
# instead of dictionary (efficiency)
#
# DisjointSets over other key types can be implemented
# based on IntegerDisjointSets through a map from the
# key to an integer index
#
type IntegerDisjointSets
parents::Array{Int, 1}
ranks::Array{Int, 1}
ngroups::Int
IntegerDisjointSets(n::Integer) = new([1:n], zeros(Int, n), n)
end
length(s::IntegerDisjointSets) = length(s.parents)
num_groups(s::IntegerDisjointSets) = s.ngroups
# find the root element of the subset that contains x
# using path compression
function find_root(s::IntegerDisjointSets, x::Integer)
@inbounds p::Int = s.parents[x]
@inbounds if s.parents[p] != p
s.parents[x] = p = find_root(s, p)
end
p
end
in_same_set(s::IntegerDisjointSets, x::Integer, y::Integer) =
find_root(s, x) == find_root(s, y)
function merge!(s::IntegerDisjointSets, x::Integer, y::Integer)
xroot = find_root(s, x)
yroot = find_root(s, y)
if xroot != yroot
rks::Vector{Int} = s.ranks
@inbounds xrank::Int = rks[xroot]
@inbounds yrank::Int = rks[yroot]
if xrank < yrank
@inbounds s.parents[xroot] = yroot
else
@inbounds s.parents[yroot] = xroot
if xrank == yrank
s.ranks[xroot] += 1
end
end
s.ngroups -= 1
end
end
function push!(s::IntegerDisjointSets, x::Integer)
push!(s.parents, x)
push!(s.ranks, 0)
s.ngroups += 1
end
function push!(s::IntegerDisjointSets)
x = length(s) + 1
push!(s, x)
return x
end
#
# an arbitrary value type T DisjointSets
#
# genericity is implemented here by using a
# dictionary to map the input value to an internal index
#
type DisjointSets{T}
intmap::Dict{T, Int}
internal::IntegerDisjointSets
function DisjointSets(xs)
imap = Dict{T, Int}()
n = length(xs)
sizehint(imap, n)
id = 0
for x in xs
imap[x] = (id += 1)
end
new(imap, IntegerDisjointSets(n))
end
end
length(s::DisjointSets) = length(s.internal)
num_groups(s::DisjointSets) = num_groups(s.internal)
find_root{T}(s::DisjointSets{T}, x::T) = find_root(s.internal, s.intmap[x])
in_same_set{T}(s::DisjointSets{T}, x::T, y::T) = in_same_set(s.internal, s.intmap[x], s.intmap[y])
function merge!{T}(s::DisjointSets{T}, x::T, y::T)
merge!(s.internal, s.intmap[x], s.intmap[y])
end
function push!{T}(s::DisjointSets{T}, x::T)
id = push!(s.internal)
s.intmap[x] = id
end
end