data_structures_rmolinari 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ea5f3d2fed60234fefe18577985f1e8ae967ecec92ef0812ccaeff0fb81ca392
4
- data.tar.gz: e3e59746e8d7e881209a2c3a0e78ea186aa0562d138d7e2b6ed261943f6cb45f
3
+ metadata.gz: b8d63f6987f160f00ce92f79643f904f95bc230e4a5b60679f4301ecd366622a
4
+ data.tar.gz: cdc660ab53a0259a79b72ecc3928f640faa7b1251a1bae3baabb1c70bac20d01
5
5
  SHA512:
6
- metadata.gz: e480ccee258f97479f1768b8f94b65a1c13f3b1e8f15e843c4240adeac555574383ef7de3928a057fd0b6707823cb4eeddee2128a49175c2f671e1526f887c2e
7
- data.tar.gz: 30ac4bf22fe37bdfbf4eeccdcdfc2feba23278703957eebf5f9be6c30bb3e68024ccd49ef63c892d78c1fd58b54336a762c86cb107f9f27937222e9baf252ef4
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.0
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