gpt4 book ai didi

c++ - 离散事件模拟在 windows 和 linux 中生成不同的结果

转载 作者:太空狗 更新时间:2023-10-29 23:04:20 26 4
gpt4 key购买 nike

我正在进行 m/m/2/2 离散事件模拟。结果与理论值相同,这意味着程序是正确的(在 Ubuntu 中,g++)。但是,当我在windows(visual studio)中再次测试代码时,结果只有在试验次数小于10000时才是正确的。我调试了很长时间,最后发现我必须使用 (double) rand ()/( RAND_MAX + 1 ) 而不仅仅是 (double) rand()/RAND_MAX

这是为什么呢?这两个编译器生成随机数的方式不同吗?

#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <cmath>
#include "iomanip"
#include <queue>
using namespace std;

#define TRIAL_NUM 10000000

//structure that represent a customer
struct cust
{
int cust_id;
double arrival_time;
double depart_time;
};

//uniform random generator
double uniRand()
{
return (double) rand() / RAND_MAX;
}

//exponential random generator
double expRand(double lam)
{
double u,x;
u=uniRand();
x=(-1/lam)*log(1-u);
return(x);
}

int main()
{
//seed the random generator
srand (time(NULL));
//queue that hold all customers
std::queue<cust*> customers;
double lam = 0, mu = 0;
bool showStatus = false;
cout<<"M/M/1/1 Discrete Event Simulation with "<<TRIAL_NUM<<" customers\n"<<" Please spacify the value of lambda:";
cin>>lam;
while(lam<= 0)
{
cout<<"lambda value must be a positive number, try again:";
cin>>lam;
}
cout<<"Please specify the value of mu:";
cin>>mu;
while(mu<= 0)
{
cout<<"lambda value must be a positive number, try again:";
cin>>mu;
}
cout<<"Show status for each customer? (y/n)";
char show;
cin>>show;
while( tolower(show) != 'y' && tolower(show) != 'n')
{
cout<<"Invalid input, try again:";
cin>>show;
}
if ( tolower(show) =='y' )
{
showStatus = true;
}

//Generating all arrival time, service time for all customers
double temp_time = 1;
cust* temp;
for (int i = 1; i <= TRIAL_NUM; ++i)
{
temp= new cust;
temp -> arrival_time = temp_time + expRand(lam);
temp_time = temp->arrival_time;
temp->depart_time = temp->arrival_time + expRand(mu);
temp->cust_id = i;
customers.push(temp);
}

//Blocking customer count
double block = 0;
bool blockFlag = false;
temp = customers.front();
double server1 = 0, server2 = 0;

//perform simulation
while( !customers.empty())
{
if ( server1 < temp->arrival_time)
{
server1 = temp->depart_time;
}
else if ( server2 < temp->arrival_time)
{
server2 = temp->depart_time;
}
else
{
block++;
blockFlag = true;
}
if (showStatus)
{
cout<<"Customer "<<temp->cust_id<<"\tarrived at:"<<temp->arrival_time<<"\tservice time:"<<temp->depart_time<<"\tstatus:";
if (blockFlag)
{
cout<<"Blocked"<<endl;
}
else{
cout<<"Served"<<endl;
}
}
customers.pop();
if (!customers.empty())
{
temp = customers.front();
}
blockFlag = false;
}
cout<<"Blocking probability is: "<<block/TRIAL_NUM<<endl;
return 0;
}

最佳答案

(double) rand()/(RAND_MAX + 1) 是一个危险的表达式。

如果,正如经常发生的那样,RAND_MAX 等于 INT_MAX 那么 RAND_MAX + 1 是一个溢出和未定义的行为(它通常导致在 INT_MIN 中,但任何规范都不能保证这一点)。

在 Visual C++ 中,RAND_MAX 是 32767,您没有这个问题(但 32767 是一个很小的值,它“开始循环”很快)。

无论如何,我认为真正的问题在于:

u = uniRand();
x = (-1 / lam) * log(1 - u);

uniRand() 定义为 (double) rand()/RAND_MAX 时,它会产生以下范围内的值:

0.0 <= uniRand() <= 1.0

当该值等于 1.0 时,您有一个 pole error在您的 log(1-u) 中。由于 RAND_MAX 的值较小,这种情况在 Visual C++ 中会更频繁地发生。

关于c++ - 离散事件模拟在 windows 和 linux 中生成不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23039515/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com