lazy_priority_queue 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/lazy_priority_queue.rb +144 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0fd645a3f0b657b9d5f8d406e3d1c36e88d4e9f0
|
4
|
+
data.tar.gz: 805c1d6fdc15a7604b05457c896009e6e4af17de
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 34178a91738b2884553b73555f9e1a5daaa4a60deb6735ff26fad10704aaf417bc8f244384256dec41eae70ca6343aeac2833581f4e5c8aca89d88e1904132b6
|
7
|
+
data.tar.gz: c963785af0360405e04a0bf0b6b4ce3cfd23e70f8c59a7c7eb710bc5b2bd2ab40f000dc603ea39757c5e1d124ce13b2fcfb7e345d3bc756992ceaa2aabce84a0
|
@@ -0,0 +1,144 @@
|
|
1
|
+
class LazyPriorityQueue
|
2
|
+
|
3
|
+
Node = Struct.new :element,
|
4
|
+
:key,
|
5
|
+
:rank,
|
6
|
+
:parent,
|
7
|
+
:left_child,
|
8
|
+
:right_sibling
|
9
|
+
|
10
|
+
def initialize top_condition, &heap_property
|
11
|
+
@roots = []
|
12
|
+
@references = {}
|
13
|
+
@top_condition = top_condition
|
14
|
+
@heap_property = heap_property
|
15
|
+
end
|
16
|
+
|
17
|
+
def enqueue element, key
|
18
|
+
raise 'The provided element already is in the queue.' if @references[element]
|
19
|
+
|
20
|
+
node = Node.new element, key, 0
|
21
|
+
|
22
|
+
@top = @top ? select(@top, node) : node
|
23
|
+
@roots << node
|
24
|
+
@references[element] = node
|
25
|
+
|
26
|
+
element
|
27
|
+
end
|
28
|
+
|
29
|
+
def change_priority element, new_key
|
30
|
+
node = @references[element]
|
31
|
+
|
32
|
+
raise 'Element provided is not in the queue.' unless node
|
33
|
+
|
34
|
+
test_node = node.clone
|
35
|
+
test_node.key = new_key
|
36
|
+
raise 'Priority can only be changed to a more prioritary value.' unless @heap_property[test_node, node]
|
37
|
+
|
38
|
+
node.key = new_key
|
39
|
+
node = sift_up node
|
40
|
+
@top = select(@top, node) unless node.parent
|
41
|
+
|
42
|
+
element
|
43
|
+
end
|
44
|
+
|
45
|
+
def peek
|
46
|
+
@top and @top.element
|
47
|
+
end
|
48
|
+
|
49
|
+
def dequeue
|
50
|
+
return unless @top
|
51
|
+
|
52
|
+
element = @top.element
|
53
|
+
@references.delete element
|
54
|
+
@roots.delete @top
|
55
|
+
|
56
|
+
child = @top.left_child
|
57
|
+
|
58
|
+
while child
|
59
|
+
next_child = child.right_sibling
|
60
|
+
child.parent = nil
|
61
|
+
child.right_sibling = nil
|
62
|
+
@roots << child
|
63
|
+
child = next_child
|
64
|
+
end
|
65
|
+
|
66
|
+
@roots = coalesce @roots
|
67
|
+
@top = @roots.inject { |top, node| select top, node }
|
68
|
+
|
69
|
+
element
|
70
|
+
end
|
71
|
+
|
72
|
+
def delete element
|
73
|
+
change_priority element, @top_condition
|
74
|
+
dequeue
|
75
|
+
end
|
76
|
+
|
77
|
+
def empty?; @references.empty? end
|
78
|
+
def size; @references.size end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def sift_up node
|
83
|
+
return node unless node.parent and not @heap_property[node.parent, node]
|
84
|
+
|
85
|
+
node.parent.key, node.key = node.key, node.parent.key
|
86
|
+
node.parent.element, node.element = node.element, node.parent.element
|
87
|
+
|
88
|
+
@references[node.element] = node
|
89
|
+
@references[node.parent.element] = node.parent
|
90
|
+
|
91
|
+
sift_up node.parent
|
92
|
+
end
|
93
|
+
|
94
|
+
def select parent_node, child_node
|
95
|
+
@heap_property[parent_node, child_node] ? parent_node : child_node
|
96
|
+
end
|
97
|
+
|
98
|
+
def coalesce trees
|
99
|
+
coalesced_trees = []
|
100
|
+
|
101
|
+
while tree = trees.pop
|
102
|
+
if coalesced_tree = coalesced_trees[tree.rank]
|
103
|
+
# This line must go before than...
|
104
|
+
coalesced_trees[tree.rank] = nil
|
105
|
+
# ...this one.
|
106
|
+
trees << add(tree, coalesced_tree)
|
107
|
+
else
|
108
|
+
coalesced_trees[tree.rank] = tree
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
coalesced_trees.compact
|
113
|
+
end
|
114
|
+
|
115
|
+
def add node_one, node_two
|
116
|
+
raise 'Both nodes must hold the same rank.' if node_one.rank != node_two.rank
|
117
|
+
raise 'Both nodes must be roots (no parents).' if node_one.parent || node_two.parent
|
118
|
+
|
119
|
+
adder_node, addend_node = @heap_property[node_one, node_two] ? [node_one, node_two] : [node_two, node_one]
|
120
|
+
|
121
|
+
addend_node.parent = adder_node
|
122
|
+
|
123
|
+
# This line must go before than...
|
124
|
+
addend_node.right_sibling = adder_node.left_child
|
125
|
+
# ...this one.
|
126
|
+
adder_node.left_child = addend_node
|
127
|
+
|
128
|
+
adder_node.rank += 1
|
129
|
+
|
130
|
+
adder_node
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class MinPriorityQueue < LazyPriorityQueue
|
135
|
+
def initialize
|
136
|
+
super(-Float::INFINITY) { |parent_node, child_node| parent_node.key <= child_node.key }
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class MaxPriorityQueue < LazyPriorityQueue
|
141
|
+
def initialize
|
142
|
+
super( Float::INFINITY) { |parent_node, child_node| parent_node.key >= child_node.key }
|
143
|
+
end
|
144
|
+
end
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lazy_priority_queue
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matías Battocchia
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-11 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Lazy priority queue is a priority queue which implements a lazy binomial
|
14
|
+
heap. It supports the change priority operation, being suitable for algorithms like
|
15
|
+
Dijkstra's shortest path and Prim's minimum spanning tree. It can be instantiated
|
16
|
+
as a min-priority queue as well as a max-priority queue.
|
17
|
+
email: matias@riseup.net
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- lib/lazy_priority_queue.rb
|
23
|
+
homepage: https://github.com/matiasbattocchia/lazy_priority_queue
|
24
|
+
licenses:
|
25
|
+
- MIT
|
26
|
+
metadata: {}
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubyforge_project:
|
43
|
+
rubygems_version: 2.4.5.1
|
44
|
+
signing_key:
|
45
|
+
specification_version: 4
|
46
|
+
summary: A priority queue which implements a lazy binomial heap.
|
47
|
+
test_files: []
|