2013-08-12 12 views
9

私はPythonコードをC++に変換しようとしています。コードが行うことは、モンテカルロシミュレーションを実行することです。私はPythonとC++の結果が非常に近いと思っていましたが、面白いことが起こったようです。ここでC++乱数生成とPythonの違い

は、私はPythonで何をすべきかです:ここでは

self.__length = 100 
self.__monte_carlo_array=np.random.uniform(0.0, 1.0, self.__length) 

は、私はC++で何をすべきかです:

int length = 100; 
std::random_device rd; 
std::mt19937_64 mt(rd()); 
std::uniform_real_distribution<double> distribution(0, 1); 

for(int i = 0; i < length; i++) 
{ 
    double d = distribution(mt); 
    monte_carlo_array[i] = d; 
} 

私はその後、乱数生成はPythonとC++の両方の時間を100x5以上走り、これらの乱数を使ってモンテカルロシミュレーションを行います。

モンテカルロシミュレーションでは、しきい値を0.5に設定したので、結果が均一に分散されているかどうかを簡単に確認できます。ここ

モンテカルロシミュレーションが何概念案である:

for(i = 0; i < length; i++) 
{ 
    if(monte_carlo_array[i] > threshold) // threshold = 0.5 
     monte_carlo_output[i] = 1; 
    else 
     monte_carlo_output[i] = 0; 
} 

モンテカルロの長さは、アレイ120であるので、私は、PythonとC++の両方で60の1 Sを見ることを期待します。私は1の平均数を計算し、C++とPythonの平均数は約60ですが、その傾向は高度に相関していますが、さらに、Pythonの平均数はで、常にC++よりも高いです。

distribution chart これは私が何か間違って行ったことが原因であるかどうか、あるいは単にC++とPythonのランダム生成メカニズムの違いが原因であるかどうか分かりますか?

[編集] RNG in Pythonもメルセンヌツイスターであることに注意してください19937.

+1

異なる乱数ジェネレータは、異なる乱数セットを提供します。私はあなたがそれを数回(数百回のように)走らせれば、それほど明白な違いはないと思います。 –

+2

これは実際に表示するコードで表示されますか?他の入力がなければなりません。さもなければ、コード間には何の相関もありません!私はバグが他の場所にあると思われます... –

+0

これらの結果の継ぎ目は操作されました... –

答えて

5

私はコードに基づいてこれを書いては投稿:C++での

import numpy as np 

length = 1000 
monte_carlo_array=np.random.uniform(0.0, 1.0, length) 
# print monte_carlo_array 
threshold = 0.5 
above = 0 

for i in range (0,length): 
    if monte_carlo_array[i] > threshold: 
     above+=1 
print above 

と、これを:

#include <random> 
#include <iostream> 

int main() 
{ 
    const int length = 1000; 
    std::random_device rd; 
    std::mt19937_64 mt(rd()); 
    std::uniform_real_distribution<double> distribution(0, 1); 
    double threshold = 0.5; 
    double monte_carlo_array[length]; 

    for(int i = 0; i < length; i++) 
    { 
     double d = distribution(mt); 
     monte_carlo_array[i] = d; 
    } 
    int above = 0; 

    for(int i = 0; i < length; i++) 
    { 
     if (monte_carlo_array[i] > threshold) 
     { 
      above++; 
     } 
    } 
    std::cout << above << std::endl; 
} 

それぞれ5回実行されます。

Python: 
480 
507 
485 
515 
506 
average: 
498.6 

C++: 
499 
484 
531 
509 
509 
average 
506.4 

だから何か私はC + +がPythonよりも高いことが分かっている。しかし、私は、「乱数は少数のサンプルで均一に分布していません」というより多くのケースだと思います。

私が代わりに100000に長さを変えて、まだ結果が50Kを中心に上下に異なります。要するに

Python: 

50235 
49752 
50215 
49717 
49974 

Average: 
49978.6 

C++: 

50085 
50018 
49993 
49779 
49966 

Average: 
49968.2 

を、私はそれがC++とPythonでの乱数の実装との間の大きな違いはないと思いますそれは "それがおよそ0.5である方法"に来るとき。しかし、私は統計をあまり研究していませんでした(それは何年も前でした)。

+0

こんにちは、マット。ご回答どうもありがとうございました。大きなサンプルでは大きな違いはないと私は完全に同意します。しかし、実際には、私は1000の長さの配列を生成するのではなく、120を生成します。したがって、いくつかの違いを見ることは合理的です。そして実際には、モンテカルロの出力にある範囲の乱数が乗算され、その範囲はPythonとC++の両方で同じです。 int amount = 0; for(i = 0; i <120; i ++)amount + = monte_carlo_output * random_number;しかし、Pythonは常に値の面でC++を打ち破っています。 – ChangeMyName

+0

おそらくあなたは5回しか走らなかったからでしょう。私は上記のコードを書き直して120のランを実行しましたが、バリエーションは大きくなりましたが、結果はまだ私が約0.5インチ上の60インチになりますが、それは変わります。私はPythonで10000回実行しましたが、それは0.5より大きい数字の40から79までの範囲です。 C++では、1つの例では42から80になりました。言い換えれば、C++とPythonで同じことをしている場合、同じ結果が得られるはずです(同じ乱数ジェネレータもあります)。もちろん、そうでないWindowsマシンで実行している場合は完全に可能です) –

0

乱数でわからないときは、Random ORGのようなサービスを使用して膨大な乱数を生成するだけです。その後、両方の実装(C++とPython)で配列としてこの数値を指定します。この方法で両方のプログラムが同じ乱数セットを使用していることを確認し、コードの残りの部分がOKであることを確認できます。