我正在使用OMNeT ++ 5.1.1模擬器。我已經看到了bernoulli()函數的一些奇怪行爲,所以我構建了一個MWE以查看發生了什麼。OMNeT ++ RNG不會收斂到意味着
MWE通過創建具有單個節點的網絡並在t = 0時設置一個計時器(自我消息)來工作。當計時器關閉時,仿真運行一些n次伯努利試驗,成功概率爲p。值n和p是通過使用Register_PerRunConfigOption()宏定義的每次運行配置選項指定的。
這裏是我的代碼:
#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;
}
這段代碼是我能想到的那樣簡單(我是新來的OMNeT ++)。這裏是.ned文件:
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
(我故意挑了第三次運行)。當我使用上面的omnetpp.ini文件進行此操作時,我獲得了大約532,006次成功(儘管此數字在每次運行時都略有變化)。對於10^7次運行,這與平均值大約有46個標準偏差(使用二項分佈的均值和方差計算)。
此外,如果我註釋掉rng-class="cMersenneTwister"
這一行,則跳轉到531,793次成功,每次都會稍微改變(但不是根本)。此外,如果我註釋掉seed-0-mt=...
一行,那麼突然模擬開始在0.06標準內產生值。開發。的意思!儘管OMNeT ++手冊確保使用cMersenneTwister算法意味着您可以隨機選擇種子,因爲該期間非常大。
這是怎麼發生的?我期望(1)因爲cMersenneTwister是默認的,所以它包含在omnetpp.ini文件中不應該改變任何東西,並且(2)因爲我每次選擇相同的種子(即種子3),所以我應該得到相同的結果。但我不是!這混淆我,因爲的OMNeT ++手冊指出:
對於cMersenneTwister隨機數發生器,選擇種子以使產生的序列不重疊是容易的,由於RNG的極長的序列。 RNG從32位種子值seed = runNumber * numRngs + rngNumber進行初始化。
謝謝!
當然。感謝您提供有關參數機制的有用反饋。我一直sl。。謝謝! –