Arjen Markus (25 june 2007) Monte Carlo simulations are useful in many cases where the system being studied reacts to random input, but also if you want to determine the integral of a function over a complicated area. Such simulations usually require a lot of steps and sometimes numerous runs to get meaningful results.
The script below is an attempt to model a simple queueing system. See the comments for more information. It tries to answer a vexing question: how long does one have to wait (on average)?
proc randomBinomial {p} {
return [expr {rand()>$p? 0 : 1}]
}
proc runQueue {nosteps} {
global waiting_times
global queue
set queue {}
for { set time 0 } { $time < $nosteps } { incr time } {
if { [randomBinomial 0.2] == 1 } {
if { [randomBinomial 0.1] == 1 } {
set request 10
} else {
set request 3
}
set person [list $time $request]
lappend queue $person
}
if { [llength $queue] > 0 } {
set person [lindex $queue 0]
foreach {arrival_time request} $person {break}
if { $request <= 0 } {
set queue [lrange $queue 1 end]
lappend waiting_times [expr {$time-$arrival_time}]
} else {
set request [expr {$request-1}]
lset queue 0 1 $request
}
}
}
}
set av_av_time 0
set av_max_time 0
set av_queue 0
set av_count 0
for { set i 0 } { $i < 50 } { incr i } {
set waiting_times {}
runQueue 480
set count 0
set average_time 0
set max_time 0
foreach time $waiting_times {
set average_time [expr {$average_time + $time}]
incr count
if { $time > $max_time } {
set max_time $time
}
}
set average_time [expr {$average_time/double($count)}]
set av_count [expr {$av_count + $count}]
set av_av_time [expr {$av_av_time + $average_time}]
set av_max_time [expr {$av_max_time + $max_time}]
set av_queue [expr {$av_queue + [llength $queue]}]
puts "Simulation $i: [format %.1f $average_time] - $max_time"
}
puts "Sample averages:"
puts "----------------"
puts "Number of persons: [format %.1f [expr {$av_count/50.0}]]"
puts "Average waiting time: [format %.1f [expr {$av_av_time/50.0}]]"
puts "Maximum waiting time: [format %.1f [expr {$av_max_time/50.0}]]"
puts "People still waiting: [format %.1f [expr {$av_queue/50.0}]]"