PriorityQueue 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ 0.1.2
2
+ * Repaired benchmark
3
+ * Added c_priority_queue wrapper, such that one can now require versions
4
+ explicitly using:
5
+ require "priority_queue/(c|ruby|poor)_priority_queue"
6
+ * Improved README
7
+
1
8
  0.1.1
2
9
  * Removed debug cruft
3
10
  * Added more documentation and examples
data/README CHANGED
@@ -3,9 +3,9 @@
3
3
  ## Description
4
4
  This is a fibonacci-heap priority-queue implementation. That means
5
5
 
6
- insert: O(1)
7
- decrease_priority: Amortized O(1)
8
- delete_min: Amortized O(log n)
6
+ insert: O(1)
7
+ decrease_priority: Amortized O(1)
8
+ delete_min: Amortized O(log n)
9
9
 
10
10
  This project is different from K. Kodamas PQueue in that it allows a decrease
11
11
  key operation. That makes PriorityQueue usable for algorithms like dijkstras
@@ -29,17 +29,24 @@ guarantee it will work for you.
29
29
 
30
30
  ## Installation
31
31
 
32
+ ### Installing from source
33
+
32
34
  De-compress archive and enter its top directory.
33
35
  Then type:
34
36
 
35
37
  ($ su)
36
- $ ruby setup.rb
38
+ # ruby setup.rb
37
39
 
38
40
  These simple step installs this program under the default
39
41
  location of Ruby libraries. You can also install files into
40
42
  your favorite directory by supplying setup.rb some options.
41
43
  Try "ruby setup.rb --help".
42
44
 
45
+ ### Installing a ruby gem
46
+
47
+ ($ su)
48
+ # gem install PriorityQueue
49
+
43
50
  ## Usage
44
51
 
45
52
  In this priority queue implementation the queue behaves similarly to a hash
@@ -81,5 +88,46 @@ that maps objects onto priorities.
81
88
  for more exmples look into the documentation, the unit tests and the benchmark
82
89
  suite.
83
90
 
84
- # Todo
91
+ ### Dijkstras shortest path algorithm
92
+ def dijkstra(start_node)
93
+ # Nodes that may have neighbours wich can be relaxed further
94
+ active = PriorityQueue.new
95
+ # Best distances found so far
96
+ distances = Hash.new { 1.0 / 0.0 }
97
+ # Parent pointers describing shortest paths for all nodes
98
+ parents = Hash.new
99
+
100
+ # Initialize with start node
101
+ active[start_node] = 0
102
+ until active.empty?
103
+ u, distance = active.delete_min
104
+ distances[u] = distance
105
+ d = distance + 1
106
+ u.neighbours.each do | v |
107
+ next unless d < distances[v] # we can't relax this one
108
+ active[v] = distances[v] = d
109
+ parents[v] = u
110
+ end
111
+ end
112
+ parents
113
+ end
114
+
115
+ ## Performance
116
+ The benchmark directory contains an example where a random graph is created and
117
+ the shortests paths from a random node in this graph to all other nodes are
118
+ calculated with dijkstras shortests path algorithm. The algorithm is used to
119
+ compare the three different priority queue implementations in this package.
120
+
121
+ * PoorPriorityQueue: A minimal priority queue implementation wich has
122
+ delete_min in O(n).
123
+ * RubyPriorityQueue: An efficent implementation in pure ruby.
124
+ * CPriorityQueue: The same efficent implementation as a c extension.
125
+
126
+ The results are shown here
127
+
128
+ ![Runtime for graphs of up to 8_000 Nodes](doc/compare_small.png "Runtime for graphs of up to 8_000 Nodes")
129
+
130
+ ![Runtime for graphs of up to 600_000 Nodes](doc/compare_big.png "Runtime for graphs of up to 600_000 Nodes")
131
+
132
+ ## Todo
85
133
  * Only write documentation once
@@ -1,7 +1,7 @@
1
- require 'PriorityQueue/RubyPriorityQueue'
2
- require 'PriorityQueue/PoorPriorityQueue'
3
- require 'PriorityQueue/CPriorityQueue'
4
- require 'pqueue'
1
+ $:.unshift "~/lib/ruby"
2
+ require 'priority_queue/ruby_priority_queue'
3
+ require 'priority_queue/poor_priority_queue'
4
+ require 'priority_queue/c_priority_queue'
5
5
  require 'benchmark'
6
6
 
7
7
  class Node
@@ -79,6 +79,7 @@ degrees = [2, 4, 16]
79
79
  degrees = [4, 16]
80
80
  degrees = [16]
81
81
  queues = [ CPriorityQueue, PoorPriorityQueue, RubyPriorityQueue ]
82
+ queues = [ CPriorityQueue, RubyPriorityQueue ]
82
83
 
83
84
  max_time = 400
84
85
  ignore = Hash.new
@@ -96,8 +97,9 @@ results = Hash.new { | h, k | h[k] =
96
97
  Benchmark.bm(30) do | b |
97
98
  sizes.each do | size |
98
99
  break if !ignore.empty? and ignore.values.inject(true) { | r, v | r and v }
100
+ puts
101
+ puts "Testing with graphs of size #{size}"
99
102
  degrees.each do | degree |
100
- p ignore
101
103
  repeats.times do | r |
102
104
  nodes = make_graph(size, degree)
103
105
  queues.each do | queue |
Binary file
@@ -0,0 +1,14 @@
1
+ set term png
2
+ set out 'compare_big.png'
3
+ set xlabel 'Number of nodes'
4
+ set ylabel 'Time in seconds (real)'
5
+ set yrange [0:240]
6
+ set ytics 30
7
+ set grid ytics mytics
8
+ set mytics 2
9
+ #set logscale xy
10
+ set title 'Dijkstras Shortest Path Algorithm using different PQ Implementations'
11
+ plot \
12
+ 'results.csv' using 1:2 with lines title "CPriorityQueue (Graph of Degree: 4)",\
13
+ 'results.csv' using 1:4 with lines title "RubyPriorityQueue (Graph of Degree: 4)", \
14
+ 'results.csv' using 1:3 with lines title "PoorPriorityQueue (Graph of Degree: 4)"
Binary file
@@ -0,0 +1,15 @@
1
+ set term png
2
+ set out 'compare_small.png'
3
+ set xlabel 'Number of nodes'
4
+ set ylabel 'Time in seconds (real)'
5
+ set yrange [0:60]
6
+ set xrange [0:8000]
7
+ set ytics 15
8
+ set grid ytics mytics
9
+ set mytics 3
10
+ #set logscale xy
11
+ set title 'Dijkstras Shortest Path Algorithm using different PQ Implementations'
12
+ plot \
13
+ 'results.csv' using 1:2 with lines title "CPriorityQueue (Graph of Degree: 4)",\
14
+ 'results.csv' using 1:4 with lines title "RubyPriorityQueue (Graph of Degree: 4)", \
15
+ 'results.csv' using 1:3 with lines title "PoorPriorityQueue (Graph of Degree: 4)"
Binary file
@@ -0,0 +1,37 @@
1
+ size "CPriorityQueue (Graph of Degree: 4)" "PoorPriorityQueue (Graph of Degree: 4)" "RubyPriorityQueue (Graph of Degree: 4)"
2
+ 100 0.00224618911743164 0.00624475479125977 0.00999178886413574
3
+ 200 0.00454645156860352 0.0206499099731445 0.0216238498687744
4
+ 300 0.00689601898193359 0.0456759929656982 0.0333521842956543
5
+ 400 0.00930037498474121 0.0799281597137451 0.0460003852844238
6
+ 500 0.0121791362762451 0.120535612106323 0.0602848052978516
7
+ 600 0.0147404193878174 0.175632238388062 0.0720498085021973
8
+ 700 0.017409610748291 0.239475774765015 0.0866350173950195
9
+ 800 0.019864559173584 0.308732604980469 0.0979691028594971
10
+ 900 0.0226212501525879 0.394028520584106 0.11493763923645
11
+ 1000 0.0251464366912842 0.487221813201904 0.125885772705078
12
+ 2000 0.0565140247344971 2.28050599098206 0.276543807983398
13
+ 3000 0.085650634765625 6.21102161407471 0.448645544052124
14
+ 4000 0.10867018699646 8.67334637641907 0.573670101165771
15
+ 5000 0.138333988189697 14.8025764465332 0.749224042892456
16
+ 6000 0.188258218765259 23.5921889781952 0.926058626174927
17
+ 7000 0.22198920249939 35.1978524208069 1.12497220039368
18
+ 8000 0.253745651245117 51.36594581604 1.34597997665405
19
+ 9000 0.261373472213745 48.2841837882996 1.37383661270142
20
+ 10000 0.296752548217773 63.1833290576935 1.60117835998535
21
+ 20000 0.624662017822266 277.677141237259 3.37345514297485
22
+ 30000 1.0169261932373 733.016969585419 5.47739477157593
23
+ 40000 1.29656438827515 '' 7.03887400627136
24
+ 50000 1.84444799423218 '' 9.04675197601318
25
+ 60000 2.16575860977173 '' 11.4338163852692
26
+ 70000 2.34671788215637 '' 12.989319562912
27
+ 80000 2.91462659835815 '' 14.7507841110229
28
+ 90000 3.36594500541687 '' 17.4672434329987
29
+ 100000 3.74284019470215 '' 19.7872510433197
30
+ 200000 8.33274736404419 '' 44.0830686569214
31
+ 300000 15.3942915916443 '' 75.2278475284576
32
+ 400000 22.4600916385651 '' 109.477935791016
33
+ 500000 29.9784585952759 '' 150.160971403122
34
+ 600000 37.4891954421997 '' 192.808595132828
35
+ 700000 '' '' ''
36
+ 800000 '' '' ''
37
+ 900000 '' '' ''
@@ -762,7 +762,6 @@ VALUE pq_length(VALUE self) {
762
762
  return INT2NUM(q->length);
763
763
  }
764
764
 
765
- /*
766
765
  /* call-seq:
767
766
  * delete(key) -> [key, priority]
768
767
  * delete(key) -> nil
@@ -0,0 +1 @@
1
+ require "priority_queue/CPriorityQueue"
Binary file
Binary file
metadata CHANGED
@@ -1,67 +1,75 @@
1
- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: PriorityQueue
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.1
7
- date: 2005-10-26 00:00:00 +02:00
6
+ version: 0.1.2
7
+ date: 2005-10-30 00:00:00 +02:00
8
8
  summary: This is a fibonacci-heap priority-queue implementation
9
9
  require_paths:
10
- - lib
11
- - lib
12
- - ext
10
+ - lib
11
+ - lib
12
+ - ext
13
13
  email: priority_queue@brian-schroeder.de
14
14
  homepage: http://ruby.brian-schroeder.de/priority_queue
15
15
  rubyforge_project:
16
- description: "This is a fibonacci-heap priority-queue implementation. That means insert: O(1) decrease_priority: Amortized O(1) delete_min: Amortized O(log n) This project is different from K. Kodamas PQueue in that it allows a decrease key operation. That makes PriorityQueue usable for algorithms like dijkstras shortest path algorithm, while PQueue is more suitable for Heapsort and the like."
16
+ description: "This is a fibonacci-heap priority-queue implementation. That means insert:
17
+ O(1) decrease_priority: Amortized O(1) delete_min: Amortized O(log n)
18
+ This project is different from K. Kodamas PQueue in that it allows a decrease
19
+ key operation. That makes PriorityQueue usable for algorithms like dijkstras
20
+ shortest path algorithm, while PQueue is more suitable for Heapsort and the
21
+ like."
17
22
  autorequire: priority_queue.rb
18
23
  default_executable:
19
24
  bindir: bin
20
25
  has_rdoc: true
21
26
  required_ruby_version: !ruby/object:Gem::Version::Requirement
22
27
  requirements:
23
- - - ">"
24
- - !ruby/object:Gem::Version
25
- version: 0.0.0
28
+ -
29
+ - ">"
30
+ - !ruby/object:Gem::Version
31
+ version: 0.0.0
26
32
  version:
27
33
  platform: ruby
28
34
  signing_key:
29
35
  cert_chain:
30
36
  authors:
31
- - Brian Schroeder
37
+ - Brian Schroeder
32
38
  files:
33
- - t.rb
34
- - Makefile
35
- - priority_queue.so
36
- - README
37
- - priority_queue.o
38
- - compare_comments.rb
39
- - CHANGELOG
40
- - setup.rb
41
- - ext
42
- - lib
43
- - test
44
- - benchmark
45
- - ext/priority_queue
46
- - ext/priority_queue/extconf.rb
47
- - ext/priority_queue/priority_queue.c
48
- - lib/priority_queue.rb
49
- - lib/priority_queue
50
- - lib/priority_queue/poor_priority_queue.rb
51
- - lib/priority_queue/ruby_priority_queue.rb
52
- - test/priority_queue_test.rb
53
- - benchmark/dijkstra.rb
54
- test_files: []
55
-
39
+ - Makefile
40
+ - priority_queue.so
41
+ - README
42
+ - priority_queue.o
43
+ - compare_comments.rb
44
+ - CHANGELOG
45
+ - setup.rb
46
+ - doc
47
+ - ext
48
+ - lib
49
+ - test
50
+ - benchmark
51
+ - doc/compare_big.gp
52
+ - doc/compare_big.png
53
+ - doc/compare_small.gp
54
+ - doc/compare_small.png
55
+ - doc/results.csv
56
+ - doc/c-vs-rb.png
57
+ - ext/priority_queue
58
+ - ext/priority_queue/extconf.rb
59
+ - ext/priority_queue/priority_queue.c
60
+ - lib/priority_queue.rb
61
+ - lib/priority_queue
62
+ - lib/priority_queue/c_priority_queue.rb
63
+ - lib/priority_queue/poor_priority_queue.rb
64
+ - lib/priority_queue/ruby_priority_queue.rb
65
+ - test/priority_queue_test.rb
66
+ - benchmark/dijkstra.rb
67
+ test_files:
68
+ - test/priority_queue_test.rb
56
69
  rdoc_options: []
57
-
58
70
  extra_rdoc_files: []
59
-
60
71
  executables: []
61
-
62
72
  extensions:
63
- - ext/priority_queue/extconf.rb
73
+ - ext/priority_queue/extconf.rb
64
74
  requirements: []
65
-
66
- dependencies: []
67
-
75
+ dependencies: []
data/t.rb DELETED
@@ -1,18 +0,0 @@
1
- class T
2
- def initialize
3
- begin
4
- raise "T"
5
- rescue => e
6
- e1 = e
7
- end
8
- begin
9
- raise "T"
10
- rescue => e
11
- e2 = e
12
- end
13
- r1 = 12 rescue Object => e
14
- p [e1, e2, e, r1]
15
- end
16
- end
17
-
18
- T.new