lazy_priority_queue 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/lazy_priority_queue.rb +55 -31
- metadata +37 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b680e6b802c52236c0dcca0d886a6972f35d303b
|
4
|
+
data.tar.gz: dbbc45bb9bf1522279ba8ad7c016f584bd98620a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46bfa4d71d535dc4df7da9781df4e7b7d354a343e41b6da429cd9d9aad17b1cf23cbaf7e76962115e17c5ad99cc37e91315b0d0aab7d20d2548eb0f9c022ec06
|
7
|
+
data.tar.gz: e9277abcf22ae9c4db96636a10620f4ec87a4eb5687de440cad4b201311341c4190edd77cd8af69e049a11975e2ff2b3bf3b11f11320b479a17782ab6b88021d
|
data/lib/lazy_priority_queue.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
class LazyPriorityQueue
|
2
|
-
|
3
2
|
Node = Struct.new :element,
|
4
3
|
:key,
|
5
4
|
:rank,
|
@@ -7,15 +6,18 @@ class LazyPriorityQueue
|
|
7
6
|
:left_child,
|
8
7
|
:right_sibling
|
9
8
|
|
10
|
-
def initialize
|
9
|
+
def initialize(top_condition, &heap_property)
|
10
|
+
@top = nil
|
11
11
|
@roots = []
|
12
12
|
@references = {}
|
13
13
|
@top_condition = top_condition
|
14
14
|
@heap_property = heap_property
|
15
15
|
end
|
16
16
|
|
17
|
-
def enqueue
|
18
|
-
|
17
|
+
def enqueue(element, key)
|
18
|
+
if @references[element]
|
19
|
+
raise 'The provided element already is in the queue.'
|
20
|
+
end
|
19
21
|
|
20
22
|
node = Node.new element, key, 0
|
21
23
|
|
@@ -25,17 +27,20 @@ class LazyPriorityQueue
|
|
25
27
|
|
26
28
|
element
|
27
29
|
end
|
28
|
-
|
29
|
-
|
30
|
+
alias push enqueue
|
31
|
+
alias insert enqueue
|
30
32
|
|
31
|
-
def change_priority
|
33
|
+
def change_priority(element, new_key)
|
32
34
|
node = @references[element]
|
33
35
|
|
34
36
|
raise 'Element provided is not in the queue.' unless node
|
35
37
|
|
36
38
|
test_node = node.clone
|
37
39
|
test_node.key = new_key
|
38
|
-
|
40
|
+
|
41
|
+
unless @heap_property[test_node, node]
|
42
|
+
raise 'Priority can only be changed to a more prioritary value.'
|
43
|
+
end
|
39
44
|
|
40
45
|
node.key = new_key
|
41
46
|
node = sift_up node
|
@@ -45,7 +50,7 @@ class LazyPriorityQueue
|
|
45
50
|
end
|
46
51
|
|
47
52
|
def peek
|
48
|
-
@top
|
53
|
+
@top && @top.element
|
49
54
|
end
|
50
55
|
|
51
56
|
def dequeue
|
@@ -66,25 +71,30 @@ class LazyPriorityQueue
|
|
66
71
|
end
|
67
72
|
|
68
73
|
@roots = coalesce @roots
|
69
|
-
@top = @roots.inject { |top, node| select
|
74
|
+
@top = @roots.inject { |top, node| select(top, node) }
|
70
75
|
|
71
76
|
element
|
72
77
|
end
|
73
|
-
|
78
|
+
alias pop dequeue
|
74
79
|
|
75
|
-
def delete
|
80
|
+
def delete(element)
|
76
81
|
change_priority element, @top_condition
|
77
82
|
dequeue
|
78
83
|
end
|
79
84
|
|
80
|
-
def empty
|
81
|
-
|
82
|
-
|
85
|
+
def empty?
|
86
|
+
@references.empty?
|
87
|
+
end
|
88
|
+
|
89
|
+
def size
|
90
|
+
@references.size
|
91
|
+
end
|
92
|
+
alias length size
|
83
93
|
|
84
94
|
private
|
85
95
|
|
86
|
-
def sift_up
|
87
|
-
return node unless node.parent
|
96
|
+
def sift_up(node)
|
97
|
+
return node unless node.parent && !@heap_property[node.parent, node]
|
88
98
|
|
89
99
|
node.parent.key, node.key = node.key, node.parent.key
|
90
100
|
node.parent.element, node.element = node.element, node.parent.element
|
@@ -95,11 +105,11 @@ class LazyPriorityQueue
|
|
95
105
|
sift_up node.parent
|
96
106
|
end
|
97
107
|
|
98
|
-
def select
|
108
|
+
def select(parent_node, child_node)
|
99
109
|
@heap_property[parent_node, child_node] ? parent_node : child_node
|
100
110
|
end
|
101
111
|
|
102
|
-
def coalesce
|
112
|
+
def coalesce(trees)
|
103
113
|
coalesced_trees = []
|
104
114
|
|
105
115
|
while tree = trees.pop
|
@@ -116,11 +126,21 @@ class LazyPriorityQueue
|
|
116
126
|
coalesced_trees.compact
|
117
127
|
end
|
118
128
|
|
119
|
-
def add
|
120
|
-
|
121
|
-
|
129
|
+
def add(node_one, node_two)
|
130
|
+
if node_one.rank != node_two.rank
|
131
|
+
raise 'Both nodes must hold the same rank.'
|
132
|
+
end
|
122
133
|
|
123
|
-
|
134
|
+
if node_one.parent || node_two.parent
|
135
|
+
raise 'Both nodes must be roots (no parents).'
|
136
|
+
end
|
137
|
+
|
138
|
+
adder_node, addend_node =
|
139
|
+
if @heap_property[node_one, node_two]
|
140
|
+
[node_one, node_two]
|
141
|
+
else
|
142
|
+
[node_two, node_one]
|
143
|
+
end
|
124
144
|
|
125
145
|
addend_node.parent = adder_node
|
126
146
|
|
@@ -137,20 +157,24 @@ end
|
|
137
157
|
|
138
158
|
class MinPriorityQueue < LazyPriorityQueue
|
139
159
|
def initialize
|
140
|
-
super(-Float::INFINITY)
|
160
|
+
super(-Float::INFINITY) do |parent_node, child_node|
|
161
|
+
parent_node.key <= child_node.key
|
162
|
+
end
|
141
163
|
end
|
142
164
|
|
143
|
-
|
144
|
-
|
145
|
-
|
165
|
+
alias decrease_key change_priority
|
166
|
+
alias min peek
|
167
|
+
alias extract_min dequeue
|
146
168
|
end
|
147
169
|
|
148
170
|
class MaxPriorityQueue < LazyPriorityQueue
|
149
171
|
def initialize
|
150
|
-
super(
|
172
|
+
super(Float::INFINITY) do |parent_node, child_node|
|
173
|
+
parent_node.key >= child_node.key
|
174
|
+
end
|
151
175
|
end
|
152
176
|
|
153
|
-
|
154
|
-
|
155
|
-
|
177
|
+
alias increase_key change_priority
|
178
|
+
alias max peek
|
179
|
+
alias extract_max dequeue
|
156
180
|
end
|
metadata
CHANGED
@@ -1,19 +1,47 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lazy_priority_queue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matías Battocchia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
12
|
-
dependencies:
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
date: 2016-04-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: A priority queue which implements a lazy binomial heap. It supports the
|
42
|
+
change priority operation, being suitable for algorithms like Dijkstra's shortest
|
43
|
+
path and Prim's minimum spanning tree. It can be instantiated as a min-priority
|
44
|
+
queue as well as a max-priority queue.
|
17
45
|
email: matias@riseup.net
|
18
46
|
executables: []
|
19
47
|
extensions: []
|
@@ -22,7 +50,7 @@ files:
|
|
22
50
|
- lib/lazy_priority_queue.rb
|
23
51
|
homepage: https://github.com/matiasbattocchia/lazy_priority_queue
|
24
52
|
licenses:
|
25
|
-
-
|
53
|
+
- FreeBSD
|
26
54
|
metadata: {}
|
27
55
|
post_install_message:
|
28
56
|
rdoc_options: []
|
@@ -40,7 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
40
68
|
version: '0'
|
41
69
|
requirements: []
|
42
70
|
rubyforge_project:
|
43
|
-
rubygems_version: 2.
|
71
|
+
rubygems_version: 2.5.1
|
44
72
|
signing_key:
|
45
73
|
specification_version: 4
|
46
74
|
summary: A priority queue implemented using a lazy binomial heap. It allows change
|