data_structures_rmolinari 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8d63f6987f160f00ce92f79643f904f95bc230e4a5b60679f4301ecd366622a
|
4
|
+
data.tar.gz: cdc660ab53a0259a79b72ecc3928f640faa7b1251a1bae3baabb1c70bac20d01
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 057d29af42606c7ecc4a78e6c752fa5f7a29b41788f21ca7ede6bab0893d1ba63b6c9dc3e5f3b5747f3912718565d6dfcb5952d189f78b40a6ef77efe95f34c9
|
7
|
+
data.tar.gz: '08f6921ab4b1c7cf84c9fe5624266b7060f4f1d4f1ecc56e3850106b3bb30e0c6b30c3ea808a61939966350118684f3353ccbb628d24b353b35ae865268222d2'
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# A "disjoint set union" that represents a set of elements that belonging to _disjoint_ subsets. Alternatively, this expresses a
|
2
|
+
# partion of a fixed set.
|
3
|
+
#
|
4
|
+
# The data structure provides efficient actions to merge two disjoint subsets, i.e., replace them by their union, and determine if
|
5
|
+
# two elements are in the same subset.
|
6
|
+
#
|
7
|
+
# The elements of the set must be 0, 1, ..., n-1. Client code can map its data to these representatives. The code uses several ideas
|
8
|
+
# from Tarjan and van Leeuwen for efficiency
|
9
|
+
#
|
10
|
+
# See https://en.wikipedia.org/wiki/Disjoint-set_data_structure for a good introduction.
|
11
|
+
#
|
12
|
+
# - Tarjan, Robert E., van Leeuwen, Jan (1984). "Worst-case analysis of set union algorithms". Journal of the ACM. 31 (2): 245–281.
|
13
|
+
class DisjointUnionInternal
|
14
|
+
attr_reader :subset_count
|
15
|
+
|
16
|
+
# @param size the size of the universe, which must be known at the time of construction. The elements 0, 1, ..., size - 1 start
|
17
|
+
# out in disjoint singleton subsets.
|
18
|
+
def initialize(size)
|
19
|
+
@size = size
|
20
|
+
# Initialize to
|
21
|
+
@d = (0...size).to_a
|
22
|
+
@rank = [0] * size
|
23
|
+
|
24
|
+
@subset_count = size
|
25
|
+
end
|
26
|
+
|
27
|
+
# Declare that e and f are equivalent, i.e., in the same subset. If they are already in the same subset this is a no-op.
|
28
|
+
#
|
29
|
+
# Each argument must be one of 0, 1, ..., size-1.
|
30
|
+
def unite(e, f)
|
31
|
+
check_value(e)
|
32
|
+
check_value(f)
|
33
|
+
raise 'Uniting an element with itself is meaningless' if e == f
|
34
|
+
|
35
|
+
e_root = find(e)
|
36
|
+
f_root = find(f)
|
37
|
+
return if e_root == f_root
|
38
|
+
|
39
|
+
@subset_count -= 1
|
40
|
+
link(e_root, f_root)
|
41
|
+
end
|
42
|
+
|
43
|
+
# The canonical representative of the subset containing e. Two elements d and e are in the same subset exactly when find(d) ==
|
44
|
+
# find(e).
|
45
|
+
# @param e must be one of 0, 1, ..., size-1.
|
46
|
+
# @return (Integer) one of 0, 1, ..., size-1.
|
47
|
+
def find(e)
|
48
|
+
# We implement find with "halving" to shrink the length of paths to the root. See Tarjan and van Leeuwin p 252.
|
49
|
+
x = e
|
50
|
+
x = @d[x] = @d[@d[x]] while @d[@d[x]] != @d[x]
|
51
|
+
@d[x]
|
52
|
+
end
|
53
|
+
|
54
|
+
private def check_value(v)
|
55
|
+
raise "Value must be given and be in (0..#{@size - 1})" unless v && v.between?(0, @size - 1)
|
56
|
+
end
|
57
|
+
|
58
|
+
private def link(e, f)
|
59
|
+
# Choose which way around to do the linking using the element "ranks". See Tarjan and van Leeuwen, p 250.
|
60
|
+
if @rank[e] > @rank[f]
|
61
|
+
@d[f] = e
|
62
|
+
elsif @rank[e] == @rank[f]
|
63
|
+
@d[f] = e
|
64
|
+
@rank[e] += 1
|
65
|
+
else
|
66
|
+
@d[e] = f
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'data_structures_rmolinari/shared'
|
2
|
+
require_relative 'data_structures_rmolinari/disjoint_union_internal'
|
2
3
|
require_relative 'data_structures_rmolinari/generic_segment_tree_internal'
|
3
4
|
require_relative 'data_structures_rmolinari/heap_internal'
|
4
5
|
require_relative 'data_structures_rmolinari/max_priority_search_tree_internal'
|
@@ -11,6 +12,7 @@ module DataStructuresRMolinari
|
|
11
12
|
# Priority Search Trees
|
12
13
|
#
|
13
14
|
# Note that MinmaxPrioritySearchTree is only a fragment of what we need
|
15
|
+
|
14
16
|
MaxPrioritySearchTree = MaxPrioritySearchTreeInternal
|
15
17
|
MinmaxPrioritySearchTree = MinmaxPrioritySearchTreeInternal
|
16
18
|
|
@@ -42,5 +44,11 @@ module DataStructuresRMolinari
|
|
42
44
|
|
43
45
|
########################################
|
44
46
|
# Heap
|
47
|
+
|
45
48
|
Heap = HeapInternal
|
49
|
+
|
50
|
+
########################################
|
51
|
+
# Disjoint Union
|
52
|
+
|
53
|
+
DisjointUnion = DisjointUnionInternal
|
46
54
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: data_structures_rmolinari
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rory Molinari
|
@@ -72,12 +72,15 @@ description: |
|
|
72
72
|
Sometimes it is not enough to read the description of a data structure and accompanying pseudo-code.
|
73
73
|
Actually implementing the structure is often helpful in understanding what is going on. It is also
|
74
74
|
usually fun.
|
75
|
+
|
76
|
+
We implement Disjoin Union, Heap, Priority Search Tree, and Segment Tree.
|
75
77
|
email: rorymolinari+rubygems@gmail.com
|
76
78
|
executables: []
|
77
79
|
extensions: []
|
78
80
|
extra_rdoc_files: []
|
79
81
|
files:
|
80
82
|
- lib/data_structures_rmolinari.rb
|
83
|
+
- lib/data_structures_rmolinari/disjoint_union_internal.rb
|
81
84
|
- lib/data_structures_rmolinari/generic_segment_tree_internal.rb
|
82
85
|
- lib/data_structures_rmolinari/heap_internal.rb
|
83
86
|
- lib/data_structures_rmolinari/max_priority_search_tree_internal.rb
|