私はOMNeT ++ 5.1.1シミュレータを使用しています。私はbernoulli()関数からいくつかの奇妙な動作を見てきたので、何が起こっているかを見るためにMWEを構築しました。OMNeT ++ RNGが平均に収束しない
MWEは、単一のノードを持つネットワークを作成し、t = 0に1つのタイマー(自己メッセージ)を設定することによって動作します。タイマがオフになると、シミュレーションは成功確率pでいくつかのn回のベルヌーイ試行を実行します。値nとpは、Register_PerRunConfigOption()マクロを使用して定義した実行単位の設定オプションで指定します。 (私は++ OMNeTに新たなんだ)
#include <math.h>
#include <omnetpp.h>
using namespace omnetpp;
Register_PerRunConfigOption(CFGID_NUM_TRIALS, "num-trials", CFG_INT,
"0", "The number of Bernoulli trials to run");
Register_PerRunConfigOption(CFGID_BERNOULLI_MEAN, "bernoulli-mean",
CFG_DOUBLE, "0.0", "The mean of the Bernoulli experiments");
class Test : public cSimpleModule {
private:
int nTrials, nSuccess;
double p;
cMessage *timer;
protected:
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
};
Define_Module(Test);
void Test::initialize()
{
nTrials = getEnvir()->getConfig()->getAsInt(CFGID_NUM_TRIALS);
p = getEnvir()->getConfig()->getAsDouble(CFGID_BERNOULLI_MEAN);
timer = new cMessage("timer");
scheduleAt(0.0, timer);
}
void Test::handleMessage(cMessage *msg)
{
int trial;
printf("\n\n");
for (int n = 0; n < nTrials; n++) {
trial = bernoulli(p);
if (trial)
nSuccess++;
}
double mean = nTrials * p;
double variance = mean * (1.0 - p);
double stddev = std::sqrt(variance);
printf("nTrials: %12d(%.3e)\n", nTrials, (double) nTrials);
printf("nSuccess: %12d(%.3e)\n", nSuccess, (double) nSuccess);
printf("Pct.: %12.5f\n", 100.0 * (double) nSuccess/nTrials);
printf("nStdDevs: %12.2f\n", (nSuccess - mean)/stddev);
printf("\n\n");
delete msg;
}
このコードは、私は考えることができように簡単です:
は、ここに私のコードです。ここで
simple Test
{
gates:
}
network Bernoulli
{
submodules:
node: Test;
}
omnetpp.iniファイルされる:私はコマンドを使用してコードを実行しています
[General]
network = Bernoulli
bernoulli-mean = 0.05
num-trials = 10000000
rng-class = "cMersenneTwister"
seed-0-mt = ${seed=0,1,2,3,4,5,6,7,8,9}
:./exe_file -u Cmdenv -r 3
(私は意図的に3回目を拾い出しています)。ここ.nedファイルです。上記のomnetpp.iniファイルでこれを実行すると、約532,006回の成功が得られます(ただし、この番号は各実行時に軽度に変更されます)。 10^7回の実行については、これは平均からの約46標準偏差(二項分布の平均および分散を用いて計算される)である。
さらに、私がrng-class="cMersenneTwister"
行をコメントアウトすると、その数は約531,793回の成功にジャンプし、毎回少しずつ(ただし根本的には変わらない)変更されます。
さらに、私がseed-0-mt=...
行をコメントアウトすると、突然シミュレーションが開始され、0.06スタンダード以内の値が生成されます。 dev。平均の!これは、OMNeT ++マニュアルがcMersenneTwisterアルゴリズムを使用すると、期間が非常に長いため、ランダムに種を選択できることを保証するという事実にもかかわらずです。
なぜこれが起こっていますか?私は、(1)cMersenneTwisterがデフォルトであるので、omnetpp.iniファイルに何も変更してはならないこと、(2)毎回同じシード(つまりシード3)を選択しているので、私は同じ結果を得ているはずです。でも僕はそうじゃない! cMersenneTwister乱数ジェネレータの
、生成されたシーケンスが重ならないように種を選択するため、RNGの非常に長い列に、簡単です:OMNeT ++マニュアル状態はので、これは、私を混乱させる。 RNGは、32ビットのシード値seed = runNumber * numRngs + rngNumberから初期化されます。
ありがとうございます!
などを使用できます。パラメータメカニズムについての有益なフィードバックをありがとう。私はうんざりしている。ありがとうございました! –