lazy_priority_queue 0.0.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.
- 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: []
|