イベント (車両がトンネルに入る) の発生をシミュレートしようとしていますが、これはポアソン過程であることが判明しました。
午前 9 時から午後 5 時まで、1 日を 1 分間隔に分割しました。
1分間隔ごとに、平均を計算/取得しました:
- その期間中にトンネルに入る車両の数。
- 各車両のトンネル進入時間(予想到着時間)
たとえば、10:37-38 の場合、平均は 5 台の車両で、平均到着間隔は 12 秒です。
10:37-38 分をサンプリングするには、次のようにします。
- 平均5のポアソン分布をサンプリングして、到着するアイテムの数を決定し、Xに割り当てます
- 平均 1/12 X 回の指数分布をサンプリングして、到着間隔 y_0,y_1..._y_x を導き出します
- 到着間隔を合計し、K に割り当てます
- Kが 60 秒より大きい場合は、手順 2 に進みます。
- 各種カウンターを貯める
- 最後に統計を出力します。
コードは次のとおりです。
#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;
}
上記のコードの問題は次のとおりです。
拒否の部分は非常にコストがかかります
平均到着間隔の結果は正しくありません。
- 1 分あたりの平均アイテム数: 5.014
- 平均到着間隔: 7.647 秒
だから私の質問は次のとおりです:
到着間隔の合計が期間内の最大秒数を決して超えないようにするための、より効率的な手法はありますか?
到着間隔の平均値が偏っているのはなぜですか? 上記の例では、おおよそ 12 になると予想しています。コードにバグがあると思いますが、それを特定することはできません。