2012-11-27 25 views
2

使用隨機數生成器來做Pi的C++近似,輸出的結果與運行Ubuntu的AMD 64計算機上的預期完全一樣,但是在我的學校機器上,我實現的第二個算法已經失效,並會喜歡一些見解爲什麼。代碼如下:完全不同的輸出C++蒙特卡羅近似

#ifndef RANDOMNUMBER_H_ 
#define RANDOMNUMBER_H_ 

class RandomNumber { 
public: 
RandomNumber() { 
    x = time(NULL); 
    m = pow(2, 19); //some constant value 
    M = 65915 * 7915; //multiply of some simple numbers p and q 
    method = 1; 
} 
RandomNumber(int seed) { 
    x = ((seed > 0) ? seed : time(NULL)); 
    m = pow(2, 19); //some constant value 
    method = 1; //method number 
    M = 6543 * 7915; //multiply of some simple numbers p and q 
} 
void setSeed(long int seed) { 
    x = seed; //set start value 
} 

void chooseMethod(int method) { 
    this->method = ((method > 0 && method <= 2) ? method : 1); //choose one of  two method 
} 

long int linearCongruential() { //first generator, that uses linear congruential method 
    long int c = 0; // some constant 
    long int a = 69069; //some constant 
    x = (a * x + c) % m; //solution next value 
    return x; 
} 

long int BBS() { //algorithm Blum - Blum - Shub 
    x = (long int) (pow(x, 2)) % M; 
    return x; 
} 
double nextPoint() { //return random number in range (-1;1) 
    double point; 
    if (method == 1) //use first method 
     point = linearCongruential()/double(m); 
    else 
     point = BBS()/double(M); 
    return point; 
} 
private: 
long int x; //current value 
long int m; // some range for first method 
long int M; //some range for second method 
int method; //method number 
}; 

#endif /* RANDOMNUMBER_H_ */ 

和測試類:

#include <iostream> 
#include <stdlib.h> 
#include <math.h> 
#include <iomanip> 
#include "RandomNumber.h" 
using namespace std; 

int main(int argc, char* argv[]) { 
cout.setf(ios::fixed); 
cout.precision(6); 
RandomNumber random; 
random.setSeed(argc); 
srand((unsigned) time(NULL)); 
cout << "---------------------------------" << endl; 
cout << " Monte Carlo Pi Approximation" << endl; 
cout << "---------------------------------" << endl; 
cout << " Enter number of points: "; 
long int k1; 
cin >> k1; 
cout << "Select generator number: "; 
int method; 
cin >> method; 
random.chooseMethod(method); 
cout << "---------------------------------" << endl; 
long int k2 = 0; 
double sumX = 0; 
double sumY = 0; 
for (long int i = 0; i < k1; i++) { 
    double x = pow(-1, int(random.nextPoint() * 10) % 2) 
      * random.nextPoint(); 
    double y = pow(-1, int(random.nextPoint() * 10) % 2) 
      * random.nextPoint(); 
    sumX += x; 
    sumY += y; 
    if ((pow(x, 2) + pow(y, 2)) <= 1) 
     k2++; 

} 
double pi = 4 * (double(k2)/k1); 
cout << "M(X) = " << setw(10) << sumX/k1 << endl; //mathematical expectation of x 
cout << "M(Y) = " << setw(10) << sumY/k1 << endl; //mathematical expectation of y 
cout << endl << "Pi = " << pi << endl << endl; //approximate Pi 

return 0; 
} 

第二種方法始終返回4.000我的實驗室的機器上,但返回我的個人計算機上的一個相當接近。

+0

聽起來像整數長度或其他一些差異。或者你也許已經進入了整數溢出等「未定義」的領域。 –

+0

你正在使用什麼編譯器? – piokuc

+0

什麼操作系統和編譯器是你的實驗室機器? –

回答

4

首先,你使用的BBS生成器將始終返回1

由於您的程序沒有參數,推測其argc將是1。你通過argc作爲種子(爲什麼?),所以x的初始值是1

BBS()具有以下邏輯:

x = (long int) (pow(x, 2)) % M; 

顯然,1平方模M1,所以x永遠不會改變。

當您使用這樣的生成器運行模擬程序時,程序將始終輸出4

P.S.維基百科有以下說關於初始值x0Blum Blum Shub

種子x0應該是一個整數,它的互質數,以M(即pq不是的x0因素),而不是10

+1

也許他們用參數運行它?我敢打賭,他們打算通過'atoi(argv [1])'。 – Xymostech

+0

@Xymostech:這就是我認爲的(兩點)。 – NPE

+0

我的意思是如果傳遞參數,然後調用setSeed函數,否則使用系統時間。工作,但感謝您的幫助。 – kqualters