pqueue 2.0.0 → 2.0.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.
- data/.ruby +1 -1
- data/HISTORY.rdoc +11 -0
- metadata +7 -8
- data/lib/pqueue/legacy.rb +0 -269
data/.ruby
CHANGED
data/HISTORY.rdoc
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
= CHANGE HISTORY
|
2
2
|
|
3
|
+
== 2.0.1 / 2011-10-29
|
4
|
+
|
5
|
+
Quick fix to remove old legacy library that was supposed to be
|
6
|
+
removed in previous release. No big deal, it just confused the
|
7
|
+
YARD documentation.
|
8
|
+
|
9
|
+
Changes:
|
10
|
+
|
11
|
+
* Remove legacy version of library.
|
12
|
+
|
13
|
+
|
3
14
|
== 2.0.0 / 2011-10-29
|
4
15
|
|
5
16
|
This is a complete rewrite to simplify the design and use more
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pqueue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -17,7 +17,7 @@ date: 2011-10-29 00:00:00.000000000 Z
|
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: detroit
|
20
|
-
requirement: &
|
20
|
+
requirement: &22996340 !ruby/object:Gem::Requirement
|
21
21
|
none: false
|
22
22
|
requirements:
|
23
23
|
- - ! '>='
|
@@ -25,10 +25,10 @@ dependencies:
|
|
25
25
|
version: '0'
|
26
26
|
type: :development
|
27
27
|
prerelease: false
|
28
|
-
version_requirements: *
|
28
|
+
version_requirements: *22996340
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: microtest
|
31
|
-
requirement: &
|
31
|
+
requirement: &22995600 !ruby/object:Gem::Requirement
|
32
32
|
none: false
|
33
33
|
requirements:
|
34
34
|
- - ! '>='
|
@@ -36,10 +36,10 @@ dependencies:
|
|
36
36
|
version: '0'
|
37
37
|
type: :development
|
38
38
|
prerelease: false
|
39
|
-
version_requirements: *
|
39
|
+
version_requirements: *22995600
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: ae
|
42
|
-
requirement: &
|
42
|
+
requirement: &22994880 !ruby/object:Gem::Requirement
|
43
43
|
none: false
|
44
44
|
requirements:
|
45
45
|
- - ! '>='
|
@@ -47,7 +47,7 @@ dependencies:
|
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
|
-
version_requirements: *
|
50
|
+
version_requirements: *22994880
|
51
51
|
description: ! 'A priority queue is like a standard queue, except that each inserted
|
52
52
|
elements
|
53
53
|
|
@@ -66,7 +66,6 @@ extra_rdoc_files:
|
|
66
66
|
- COPYING.rdoc
|
67
67
|
files:
|
68
68
|
- .ruby
|
69
|
-
- lib/pqueue/legacy.rb
|
70
69
|
- lib/pqueue.rb
|
71
70
|
- test/test_pqueue.rb
|
72
71
|
- HISTORY.rdoc
|
data/lib/pqueue/legacy.rb
DELETED
@@ -1,269 +0,0 @@
|
|
1
|
-
# PQueue, a Priority Queue with array based heap.
|
2
|
-
#
|
3
|
-
# A priority queue is like a standard queue, except that each inserted
|
4
|
-
# elements is given a certain priority, based on the result of the
|
5
|
-
# comparison block given at instantiation time. Also, retrieving an element
|
6
|
-
# from the queue will always return the one with the highest priority
|
7
|
-
# (see #pop and #top).
|
8
|
-
#
|
9
|
-
# The default is to compare the elements in repect to their #> method.
|
10
|
-
# For example, Numeric elements with higher values will have higher
|
11
|
-
# priorities.
|
12
|
-
#
|
13
|
-
class PQueue
|
14
|
-
|
15
|
-
# number of elements
|
16
|
-
attr_reader :size
|
17
|
-
# compare Proc
|
18
|
-
attr_reader :gt
|
19
|
-
attr_reader :qarray #:nodoc:
|
20
|
-
protected :qarray
|
21
|
-
|
22
|
-
# Returns a new priority queue.
|
23
|
-
#
|
24
|
-
# If elements are given, build the priority queue with these initial
|
25
|
-
# values. The elements object must respond to #to_a.
|
26
|
-
#
|
27
|
-
# If a block is given, it will be used to determine the priority between
|
28
|
-
# the elements.
|
29
|
-
#
|
30
|
-
# By default, the priority queue retrieves maximum elements first
|
31
|
-
# (using the #> method).
|
32
|
-
def initialize(elements=nil, &block) # :yields: a, b
|
33
|
-
@qarray = [nil]
|
34
|
-
@size = 0
|
35
|
-
@gt = block || lambda {|a,b| a > b}
|
36
|
-
replace(elements) if elements
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
# Assumes that the tree is a heap, for nodes < k.
|
42
|
-
#
|
43
|
-
# The element at index k will go up until it finds its place.
|
44
|
-
def upheap(k)
|
45
|
-
k2 = k.div(2)
|
46
|
-
v = @qarray[k]
|
47
|
-
while k2 > 0 && @gt[v, @qarray[k2]]
|
48
|
-
@qarray[k] = @qarray[k2]
|
49
|
-
k = k2
|
50
|
-
k2 = k2.div(2)
|
51
|
-
end
|
52
|
-
@qarray[k] = v
|
53
|
-
end
|
54
|
-
|
55
|
-
# Assumes the entire tree is a heap.
|
56
|
-
#
|
57
|
-
# The element at index k will go down until it finds its place.
|
58
|
-
def downheap(k)
|
59
|
-
v = @qarray[k]
|
60
|
-
q2 = @size.div(2)
|
61
|
-
loop {
|
62
|
-
break if k > q2
|
63
|
-
j = 2 * k
|
64
|
-
if j < @size && @gt[@qarray[j+1], @qarray[j]]
|
65
|
-
j += 1
|
66
|
-
end
|
67
|
-
break if @gt[v, @qarray[j]]
|
68
|
-
@qarray[k] = @qarray[j]
|
69
|
-
k = j
|
70
|
-
}
|
71
|
-
@qarray[k] = v;
|
72
|
-
end
|
73
|
-
|
74
|
-
|
75
|
-
# Recursive version of heapify. I kept the code, since it may be
|
76
|
-
# easier to understand than the non-recursive one.
|
77
|
-
# def heapify
|
78
|
-
# @size.div(2).downto(1) {|i| h(i)}
|
79
|
-
# end
|
80
|
-
# def h(t)
|
81
|
-
# l = 2 * t
|
82
|
-
# r = l + 1
|
83
|
-
# hi = if r > @size || @gt[@qarray[l],@qarray[r]] then l else r end
|
84
|
-
# if @gt[@qarray[hi],@qarray[t]]
|
85
|
-
# @qarray[hi], @qarray[t] = @qarray[t], @qarray[hi]
|
86
|
-
# h(hi) if hi <= @size.div(2)
|
87
|
-
# end
|
88
|
-
# end
|
89
|
-
|
90
|
-
# Make a heap out of an unordered array.
|
91
|
-
def heapify
|
92
|
-
@size.div(2).downto(1) do |t|
|
93
|
-
begin
|
94
|
-
l = 2 * t
|
95
|
-
r = l + 1
|
96
|
-
hi = if r > @size || @gt[@qarray[l],@qarray[r]] then l else r end
|
97
|
-
if @gt[@qarray[hi],@qarray[t]]
|
98
|
-
@qarray[hi], @qarray[t] = @qarray[t], @qarray[hi]
|
99
|
-
if hi <= @size.div(2)
|
100
|
-
t = hi
|
101
|
-
redo
|
102
|
-
end # if
|
103
|
-
end #if
|
104
|
-
end #begin
|
105
|
-
end # downto
|
106
|
-
end
|
107
|
-
|
108
|
-
public
|
109
|
-
|
110
|
-
# Add an element in the priority queue.
|
111
|
-
#
|
112
|
-
# The insertion time is O(log n), with n the size of the queue.
|
113
|
-
def push(v)
|
114
|
-
@size += 1
|
115
|
-
@qarray[@size] = v
|
116
|
-
upheap(@size)
|
117
|
-
return self
|
118
|
-
end
|
119
|
-
|
120
|
-
alias :<< :push
|
121
|
-
|
122
|
-
# Return the element with the highest priority and remove it from
|
123
|
-
# the queue.
|
124
|
-
#
|
125
|
-
# The highest priority is determined by the block given at instanciation
|
126
|
-
# time.
|
127
|
-
#
|
128
|
-
# The deletion time is O(log n), with n the size of the queue.
|
129
|
-
#
|
130
|
-
# Return nil if the queue is empty.
|
131
|
-
def pop
|
132
|
-
return nil if empty?
|
133
|
-
res = @qarray[1]
|
134
|
-
@qarray[1] = @qarray[@size]
|
135
|
-
@size -= 1
|
136
|
-
downheap(1)
|
137
|
-
return res
|
138
|
-
end
|
139
|
-
|
140
|
-
# Return the element with the highest priority.
|
141
|
-
def top
|
142
|
-
return nil if empty?
|
143
|
-
return @qarray[1]
|
144
|
-
end
|
145
|
-
|
146
|
-
# Add more than one element at the same time. See #push.
|
147
|
-
#
|
148
|
-
# The elements object must respond to #to_a, or to be a PQueue itself.
|
149
|
-
def push_all(elements)
|
150
|
-
if empty?
|
151
|
-
if elements.kind_of?(PQueue)
|
152
|
-
initialize_copy(elements)
|
153
|
-
else
|
154
|
-
replace(elements)
|
155
|
-
end
|
156
|
-
else
|
157
|
-
if elements.kind_of?(PQueue)
|
158
|
-
@qarray[@size + 1, elements.size] = elements.qarray[1..-1]
|
159
|
-
elements.size.times{ @size += 1; upheap(@size)}
|
160
|
-
else
|
161
|
-
ary = elements.to_a
|
162
|
-
@qarray[@size + 1, ary.size] = ary
|
163
|
-
ary.size.times{ @size += 1; upheap(@size)}
|
164
|
-
end
|
165
|
-
end
|
166
|
-
return self
|
167
|
-
end
|
168
|
-
|
169
|
-
alias :merge :push_all
|
170
|
-
|
171
|
-
|
172
|
-
# Return top n-element as a sorted array.
|
173
|
-
def pop_array(n=@size)
|
174
|
-
ary = []
|
175
|
-
n.times{ary.push(pop)}
|
176
|
-
return ary
|
177
|
-
end
|
178
|
-
|
179
|
-
|
180
|
-
# True if there is no more elements left in the priority queue.
|
181
|
-
def empty?
|
182
|
-
return @size.zero?
|
183
|
-
end
|
184
|
-
|
185
|
-
# Remove all elements from the priority queue.
|
186
|
-
def clear
|
187
|
-
@qarray.replace([nil])
|
188
|
-
@size = 0
|
189
|
-
return self
|
190
|
-
end
|
191
|
-
|
192
|
-
# Replace the content of the heap by the new elements.
|
193
|
-
#
|
194
|
-
# The elements object must respond to #to_a, or to be a PQueue itself.
|
195
|
-
def replace(elements)
|
196
|
-
if elements.kind_of?(PQueue)
|
197
|
-
initialize_copy(elements)
|
198
|
-
else
|
199
|
-
@qarray.replace([nil] + elements.to_a)
|
200
|
-
@size = @qarray.size - 1
|
201
|
-
heapify
|
202
|
-
end
|
203
|
-
return self
|
204
|
-
end
|
205
|
-
|
206
|
-
# Return a sorted array, with highest priority first.
|
207
|
-
def to_a
|
208
|
-
old_qarray = @qarray.dup
|
209
|
-
old_size = @size
|
210
|
-
res = pop_array
|
211
|
-
@qarray = old_qarray
|
212
|
-
@size = old_size
|
213
|
-
return res
|
214
|
-
end
|
215
|
-
|
216
|
-
alias :sort :to_a
|
217
|
-
|
218
|
-
# Replace the top element with the given one, and return this top element.
|
219
|
-
#
|
220
|
-
# Equivalent to successively calling #pop and #push(v).
|
221
|
-
def replace_top(v)
|
222
|
-
# replace top element
|
223
|
-
if empty?
|
224
|
-
@qarray[1] = v
|
225
|
-
@size += 1
|
226
|
-
return nil
|
227
|
-
else
|
228
|
-
res = @qarray[1]
|
229
|
-
@qarray[1] = v
|
230
|
-
downheap(1)
|
231
|
-
return res
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
# Return true if the given object is present in the queue.
|
236
|
-
def include?(element)
|
237
|
-
return @qarray.include?(element)
|
238
|
-
end
|
239
|
-
|
240
|
-
# Iterate over the ordered elements, destructively.
|
241
|
-
def each_pop #:yields: popped
|
242
|
-
until empty?
|
243
|
-
yield pop
|
244
|
-
end
|
245
|
-
return nil
|
246
|
-
end
|
247
|
-
|
248
|
-
# Pretty print
|
249
|
-
def inspect
|
250
|
-
"<#{self.class}: size=#{@size}, top=#{top || "nil"}>"
|
251
|
-
end
|
252
|
-
|
253
|
-
###########################
|
254
|
-
### Override Object methods
|
255
|
-
|
256
|
-
# Return true if the queues contain equal elements.
|
257
|
-
def ==(other)
|
258
|
-
return size == other.size && to_a == other.to_a
|
259
|
-
end
|
260
|
-
|
261
|
-
private
|
262
|
-
|
263
|
-
def initialize_copy(other)
|
264
|
-
@gt = other.gt
|
265
|
-
@qarray = other.qarray.dup
|
266
|
-
@size = other.size
|
267
|
-
end
|
268
|
-
end # class PQueue
|
269
|
-
|