Skip to content

Instantly share code, notes, and snippets.

@msaffitz
Created September 14, 2020 23:43
Show Gist options
  • Save msaffitz/aadcdbc50fd2a90515f2b5163971d0da to your computer and use it in GitHub Desktop.
Save msaffitz/aadcdbc50fd2a90515f2b5163971d0da to your computer and use it in GitHub Desktop.
Monte Carlo Dock Capacity Planning
#!/bin/ruby
BOAT_SIZES = [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
BOAT_COUNTS = [ 3, 3, 3, 4, 5, 6, 7, 5, 4, 4, 4, 4]
ALL_BOATS = BOAT_SIZES.zip(BOAT_COUNTS).map { |s,c| Array.new(c, s) }.flatten
BUFFER = 3 # Spacing between boats
MAX_SIZES = 23.upto(34) # Maximum length overall permitted to moore
ITERATIONS = 5000
MAX_DOCK_LENGTH = 316
MAX_SIZES.each do |max_size|
total_boats_moored = []
ITERATIONS.times do |i|
arrivals = ALL_BOATS.shuffle
remaining_capacity = MAX_DOCK_LENGTH
boats_moored = 0
next_arrival = arrivals.shift
until remaining_capacity < (next_arrival + BUFFER) || arrivals.length == 0
if next_arrival > max_size
next_arrival = arrivals.shift
next
end
boats_moored += 1
remaining_capacity -= (next_arrival + BUFFER)
next_arrival = arrivals.shift
end
total_boats_moored << boats_moored
end
histogram = total_boats_moored.group_by { |v| v }.transform_values { |v| v.size.to_f / ITERATIONS * 100 }.sort_by { |_, v| v }
average = total_boats_moored.sum.to_f / total_boats_moored.count
puts "#{max_size} offers #{histogram} (average #{average})"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment