File Coverage

blib/lib/Array/Heap/PriorityQueue/Numeric.pm
Criterion Covered Total %
statement 37 40 92.5
branch 4 10 40.0
condition n/a
subroutine 13 14 92.8
pod 10 10 100.0
total 64 74 86.4


line stmt bran cond sub pod time code
1             package Array::Heap::PriorityQueue::Numeric;
2 1     1   14773 use strict;
  1         1  
  1         25  
3 1     1   4 use warnings;
  1         1  
  1         25  
4 1     1   3 use vars qw( $VERSION );
  1         0  
  1         54  
5             $VERSION = '1.10';
6 1     1   455 use Array::Heap qw( make_heap pop_heap push_heap );
  1         471  
  1         388  
7              
8             =head1 NAME
9              
10             Array::Heap::PriorityQueue::Numeric - Numeric priority queue
11              
12             =head1 SYNOPSIS
13              
14             use Array::Heap::PriorityQueue::Numeric;
15             my $pq = Array::Heap::PriorityQueue::Numeric->new();
16             $pq->add('fish', 42);
17             $pq->add('banana', 27);
18             print $pq->get(), "\n"; # banana
19             print $pq->peek(), "\n"; # fish
20              
21             =head1 DESCRIPTION
22              
23             This module implements a priority queue, which is a data structure that can
24             efficiently locate the item with the lowest weight at any time. This is useful
25             for writing cost-minimizing and shortest-path algorithms.
26              
27             Weights are numeric values.
28              
29             This module is a wrapper for the *_heap methods provided by L.
30              
31             =head1 FUNCTIONS
32              
33             =over 4
34              
35             =item Array::Heap::PriorityQueue::Numeric->new()
36              
37             Create a new, empty priority queue.
38              
39             =cut
40              
41             sub new {
42 1     1 1 18 my ($class) = @_;
43 1         6 return bless [ ] => $class;
44             }
45              
46             =item $pq->add($item, $weight)
47              
48             Add an item to the priority queue with the given weight. Weight must be
49             numeric, and defaults to item.
50              
51             =cut
52              
53             sub add {
54 1     1 1 4 my ($self, $item, $weight) = @_;
55 1 50       6 $weight = $item + 0 unless defined $weight;
56 1         9 push_heap @$self, [ $weight, $item ];
57             }
58              
59             =item $pq->peek()
60              
61             Return the first (numerically lowest weight) item from the queue.
62             Does not modify the queue. Returns undef if the queue is empty.
63              
64             =cut
65              
66             sub peek {
67 1     1 1 3 my ($self) = @_;
68 1 50       11 my $node = $self->[0] or return;
69 1         5 return $node->[1];
70             }
71              
72             =item $pq->get()
73              
74             Removes the first item from the priority queue and returns it.
75             Returns undef if the queue is empty. If two items in the queue
76             have equal weight, this module makes no guarantee as to which
77             one will be returned first.
78              
79             =cut
80              
81             sub get {
82 1     1 1 4 my ($self) = @_;
83 1 50       16 my $node = pop_heap @$self or return;
84 1         6 return $node->[1];
85             }
86              
87             =item $pq->min_weight()
88              
89             Returns the weight of the lowest item in the queue, or undef if empty.
90              
91             =cut
92              
93             sub min_weight {
94 0     0 1 0 my ($self) = @_;
95 0 0       0 my $node = $self->[0] or return;
96 0         0 return $node->[0];
97             }
98              
99             =item $pq->size()
100              
101             Returns the number of items in the priority queue.
102              
103             =cut
104              
105             sub size {
106 1     1 1 10 my ($self) = @_;
107 1         7 return scalar @$self;
108             }
109              
110             =item $pq->items()
111              
112             Returns all items in the heap, in an arbitrary order.
113              
114             =cut
115              
116             sub items {
117 1     1 1 3 my ($self) = @_;
118 1         5 return map { $_->[1] } @$self;
  3         18  
119             }
120              
121             =item $pq->sorted_items()
122              
123             Returns all items in the heap, in weight order.
124              
125             =cut
126              
127             sub sorted_items {
128 1     1 1 3 my ($self) = @_;
129 1         7 return map { $_->[1] } sort { $a->[0] <=> $b->[0] } @$self;
  3         10  
  3         8  
130             }
131              
132             =item $pq->add_unordered($item, $weight)
133              
134             Add an item to the priority queue or change its weight, without updating
135             the heap structure. If you are adding a bunch of items at once, it may be
136             more efficient to use add_unordered, then call $pq->restore_order() once
137             you are done. Weight defaults to item.
138              
139             =cut
140              
141             sub add_unordered {
142 3     3 1 1086 my ($self, $item, $weight) = @_;
143 3 50       10 $weight = $item + 0 unless defined $weight;
144 3         15 push @$self, [ $weight, $item ];
145             }
146              
147             =item $pq->restore_order()
148              
149             Restore the heap structure after calling add_unordered. You need to do this
150             before calling any of the ordered methods (add, peek, or get).
151              
152             =cut
153              
154             sub restore_order {
155 1     1 1 6 my ($self) = @_;
156 1         22 make_heap @$self;
157             }
158              
159             =back
160              
161             =head1 LIMITATIONS
162              
163             Weights are sorted in increasing order only. If you want it the other way,
164             use the negative of the weights you have.
165              
166             =head1 SEE ALSO
167              
168             L
169              
170             =head1 AUTHOR
171              
172             Bob Mathews
173              
174             =head1 REPOSITORY
175              
176             L
177              
178             =head1 COPYRIGHT
179              
180             This program is free software; you can redistribute
181             it and/or modify it under the same terms as Perl itself.
182              
183             The full text of the license can be found in the
184             LICENSE file included with this module.
185              
186             =cut
187              
188             1 # end Numeric.pm