Skip to content

Instantly share code, notes, and snippets.

@rab
Created August 18, 2010 20:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rab/536140 to your computer and use it in GitHub Desktop.
Save rab/536140 to your computer and use it in GitHub Desktop.
Simulating Vehicle traffic for Bruce Wayner <winshocker@gmail.com>

run with:

ruby simulating_vehicles.rb

or to see each vehicle:

ruby -v simulating_vehicles.rb

You'll have to tally the results yourself across many runs, but this is way more than you deserve. (And you really need to understand it before you turn it in.)

$ time ruby -v simulating_vehicles.rb
ruby 1.9.2p0 (2010-08-18 revision 29036) [i386-darwin9.8.0]
leaves at 0 w/40 arriving 55 [40] [40 @ 55]
leaves at 12 w/2 arriving 79 [42] [42 @ 79]
leaves at 24 w/40 arriving 86 [82] [82 @ 86]
leaves at 44 w/40 arriving 108 [122] [122 @ 108]
leaves at 59 w/1 arriving 127 [123] [123 @ 127]
leaves at 90 w/4 arriving 149 [127] [127 @ 149]
leaves at 111 w/2 arriving 166 [129] [129 @ 166]
leaves at 139 w/1 arriving 197 [130] [130 @ 197]
leaves at 154 w/2 arriving 224 [132] [132 @ 224]
leaves at 177 w/40 arriving 231 [172] [172 @ 231]
leaves at 206 w/40 arriving 260 [212] [212 @ 260]
leaves at 227 w/40 arriving 296 [252] [252 @ 296]
leaves at 259 w/2 arriving 311 [254] [254 @ 311]
leaves at 265 w/1 arriving 321 [255] [255 @ 321]
leaves at 276 w/2 arriving 342 [257] [257 @ 342]
leaves at 293 w/1 arriving 344 [258] [258 @ 344]
leaves at 319 w/2 arriving 372 [260] [260 @ 372]
leaves at 324 w/40 arriving 394 [300] [300 @ 394]
leaves at 352 w/40 arriving 420 [340] [340 @ 420]
leaves at 376 w/1 arriving 433 [341] [341 @ 433]
leaves at 392 w/40 arriving 452 [381] [381 @ 452]
leaves at 412 w/40 arriving 464 [421] [421 @ 464]
leaves at 441 w/1 arriving 504 [422] [422 @ 504]
leaves at 473 w/3 arriving 523 [425] [425 @ 523]
leaves at 507 w/3 arriving 571 [428] [428 @ 571]
leaves at 537 w/2 arriving 606 [430] [430 @ 606]
leaves at 571 w/1 arriving 623 [431] [431 @ 623]
leaves at 589 w/40 arriving 639 [471] [471 @ 639]
leaves at 605 w/2 arriving 671 [473] [473 @ 671]
leaves at 640 w/1 arriving 695 [474] [474 @ 695]
leaves at 646 w/40 arriving 702 [514] [514 @ 702]
leaves at 660 w/3 arriving 717 [517] [514 @ 702]
leaves at 669 w/4 arriving 722 [521] [514 @ 702]
leaves at 691 w/1 arriving 751 [522] [514 @ 702]
=> 514 @ 702
real 0m0.026s
user 0m0.016s
sys 0m0.008s
module Simulation
class Config
class << self
# 50..70 (seconds)
attr_accessor :travel_time_range
# 5..35 (seconds)
attr_accessor :departure_rate_range
# key=passengers, value=percentage
# { 1 => 20, 2 => 30, ... }
attr_accessor :passengers_probability
def passengers
raise "No passenger capacities configured" if self.passengers_probability.empty?
sample = rand(100)
self.passengers_probability.sort.each do |passengers,probability|
sample -= probability
return passengers if sample <= 0
end
return 0
end
def departure_delay
low = self.departure_rate_range.begin
high = self.departure_rate_range.end
span = high - low + (self.departure_rate_range.exclude_end? ? 0 : 1)
return low + rand(span)
end
def travel_time
low = self.travel_time_range.begin
high = self.travel_time_range.end
span = high - low + (self.travel_time_range.exclude_end? ? 0 : 1)
return low + rand(span)
end
end
end
class Vehicle
attr_reader :departure_time, :travel_time, :arrival_time
attr_accessor :passengers
def initialize(departs_at)
@departure_time = departs_at
@passengers = Config.passengers
@travel_time = Config.travel_time
@arrival_time = @departure_time + @travel_time
end
def to_s
"leaves at %4d w/%-2d arriving %4d"%[self.departure_time,
self.passengers,
self.arrival_time]
end
end
end
Simulation::Config.departure_rate_range = 5..35 # (seconds)
Simulation::Config.travel_time_range = 50..70 # (seconds)
Simulation::Config.passengers_probability = { 1 => 20, 2 => 30, 3 => 10, 4 => 10, 40 => 30 }
next_departure = 0
vehicles = []
simple_sum = 0
final_count, final_time = 0, 0
loop do
vehicle = Simulation::Vehicle.new(next_departure)
vehicles << vehicle
simple_sum += vehicle.passengers
final_count, final_time = vehicles.sort_by {|v| v.arrival_time }.inject([0,0]) do |(count,time),v|
if count >= 500
[count,time]
else
[count+v.passengers, v.arrival_time]
end
end
puts "#{vehicle} [#{simple_sum}] [#{final_count} @ #{final_time}]" if $VERBOSE
next_departure += Simulation::Config.departure_delay
break if final_count >= 500 && next_departure > final_time
end
puts "=> #{final_count} @ #{final_time}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment