Initial commit
This commit is contained in:
90
gamemodes/darkrp/gamemode/libraries/disjointset.lua
Normal file
90
gamemodes/darkrp/gamemode/libraries/disjointset.lua
Normal file
@@ -0,0 +1,90 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
Disjoint-set forest implementation
|
||||
Inspired by the book Introduction To Algorithms (third edition)
|
||||
|
||||
by FPtje Atheos
|
||||
|
||||
Running time per operation (Union/FindSet): O(a(n)) where a is the inverse of the Ackermann function.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
local ipairs = ipairs
|
||||
local setmetatable = setmetatable
|
||||
local string = string
|
||||
local table = table
|
||||
local tostring = tostring
|
||||
|
||||
module("disjoint")
|
||||
|
||||
local metatable
|
||||
|
||||
-- Make a singleton set. Parent parameter is optional, must be a disjoint-set as well.
|
||||
function MakeSet(x, parent)
|
||||
local set = {}
|
||||
set.value = x
|
||||
set.rank = 0
|
||||
set.parent = parent or set
|
||||
|
||||
setmetatable(set, metatable)
|
||||
|
||||
return set
|
||||
end
|
||||
|
||||
local function Link(x, y)
|
||||
if x == y then return x end
|
||||
|
||||
-- Union by rank
|
||||
if x.rank > y.rank then
|
||||
y.parent = x
|
||||
return x
|
||||
end
|
||||
|
||||
x.parent = y
|
||||
|
||||
if x.rank == y.rank then
|
||||
y.rank = y.rank + 1
|
||||
end
|
||||
|
||||
return y
|
||||
end
|
||||
|
||||
-- Apply the union operation between two sets.
|
||||
function Union(x, y)
|
||||
return Link(FindSet(x), FindSet(y))
|
||||
end
|
||||
|
||||
function FindSet(x)
|
||||
local parent = x
|
||||
local listParents
|
||||
|
||||
-- Go up the tree to find the parent
|
||||
while parent ~= parent.parent do
|
||||
parent = parent.parent
|
||||
|
||||
listParents = listParents or {}
|
||||
table.insert(listParents, parent)
|
||||
end
|
||||
|
||||
-- Path compression, update all parents to refer to the top parent
|
||||
if listParents then
|
||||
for _, v in ipairs(listParents) do
|
||||
v.parent = parent
|
||||
end
|
||||
end
|
||||
|
||||
return parent
|
||||
end
|
||||
|
||||
function Disconnect(x)
|
||||
x.parent = x
|
||||
|
||||
return x
|
||||
end
|
||||
|
||||
|
||||
metatable = {
|
||||
__tostring = function(self)
|
||||
return string.format("Disjoint-Set [value: %s][Rank: %s][Parent: %s]", tostring(self.value), self.rank, tostring(self.parent.value))
|
||||
end,
|
||||
__metatable = true, -- restrict access to metatable
|
||||
__add = Union
|
||||
}
|
||||
Reference in New Issue
Block a user