Question

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:

  1. Number of vehicles that enter the tunnel during that period.
  2. 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:

  1. Sample a Poisson distribution with a mean of 5 to determine how many items will arrive, assign to X
  2. Sample an exponential distribution of mean 1/12 X times to derive inter-arrival times y_0,y_1..._y_x
  3. Sum the interarrival times and assign to K
  4. If K is larger than 60seconds go to step 2
  5. Accumulate various counters
  6. 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:

  1. The rejection part is very costly

  2. 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:

  1. 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?

  2. 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.

Was it helpful?

Solution

Sounds like you're trying to simulate a non-homogeneous Poisson process where lambda(t) is being defined in piece-wise segments to the nearest minute.

The correct way to do this is with "thinning". Basically, find the maximum lambda(t) and generate pseudo-arrivals at times t1, t2, t3,... at rate lambdamax. For each pseudo-arrival at time ti, accept it as a an actual arrival with probability lambda(ti) / lambdamax. The result is a sequence of the times at which vehicles arrive at the tunnel.

OTHER TIPS

I'm pretty sure the way to go about simulating a Poisson process is to sample the interarrival time and construct arrival times from that -- sampling both the mean number per unit time and the interarrival time doesn't make any sense to me.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top