pqueue 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|