augmented_interval_tree 0.1.0

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/interval_tree.rb +130 -0
  3. metadata +64 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2591f2d25e1de25e701a3115d5eb647334a67a74
4
+ data.tar.gz: e224077f0534ff854255a2d3ba840278148ac466
5
+ SHA512:
6
+ metadata.gz: 88911836bf22f53b32cb414ec7583ac91bb4dee0c4d72e11af929c8873fc4cc49206d18db427e4c7dca29e5c6b7a1c68ce5bfc3843fadc53f0b05163cf695224
7
+ data.tar.gz: 02dea2fac6b40520bb156cdc429f936c42b8c919e27cd958cec8e3ca9731c422cc8f18d03c6a95e527e991fa13f09a6660400fdb6aae80312f5044e14e646429
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Title:: the IntervalTree module using "augmented tree"
4
+ # Author:: Hiroyuki Mishima, Simeon Simeonov, Carlos Alonso
5
+ # Copyright:: The MIT/X11 license
6
+ #
7
+ # see also ....
8
+ # description in Wikipedia
9
+ # http://en.wikipedia.org/wiki/Interval_tree
10
+ # implementation in Python by Tyler Kahn
11
+ # http://forrst.com/posts/Interval_Tree_implementation_in_python-e0K
12
+ #
13
+ # Usage:
14
+ # require "interval_tree"
15
+ # itv = [(0...3), (1...4), (3...5),]
16
+ # t = IntervalTree::Tree.new(itv)
17
+ # p t.search(2) => [0...3, 1...4]
18
+ # p t.search(1...3) => [0...3, 1...4, 3...5]
19
+ #
20
+ # note: result intervals are always returned
21
+ # in the "left-closed and right-open" style that can be expressed
22
+ # by three-dotted Range object literals (first...last)
23
+
24
+ module IntervalTree
25
+
26
+ class Tree
27
+ def initialize(ranges, &range_factory)
28
+ range_factory = lambda { |l, r| (l ... r+1) } unless block_given?
29
+ ranges_excl = ensure_exclusive_end([ranges].flatten, range_factory)
30
+ @top_node = divide_intervals(ranges_excl)
31
+ end
32
+ attr_reader :top_node
33
+
34
+ def divide_intervals(intervals)
35
+ return nil if intervals.empty?
36
+ x_center = center(intervals)
37
+ s_center = Array.new
38
+ s_left = Array.new
39
+ s_right = Array.new
40
+
41
+ intervals.each do |k|
42
+ case
43
+ when k.last < x_center
44
+ s_left << k
45
+ when k.first > x_center
46
+ s_right << k
47
+ else
48
+ s_center << k
49
+ end
50
+ end
51
+ Node.new(x_center, s_center,
52
+ divide_intervals(s_left), divide_intervals(s_right))
53
+ end
54
+
55
+
56
+ def search(interval)
57
+ return nil unless @top_node
58
+ if interval.respond_to?(:first)
59
+ first = interval.first
60
+ last = interval.last
61
+ else
62
+ first = interval
63
+ last = nil
64
+ end
65
+
66
+ if last
67
+ result = Array.new
68
+ (first...last).each do |j|
69
+ search(j).each{|k|result << k}
70
+ result.uniq!
71
+ end
72
+ result.sort_by{|x|[x.first, x.last]}
73
+ else
74
+ point_search(self.top_node, first, []).sort_by{|x|[x.first, x.last]}
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ def ensure_exclusive_end(ranges, range_factory)
81
+ ranges.map do |range|
82
+ case
83
+ when !range.respond_to?(:exclude_end?)
84
+ range
85
+ when range.exclude_end?
86
+ range
87
+ else
88
+ range_factory.call(range.first, range.end)
89
+ end
90
+ end
91
+ end
92
+
93
+ # augmented tree
94
+ # using a start point as resresentative value of the node
95
+ def center(intervals)
96
+ i = intervals.reduce([intervals.first.first, intervals.first.last]) { |acc, int| [[acc.first, int.first].min, [acc.last, int.last].max] }
97
+ i.first + (i.last - i.first) / 2
98
+ end
99
+
100
+ def point_search(node, point, result)
101
+ node.s_center.each do |k|
102
+ if k.include?(point)
103
+ result << k
104
+ end
105
+ end
106
+ if node.left_node && ( point < node.x_center )
107
+ point_search(node.left_node, point, []).each{|k|result << k}
108
+ end
109
+ if node.right_node && ( point >= node.x_center )
110
+ point_search(node.right_node, point, []).each{|k|result << k}
111
+ end
112
+ result.uniq
113
+ end
114
+ end # class Tree
115
+
116
+ class Node
117
+ def initialize(x_center, s_center, left_node, right_node)
118
+ @x_center = x_center
119
+ @s_center = s_center
120
+ @left_node = left_node
121
+ @right_node = right_node
122
+ end
123
+ attr_reader :x_center, :s_center, :left_node, :right_node
124
+ end # class Node
125
+
126
+ end # module IntervalTree
127
+
128
+ if __FILE__ == $0
129
+ puts "This is the Augmented Interval Tree library."
130
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: augmented_interval_tree
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Hiroyuki Mishima
8
+ - Simeon Simeonov
9
+ - Carlos Alonso
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2015-11-09 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: '2.11'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '2.11'
29
+ description: |
30
+ A Ruby implementation of the Augmented Interval Tree data structure.
31
+ See also: http://en.wikipedia.org/wiki/Interval_tree
32
+ email:
33
+ - missy@be.to
34
+ - info@mrcalonso.com
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - lib/interval_tree.rb
40
+ homepage: https://github.com/misshie/interval-tree
41
+ licenses:
42
+ - MIT
43
+ metadata: {}
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubyforge_project:
60
+ rubygems_version: 2.4.5
61
+ signing_key:
62
+ specification_version: 4
63
+ summary: A Ruby implementation of the Augmented Interval Tree data structure
64
+ test_files: []