discrete_event 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9e7875c381a853a1246453ae83b5cfb1f1b50f05
4
+ data.tar.gz: 1e405666d2a7e03b0123f2ace8e4e1ca571242c1
5
+ SHA512:
6
+ metadata.gz: 318572c57f5188a0e4450aa37ecc7516d2152a4d65865b238ba97cf7ed0c797803aa54e78d0aa3f2d8681281601071f97ac37c3210acb14ff9f08211dbc35531
7
+ data.tar.gz: d0f301f5b7de3140efb41f812e269b750c466331ba583868c5c50e1b98b768c9e6b03add22fdc5c80a1323bca8c68a38889a6e8586aed58d83a56cb49d31ac21
data/README.rdoc CHANGED
@@ -31,16 +31,17 @@ subclass of {DiscreteEvent::EventQueue}, to simulate an M/M/1 queueing system.
31
31
 
32
32
  attr_reader :arrival_rate, :service_rate, :system, :served
33
33
 
34
- def initialize arrival_rate, service_rate
34
+ def initialize(arrival_rate, service_rate)
35
35
  super()
36
- @arrival_rate, @service_rate = arrival_rate, service_rate
36
+ @arrival_rate = arrival_rate
37
+ @service_rate = service_rate
37
38
  @system = []
38
39
  @served = []
39
40
  end
40
41
 
41
42
  # Sample from Exponential distribution with given mean rate.
42
- def rand_exp rate
43
- -Math::log(rand)/rate
43
+ def rand_exp(rate)
44
+ -Math.log(rand) / rate
44
45
  end
45
46
 
46
47
  # Customer arrival process.
@@ -69,7 +70,11 @@ subclass of {DiscreteEvent::EventQueue}, to simulate an M/M/1 queueing system.
69
70
  # Number of customers currently waiting for service (does not include
70
71
  # the one (if any) currently being served).
71
72
  def queue_length
72
- if system.empty? then 0 else system.length - 1 end
73
+ if system.empty?
74
+ 0
75
+ else
76
+ system.length - 1
77
+ end
73
78
  end
74
79
 
75
80
  # Called by super.run.
@@ -81,7 +86,7 @@ subclass of {DiscreteEvent::EventQueue}, to simulate an M/M/1 queueing system.
81
86
  #
82
87
  # Run until a fixed number of passengers has been served.
83
88
  #
84
- def mm1_queue_demo arrival_rate, service_rate, num_pax
89
+ def mm1_queue_demo(arrival_rate, service_rate, num_pax)
85
90
  # Run simulation and accumulate stats.
86
91
  q = MM1Queue.new arrival_rate, service_rate
87
92
  num_served = 0
@@ -89,7 +94,7 @@ subclass of {DiscreteEvent::EventQueue}, to simulate an M/M/1 queueing system.
89
94
  total_wait = 0.0
90
95
  q.run do
91
96
  unless q.served.empty?
92
- raise "confused" if q.served.size > 1
97
+ raise 'confused' if q.served.size > 1
93
98
  c = q.served.shift
94
99
  total_queue += c.queue_on_arrival
95
100
  total_wait += c.service_begin - c.arrival_time
@@ -103,12 +108,13 @@ subclass of {DiscreteEvent::EventQueue}, to simulate an M/M/1 queueing system.
103
108
  expected_mean_wait = rho / (service_rate - arrival_rate)
104
109
  expected_mean_queue = arrival_rate * expected_mean_wait
105
110
 
106
- return total_queue / num_served, expected_mean_queue,
107
- total_wait / num_served, expected_mean_wait
111
+ [
112
+ total_queue / num_served, expected_mean_queue,
113
+ total_wait / num_served, expected_mean_wait
114
+ ]
108
115
  end
109
116
 
110
117
 
111
-
112
118
  This and other examples are available in the <tt>test/discrete_event</tt>
113
119
  directory.
114
120
 
@@ -150,14 +156,14 @@ You may also be interested in the Ruby bindings of the GNU Science Library, whic
150
156
  * added DiscreteEvent::Simulation#at_each_index (removed in 1.0.0)
151
157
  * added DiscreteEvent::Simulation#recur_after
152
158
  * added DiscreteEvent::Simulation#every
153
- * {DiscreteEvent::FakeRand} now supports the <tt>Kernel::rand(n)</tt> form.
159
+ * {DiscreteEvent::FakeRand} now supports the <tt>Kernel::rand(n)</tt> form.
154
160
 
155
161
  <em>0.1.0:</em>
156
162
  * first release
157
163
 
158
164
  == LICENSE
159
165
 
160
- Copyright (c) 2010-2011 John Lees-Miller
166
+ Copyright (c) 2010-2017 John Lees-Miller
161
167
 
162
168
  Permission is hereby granted, free of charge, to any person obtaining
163
169
  a copy of this software and associated documentation files (the
@@ -177,4 +183,3 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
177
183
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
178
184
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
179
185
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
180
-
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pqueue'
2
4
 
3
5
  require 'discrete_event/event_queue'
@@ -14,7 +16,7 @@ module DiscreteEvent
14
16
  #
15
17
  # @return [Simulation]
16
18
  #
17
- def self.simulation *args, &block
19
+ def self.simulation(*args, &block)
18
20
  sim = DiscreteEvent::Simulation.new(*args)
19
21
  sim.instance_eval(&block)
20
22
  sim
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DiscreteEvent
2
4
  #
3
5
  # Queue of pending events; also keeps track of the clock (the current time).
@@ -32,9 +34,9 @@ module DiscreteEvent
32
34
  #
33
35
  attr_reader :events
34
36
 
35
- def initialize now=0.0
37
+ def initialize(now = 0.0)
36
38
  @now = now
37
- @events = PQueue.new {|a,b| a.time < b.time}
39
+ @events = PQueue.new { |a, b| a.time < b.time }
38
40
  @recur_interval = nil
39
41
  end
40
42
 
@@ -48,8 +50,8 @@ module DiscreteEvent
48
50
  #
49
51
  # @return [Event]
50
52
  #
51
- def at time, &action
52
- raise "cannot schedule event in the past" if time < now
53
+ def at(time, &action)
54
+ raise 'cannot schedule event in the past' if time < now
53
55
  event = Event.new(time, action)
54
56
  @events.push(event)
55
57
  event
@@ -65,7 +67,7 @@ module DiscreteEvent
65
67
  #
66
68
  # @return [Event]
67
69
  #
68
- def after delay, &action
70
+ def after(delay, &action)
69
71
  at(@now + delay, &action)
70
72
  end
71
73
 
@@ -76,7 +78,7 @@ module DiscreteEvent
76
78
  #
77
79
  # @return [nil]
78
80
  #
79
- def cancel event
81
+ def cancel(event)
80
82
  # not very efficient but hopefully not used very often
81
83
  temp = []
82
84
  until @events.empty? || @events.top.time > event.time
@@ -84,8 +86,8 @@ module DiscreteEvent
84
86
  break if e.equal?(event)
85
87
  temp << e
86
88
  end
87
- temp.each do |e|
88
- @events.push(e)
89
+ temp.each do |temp_event|
90
+ @events.push(temp_event)
89
91
  end
90
92
  nil
91
93
  end
@@ -93,7 +95,7 @@ module DiscreteEvent
93
95
  #
94
96
  # Schedule +action+ (a block) to run for each element in the given list
95
97
  # (possibly at different times).
96
- #
98
+ #
97
99
  # This method may be of interest if you have a large number of events that
98
100
  # occur at known times. You could use {#at} to add each one to the event
99
101
  # queue at the start of the simulation, but this will make adding other
@@ -125,7 +127,7 @@ module DiscreteEvent
125
127
  #
126
128
  # @return [nil]
127
129
  #
128
- def at_each elements, time=nil, &action
130
+ def at_each(elements, time = nil, &action)
129
131
  raise ArgumentError, 'no action given' unless block_given?
130
132
 
131
133
  unless elements.empty?
@@ -133,11 +135,11 @@ module DiscreteEvent
133
135
  if time.nil?
134
136
  element_time = element.time
135
137
  elsif time.is_a? Proc
136
- element_time = time.call(element)
138
+ element_time = time.call(element)
137
139
  elsif time.is_a? Symbol
138
140
  element_time = element.send(time)
139
- else
140
- raise ArgumentError, "bad time"
141
+ else
142
+ raise ArgumentError, 'bad time'
141
143
  end
142
144
 
143
145
  at element_time do
@@ -178,13 +180,13 @@ module DiscreteEvent
178
180
  #
179
181
  # @return [nil]
180
182
  #
181
- def recur_after interval
182
- raise "cannot recur twice" if @recur_interval
183
+ def recur_after(interval)
184
+ raise 'cannot recur twice' if @recur_interval
183
185
  @recur_interval = interval
184
186
  nil
185
187
  end
186
188
 
187
- #
189
+ #
188
190
  # Schedule +action+ (a block) to run periodically.
189
191
  #
190
192
  # This is useful for statistics collection.
@@ -206,7 +208,7 @@ module DiscreteEvent
206
208
  #
207
209
  # @return [nil]
208
210
  #
209
- def every interval, start=0, &action
211
+ def every(interval, start = 0)
210
212
  at start do
211
213
  yield
212
214
  recur_after interval
@@ -221,15 +223,11 @@ module DiscreteEvent
221
223
  # (that is, the current event hasn't finished yet, so it's still in some
222
224
  # sense the next event).
223
225
  #
224
- # @return [Numeric, nil]
226
+ # @return [Numeric, nil]
225
227
  #
226
228
  def next_event_time
227
229
  event = @events.top
228
- if event
229
- event.time
230
- else
231
- nil
232
- end
230
+ event.time if event
233
231
  end
234
232
 
235
233
  #
@@ -266,7 +264,7 @@ module DiscreteEvent
266
264
  #
267
265
  # @return [nil]
268
266
  #
269
- def run_to time
267
+ def run_to(time)
270
268
  # add an event to ensure that we actually stop at the given time, even if
271
269
  # there isn't an event in the queue
272
270
  at time do
@@ -304,16 +302,15 @@ module DiscreteEvent
304
302
  self
305
303
  end
306
304
 
307
- #
305
+ #
308
306
  # Clear any pending events in the event queue and reset {#now}.
309
307
  #
310
308
  # @return [self]
311
309
  #
312
- def reset now=0.0
310
+ def reset(now = 0.0)
313
311
  @now = now
314
312
  @events.clear
315
313
  self
316
314
  end
317
315
  end
318
316
  end
319
-
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DiscreteEvent
2
4
  #
3
5
  # Mix-in for simulations with multiple objects that have to share the same
@@ -16,7 +18,7 @@ module DiscreteEvent
16
18
  #
17
19
  # @return [Event]
18
20
  #
19
- def at time, &action
21
+ def at(time, &action)
20
22
  event_queue.at(time, &action)
21
23
  end
22
24
 
@@ -29,7 +31,7 @@ module DiscreteEvent
29
31
  #
30
32
  # @return [Event]
31
33
  #
32
- def after delay, &action
34
+ def after(delay, &action)
33
35
  event_queue.after(delay, &action)
34
36
  end
35
37
 
@@ -38,7 +40,7 @@ module DiscreteEvent
38
40
  #
39
41
  # @return [nil]
40
42
  #
41
- def cancel event
43
+ def cancel(event)
42
44
  event_queue.cancel(event)
43
45
  end
44
46
 
@@ -63,7 +65,7 @@ module DiscreteEvent
63
65
  #
64
66
  # @return [nil]
65
67
  #
66
- def at_each elements, time=nil, &action
68
+ def at_each(elements, time = nil, &action)
67
69
  event_queue.at_each(elements, time, &action)
68
70
  end
69
71
 
@@ -74,11 +76,11 @@ module DiscreteEvent
74
76
  #
75
77
  # @return [nil]
76
78
  #
77
- def recur_after interval
79
+ def recur_after(interval)
78
80
  event_queue.recur_after(interval)
79
81
  end
80
82
 
81
- #
83
+ #
82
84
  # See {EventQueue#every}.
83
85
  #
84
86
  # @param [Numeric] interval non-negative
@@ -86,7 +88,7 @@ module DiscreteEvent
86
88
  # @param [Numeric] start block first runs at this time
87
89
  #
88
90
  # @return [nil]
89
- def every interval, start=0, &action
91
+ def every(interval, start = 0, &action)
90
92
  event_queue.every(interval, start, &action)
91
93
  end
92
94
 
@@ -100,4 +102,3 @@ module DiscreteEvent
100
102
  end
101
103
  end
102
104
  end
103
-
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DiscreteEvent
2
4
  #
3
5
  # A utility for testing objects that use the built-in Ruby pseudorandom
@@ -36,16 +38,16 @@ module DiscreteEvent
36
38
  # @param [Array] fakes sequence of numbers to return
37
39
  # @return [nil]
38
40
  #
39
- def self.for object, *fakes
41
+ def self.for(object, *fakes)
40
42
  undo_for(object) # in case rand is already faked
41
43
  (class << object; self; end).instance_eval do
42
44
  define_method :rand do |*args|
43
- raise "out of fake_rand numbers" if fakes.empty?
45
+ raise 'out of fake_rand numbers' if fakes.empty?
44
46
  r = fakes.shift
45
47
 
46
48
  # can be either the rand() or rand(n) form
47
49
  n = args.shift || 0
48
- if n == 0
50
+ if n.zero?
49
51
  r
50
52
  else
51
53
  (r * n).to_i
@@ -62,11 +64,10 @@ module DiscreteEvent
62
64
  # @param [Object] object to modify
63
65
  # @return [nil]
64
66
  #
65
- def self.undo_for object
66
- if object.methods.map(&:to_s).member?('rand')
67
- (class << object; self; end).instance_eval do
68
- remove_method :rand
69
- end
67
+ def self.undo_for(object)
68
+ return unless object.methods.map(&:to_s).member?('rand')
69
+ (class << object; self; end).instance_eval do
70
+ remove_method :rand
70
71
  end
71
72
  end
72
73
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DiscreteEvent
2
4
  #
3
5
  # A simulation, including an {EventQueue}, the current time, and various
@@ -12,17 +14,16 @@ module DiscreteEvent
12
14
  #
13
15
  # @abstract
14
16
  #
15
- def start
16
- end
17
+ def start; end
17
18
 
18
19
  #
19
- # Run (or continue, if there are existing events) the simulation until
20
+ # Run (or continue, if there are existing events) the simulation until
20
21
  # +:stop+ is thrown, or there are no more events.
21
22
  #
22
- # @yield [] after each event runs
23
+ # @yield [] after each event runs
23
24
  # @return [nil]
24
25
  #
25
- def run &block
26
+ def run
26
27
  start if @events.empty?
27
28
  catch :stop do
28
29
  if block_given?
@@ -34,4 +35,3 @@ module DiscreteEvent
34
35
  end
35
36
  end
36
37
  end
37
-
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DiscreteEvent
2
- VERSION_MAJOR = 1
3
- VERSION_MINOR = 1
4
+ VERSION_MAJOR = 2
5
+ VERSION_MINOR = 0
4
6
  VERSION_PATCH = 0
5
7
  VERSION = [VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH].join('.')
6
8
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'discrete_event/test_helper'
2
4
 
3
5
  require 'discrete_event/ex_consumer.rb'
@@ -6,10 +8,12 @@ require 'discrete_event/ex_mm1_queue.rb'
6
8
  include DiscreteEvent
7
9
  include DiscreteEvent::Example
8
10
 
9
- class TestDiscreteEvent < Test::Unit::TestCase
10
- def assert_near expected, observed, tol=1e-6
11
- assert((expected - observed).abs < tol,
12
- "expected |#{expected} - #{observed}| < #{tol}")
11
+ class TestDiscreteEvent < MiniTest::Test
12
+ def assert_near(expected, observed, tol = 1e-6)
13
+ assert(
14
+ (expected - observed).abs < tol,
15
+ "expected |#{expected} - #{observed}| < #{tol}"
16
+ )
13
17
  end
14
18
 
15
19
  def test_fake_rand
@@ -25,7 +29,7 @@ class TestDiscreteEvent < Test::Unit::TestCase
25
29
  assert_equal [0.125, 0.375, 0.875], c.consumed
26
30
 
27
31
  # Now have run out of fakes.
28
- assert_raise(RuntimeError){ c.reset.run }
32
+ assert_raises(RuntimeError) { c.reset.run }
29
33
 
30
34
  # See what happens if we fake twice.
31
35
  FakeRand.for(c, 0.5, 0.25, 0.125)
@@ -33,7 +37,7 @@ class TestDiscreteEvent < Test::Unit::TestCase
33
37
  assert_equal [0.5, 0.75, 0.875], c.consumed
34
38
 
35
39
  # Now have run out of fakes, again.
36
- assert_raise(RuntimeError){ c.reset.run }
40
+ assert_raises(RuntimeError) { c.reset.run }
37
41
 
38
42
  # Can undo and get original behavior back.
39
43
  FakeRand.undo_for(c)
@@ -57,13 +61,13 @@ class TestDiscreteEvent < Test::Unit::TestCase
57
61
  assert_equal 10, o.test
58
62
 
59
63
  # Now have run out of fakes.
60
- assert_raise(RuntimeError){ o.test }
64
+ assert_raises(RuntimeError) { o.test }
61
65
  end
62
-
66
+
63
67
  def test_mm1_queue_not_busy
64
68
  # Service begins immediately when queue is not busy.
65
69
  q = MM1Queue.new 0.5, 1.0
66
- fakes = [1, 1, 1, 1, 1].map {|x| 1/Math::E**x}
70
+ fakes = [1, 1, 1, 1, 1].map { |x| 1 / Math::E**x }
67
71
  FakeRand.for(q, *fakes)
68
72
  q.run do
69
73
  throw :stop if q.served.size >= 2
@@ -75,15 +79,17 @@ class TestDiscreteEvent < Test::Unit::TestCase
75
79
  assert_near 4.0, q.served[1].service_begin
76
80
  assert_near 5.0, q.served[1].service_end
77
81
  end
78
-
82
+
79
83
  def test_mm1_queue_busy
80
84
  # Service begins after previous customer when queue is busy.
81
85
  q = MM1Queue.new 0.5, 1.0
82
- fakes = [0.1, 0.1, # arrival, service for first customer
86
+ fakes = [
87
+ 0.1, 0.1, # arrival, service for first customer
83
88
  0.01, 0.01, # arrival times for second two customers
84
89
  1, # arrival for forth customer
85
90
  0.1, 0.1, # service times for second two customers
86
- 1].map {|x| 1/Math::E**x}
91
+ 1
92
+ ].map { |x| 1 / Math::E**x }
87
93
  FakeRand.for(q, *fakes)
88
94
  q.run do
89
95
  throw :stop if q.served.size >= 3
@@ -101,14 +107,14 @@ class TestDiscreteEvent < Test::Unit::TestCase
101
107
 
102
108
  def test_recur_after
103
109
  output = []
104
- DiscreteEvent.simulation {
110
+ DiscreteEvent.simulation do
105
111
  at 0 do
106
112
  output << now
107
113
  recur_after 5 if now < 20
108
114
  end
109
115
 
110
116
  run
111
- }
117
+ end
112
118
  assert_equal [0, 5, 10, 15, 20], output
113
119
  end
114
120
 
@@ -117,7 +123,7 @@ class TestDiscreteEvent < Test::Unit::TestCase
117
123
  # displace the root element, even if you call after(0), which is just an
118
124
  # edge case anyway.
119
125
  output = []
120
- DiscreteEvent.simulation {
126
+ DiscreteEvent.simulation do
121
127
  at 0 do
122
128
  output << now
123
129
  after 0 do
@@ -130,64 +136,64 @@ class TestDiscreteEvent < Test::Unit::TestCase
130
136
  end
131
137
 
132
138
  run
133
- }
139
+ end
134
140
  assert_equal [0, 42, 13, 5, 42, 13, 10, 42, 13], output
135
141
  end
136
142
 
137
143
  def test_every
138
144
  output = []
139
- DiscreteEvent.simulation {
145
+ DiscreteEvent.simulation do
140
146
  every 3 do
141
147
  output << now
142
148
  throw :stop if now > 10
143
149
  end
144
150
  run
145
- }
146
- assert_equal [0,3,6,9,12], output
151
+ end
152
+ assert_equal [0, 3, 6, 9, 12], output
147
153
  end
148
154
 
149
155
  Alert = Struct.new(:when, :message)
150
156
 
151
157
  def test_at_each_with_symbol
152
158
  output = []
153
- DiscreteEvent.simulation {
154
- alerts = [Alert.new(12, "ha!"), Alert.new(42, "ah!")] # and many more
159
+ DiscreteEvent.simulation do
160
+ alerts = [Alert.new(12, 'ha!'), Alert.new(42, 'ah!')] # and many more
155
161
  at_each alerts, :when do |alert|
156
162
  output << now << alert.message
157
163
  end
158
164
  run
159
- }
165
+ end
160
166
  assert_equal [12, 'ha!', 42, 'ah!'], output
161
167
  end
162
168
 
163
169
  def test_at_each_with_proc
164
170
  output = []
165
- DiscreteEvent.simulation {
166
- alerts = [Alert.new(12, "ha!"), Alert.new(42, "ah!")] # and many more
167
- at_each(alerts, proc{|alert| alert.when}) do |alert|
171
+ DiscreteEvent.simulation do
172
+ alerts = [Alert.new(12, 'ha!'), Alert.new(42, 'ah!')] # and many more
173
+ at_each(alerts, proc { |alert| alert.when }) do |alert|
168
174
  output << now << alert.message
169
175
  end
170
176
  run
171
- }
177
+ end
172
178
  assert_equal [12, 'ha!', 42, 'ah!'], output
173
179
  end
174
180
 
175
181
  Alert2 = Struct.new(:time, :message)
176
182
  def test_at_each_with_default
177
183
  output = []
178
- DiscreteEvent.simulation {
179
- alerts = [Alert2.new(12, "ha!"), Alert2.new(42, "ah!")] # and many more
184
+ DiscreteEvent.simulation do
185
+ alerts = [Alert2.new(12, 'ha!'), Alert2.new(42, 'ah!')] # and many more
180
186
  at_each alerts do |alert|
181
187
  output << now << alert.message
182
188
  end
183
189
  run
184
- }
190
+ end
185
191
  assert_equal [12, 'ha!', 42, 'ah!'], output
186
192
  end
187
193
 
188
194
  def test_next_event_time
189
- output= []
190
- s = DiscreteEvent.simulation {
195
+ output = []
196
+ s = DiscreteEvent.simulation do
191
197
  at 0 do
192
198
  output << next_event_time
193
199
  end
@@ -195,7 +201,7 @@ class TestDiscreteEvent < Test::Unit::TestCase
195
201
  at 5 do
196
202
  output << next_event_time
197
203
  end
198
- }
204
+ end
199
205
  assert_equal 0, s.next_event_time
200
206
  assert s.run_next
201
207
  assert_equal 5, s.next_event_time
@@ -215,16 +221,16 @@ class TestDiscreteEvent < Test::Unit::TestCase
215
221
  eq.at 42 do
216
222
  output << 'bye'
217
223
  end
218
- for t in eq.to_enum
224
+ eq.to_enum.each do |t|
219
225
  output_times << t
220
226
  end
221
- assert_equal %w(hi bye), output
227
+ assert_equal %w[hi bye], output
222
228
  assert_equal [13, 42], output_times
223
229
  end
224
-
230
+
225
231
  def test_mm1_queue_demo
226
232
  # Just run the demo... 1000 isn't enough to get a reliable average.
227
- obs_q, exp_q, obs_w, exp_w= mm1_queue_demo(0.25, 0.5, 1000)
233
+ _obs_q, exp_q, _obs_w, exp_w = mm1_queue_demo(0.25, 0.5, 1000)
228
234
  assert_near exp_q, 0.5 # mean queue = rho^2 / (1 - rho)
229
235
  assert_near exp_w, 2.0 # mean wait = rho / (mu - lambda)
230
236
  end
@@ -232,7 +238,7 @@ class TestDiscreteEvent < Test::Unit::TestCase
232
238
  def test_producer_consumer
233
239
  event_queue = EventQueue.new(0)
234
240
  consumer = Consumer.new(event_queue)
235
- producer = Producer.new(event_queue, %w(a b c d), consumer)
241
+ producer = Producer.new(event_queue, %w[a b c d], consumer)
236
242
 
237
243
  FakeRand.for(consumer, 2, 2, 2, 2)
238
244
  FakeRand.for(producer, 1, 1, 1, 1)
@@ -243,14 +249,15 @@ class TestDiscreteEvent < Test::Unit::TestCase
243
249
  output << [now, consumer.consumed.dup]
244
250
  end
245
251
  assert_equal [
246
- [1, []], # first object produced
247
- [2, []], # second object produced
248
- [3, ["a"]], # third object produced / first consumed
249
- [3, ["a"]],
250
- [4, ["a", "b"]], # fourth object produced / second consumed
251
- [4, ["a", "b"]],
252
- [5, ["a", "b", "c"]], # third and fourth objects consumed
253
- [6, ["a", "b", "c", "d"]]], output
252
+ [1, []], # first object produced
253
+ [2, []], # second object produced
254
+ [3, %w[a]], # third object produced / first consumed
255
+ [3, %w[a]],
256
+ [4, %w[a b]], # fourth object produced / second consumed
257
+ [4, %w[a b]],
258
+ [5, %w[a b c]], # third and fourth objects consumed
259
+ [6, %w[a b c d]]
260
+ ], output
254
261
  end
255
262
 
256
263
  def test_cancel_single
@@ -259,7 +266,7 @@ class TestDiscreteEvent < Test::Unit::TestCase
259
266
  #
260
267
  out = []
261
268
  q = EventQueue.new(0)
262
- e_a = q.at( 5) { out << :a }
269
+ e_a = q.at(5) { out << :a }
263
270
  q.cancel e_a
264
271
  assert !q.run_next
265
272
  assert_equal [], out
@@ -271,7 +278,7 @@ class TestDiscreteEvent < Test::Unit::TestCase
271
278
  #
272
279
  out = []
273
280
  q = EventQueue.new(0)
274
- e_a = q.at( 5) { out << :a }
281
+ e_a = q.at(5) { out << :a }
275
282
  assert q.run_next
276
283
  assert_equal [:a], out
277
284
  q.cancel e_a
@@ -284,8 +291,8 @@ class TestDiscreteEvent < Test::Unit::TestCase
284
291
  #
285
292
  out = []
286
293
  q = EventQueue.new(0)
287
- e_a = q.at( 5) { out << :a }
288
- e_b = q.at(10) { out << :b }
294
+ e_a = q.at(5) { out << :a }
295
+ q.at(10) { out << :b }
289
296
  q.cancel e_a
290
297
  nil while q.run_next
291
298
  assert_equal [:b], out
@@ -295,20 +302,20 @@ class TestDiscreteEvent < Test::Unit::TestCase
295
302
  out = []
296
303
  q = EventQueue.new(0)
297
304
 
298
- e_a = q.at( 5) do
305
+ e_a = q.at(5) do
299
306
  out << :a
300
307
 
301
- e_c = q.at(6) { out << :c }
302
-
308
+ q.at(6) { out << :c }
309
+
303
310
  q.cancel e_a # This should have no effect
304
311
  end
305
312
 
306
- e_b = q.at(10) do
313
+ q.at(10) do
307
314
  out << :b
308
315
  end
309
-
316
+
310
317
  nil while q.run_next
311
- assert_equal [:a, :c, :b], out
318
+ assert_equal %i[a c b], out
312
319
  end
313
320
 
314
321
  def test_cancel_last
@@ -317,7 +324,7 @@ class TestDiscreteEvent < Test::Unit::TestCase
317
324
  #
318
325
  out = []
319
326
  q = EventQueue.new(0)
320
- e_a = q.at( 5) { out << :a }
327
+ q.at(5) { out << :a }
321
328
  e_b = q.at(10) { out << :b }
322
329
  q.cancel e_b
323
330
  nil while q.run_next
@@ -330,12 +337,12 @@ class TestDiscreteEvent < Test::Unit::TestCase
330
337
  #
331
338
  out = []
332
339
  q = EventQueue.new(0)
333
- e_a = q.at( 5) { out << :a }
340
+ q.at(5) { out << :a }
334
341
  e_b = q.at(10) { out << :b }
335
- e_c = q.at(13) { out << :c }
342
+ q.at(13) { out << :c }
336
343
  q.cancel e_b
337
344
  nil while q.run_next
338
- assert_equal [:a, :c], out
345
+ assert_equal %i[a c], out
339
346
  end
340
347
 
341
348
  def test_cancel_at_same_time_1
@@ -363,7 +370,7 @@ class TestDiscreteEvent < Test::Unit::TestCase
363
370
  #
364
371
  out = []
365
372
  q = EventQueue.new(0)
366
- e_a = q.at 10 do
373
+ q.at 10 do
367
374
  out << :a
368
375
  end
369
376
  e_b = q.at 10 do
@@ -430,4 +437,3 @@ class TestDiscreteEvent < Test::Unit::TestCase
430
437
  assert_equal [:a], out
431
438
  end
432
439
  end
433
-
metadata CHANGED
@@ -1,39 +1,60 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: discrete_event
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
5
- prerelease:
4
+ version: 2.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - John Lees-Miller
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-11-14 00:00:00.000000000 Z
11
+ date: 2017-07-10 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: pqueue
16
- requirement: &74031670 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
- version: 2.0.2
19
+ version: '2.0'
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *74031670
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
25
27
  - !ruby/object:Gem::Dependency
26
28
  name: gemma
27
- requirement: &74031240 !ruby/object:Gem::Requirement
28
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
29
37
  requirements:
30
- - - ~>
38
+ - - "~>"
31
39
  - !ruby/object:Gem::Version
32
- version: 2.4.0
40
+ version: '5.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: simplecov
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.14'
33
48
  type: :development
34
49
  prerelease: false
35
- version_requirements: *74031240
36
- description: Some simple primitives for event-based discrete event simulation.
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.14'
55
+ description: |-
56
+ Some simple primitives for event-based discrete event
57
+ simulation.
37
58
  email:
38
59
  - jdleesmiller@gmail.com
39
60
  executables: []
@@ -41,48 +62,40 @@ extensions: []
41
62
  extra_rdoc_files:
42
63
  - README.rdoc
43
64
  files:
65
+ - README.rdoc
44
66
  - lib/discrete_event.rb
45
- - lib/discrete_event/events.rb
46
- - lib/discrete_event/version.rb
47
67
  - lib/discrete_event/event_queue.rb
48
- - lib/discrete_event/simulation.rb
68
+ - lib/discrete_event/events.rb
49
69
  - lib/discrete_event/fake_rand.rb
50
- - README.rdoc
70
+ - lib/discrete_event/simulation.rb
71
+ - lib/discrete_event/version.rb
51
72
  - test/discrete_event/discrete_event_test.rb
52
73
  homepage: http://github.com/jdleesmiller/discrete_event
53
74
  licenses: []
75
+ metadata: {}
54
76
  post_install_message:
55
77
  rdoc_options:
56
- - --main
78
+ - "--main"
57
79
  - README.rdoc
58
- - --title
59
- - discrete_event-1.1.0 Documentation
80
+ - "--title"
81
+ - discrete_event-2.0.0 Documentation
60
82
  require_paths:
61
83
  - lib
62
84
  required_ruby_version: !ruby/object:Gem::Requirement
63
- none: false
64
85
  requirements:
65
- - - ! '>='
86
+ - - ">="
66
87
  - !ruby/object:Gem::Version
67
88
  version: '0'
68
- segments:
69
- - 0
70
- hash: 326435089
71
89
  required_rubygems_version: !ruby/object:Gem::Requirement
72
- none: false
73
90
  requirements:
74
- - - ! '>='
91
+ - - ">="
75
92
  - !ruby/object:Gem::Version
76
93
  version: '0'
77
- segments:
78
- - 0
79
- hash: 326435089
80
94
  requirements: []
81
95
  rubyforge_project: discrete_event
82
- rubygems_version: 1.8.17
96
+ rubygems_version: 2.6.8
83
97
  signing_key:
84
- specification_version: 3
98
+ specification_version: 4
85
99
  summary: Event-based discrete event simulation.
86
100
  test_files:
87
101
  - test/discrete_event/discrete_event_test.rb
88
- has_rdoc: