I'm attempting to simulate the occurrence of an event (a vehicle entering a tunnel), which as it turns out is a Poisson process.
I've broken the day up into 1 minute intervals, starting from 9am to 5pm.
For each 1 minute interval, I've computed/obtained the mean:
- Number of vehicles that enter the tunnel during that period.
- Time between each vehicle entering the tunnel (expected interarrival time)
For example for the minute 10:37-38 the mean is 5 vehicles with a mean inter-arrival time of 12seconds
To sample the 10:37-38 minute I do the following:
- Sample a Poisson distribution with a mean of 5 to determine how many items will arrive, assign to X
- Sample an exponential distribution of mean 1/12 X times to derive inter-arrival times y_0,y_1..._y_x
- Sum the interarrival times and assign to K
- If K is larger than 60seconds go to step 2
- Accumulate various counters
- Finally print statistics.
The code is as follows:
#include <iostream>
#include <cstdio>
#include <random>
#include <algorithm>
#include <iterator>
int main()
{
double mean_num_itms = 5.0;
double mean_inter_time = 12; //seconds
double max_sec_in_period = 60; //seconds
unsigned int rounds = 10000;
std::random_device r;
std::exponential_distribution<double> exponential(1.0 / mean_inter_time);
std::poisson_distribution<double> poisson(mean_num_itms);
double total_itms = 0;
double total_inter_time = 0;
for (std::size_t i = 0; i < rounds; ++i)
{
//Determine how many items will arrive in time period
unsigned int num_itms = (unsigned int)(poisson(r));
total_itms += num_itms;
//Get the interarrival times for the 'num_itms'
double last_arrival_time = 0;
do
{
last_arrival_time = 0;
for (unsigned int j = 0; j < num_itms; ++j)
{
double current_arrival_time = exponential(r);
last_arrival_time += current_arrival_time ;
}
}
//Reject any group of arrival times that exceed period span.
while (last_arrival_time > max_sec_in_period);
total_inter_time += last_arrival_time;
}
printf("Mean items per minute: %8.3f\n" ,total_itms / rounds);
printf("Mean inter-arrival time: %8.3fsec\n",total_inter_time / total_itms);
return 0;
}
The problem with the code above is:
The rejection part is very costly
The results for the mean inter-arrival time is incorrect:
- Mean items per minute: 5.014
- Mean inter-arrival time: 7.647sec
So my questions are as follows:
Is there a better more efficient technique to ensure that the total inter-arrival times never exceed the maximum number of seconds in the period?
Why is the mean inter-arrival time skewed down? for the example above I expect it to be roughly 12 - I think there's a bug in the code but can't seem to put my finger on it.