2017-11-08 8 views
1

これは宿題に関する質問ですが、はるかに大きなプロジェクトの一部です。制約の1つは、何らかの理由でSTLを使用できないということです。cstdlibを使用せずに乱数を生成する?

私は自分のrand()関数をctimeと増分修飾子を使ってロールアップしようとしました。これは一貫したシードを持たなくても、同じ修飾子に1秒に1回以上給餌されない限り、関数は半乱数を出力すべきであると考えました。

//notcstdlib.cpp 
//<ctime> <cmath> 
int rand(int mod) 
{ 
    time_t seed; 
    return std::abs(seed * mod); 
} 

このサンプルコード

//main.cpp 
#include "notcstdlib.h" 
#include <iostream> 

int main(int argc, char** argv) 
{ 
    int f; 
    for(int i = 1; i <= 10; i++) 
    { 
     f = rand(i); 
     std::cout << "random num= " << f << "\n"; 
     std::cout << "rand % 10 = " << f%10 << "\n"; 
    } 
    return 0; 
} 

常にすべての他の数の0と8との間の第一の値とのみ偶数として7を返します。

//Output 1    //Output 2    //Output 3 
random num= 134514987 | random num= 134514987 | random num= 134514987 
rand % 10 = 7   | rand % 10 = 7   | rand % 10 = 7 
random num= 13261304 | random num= 24238584 | random num= 27941368 
rand % 10 = 4   | rand % 10 = 4   | rand % 10 = 8 
random num= 19891956 | random num= 36357876 | random num= 41912052 
rand % 10 = 6   | rand % 10 = 6   | rand % 10 = 2 
random num= 26522608 | random num= 48477168 | random num= 55882736 
rand % 10 = 8   | rand % 10 = 8   | rand % 10 = 6 
random num= 33153260 | random num= 60596460 | random num= 69853420 
rand % 10 = 0   | rand % 10 = 0   | rand % 10 = 0 
random num= 39783912 | random num= 72715752 | random num= 83824104 
rand % 10 = 2   | rand % 10 = 2   | rand % 10 = 4 
random num= 46414564 | random num= 84835044 | random num= 97794788 
rand % 10 = 4   | rand % 10 = 4   | rand % 10 = 8 
random num= 53045216 | random num= 96954336 | random num= 111765472 
rand % 10 = 6   | rand % 10 = 6   | rand % 10 = 2 
random num= 59675868 | random num= 109073628 | random num= 125736156 
rand % 10 = 8   | rand % 10 = 8   | rand % 10 = 6 
random num= 66306520 | random num= 121192920 | random num= 139706840 
rand % 10 = 0   | rand % 10 = 0   | rand % 10 = 0 

明らかに、私はrand()のいくつかの重要な面を見逃しており、実装していません。この問題に取り組むより良い方法はありますか?

+0

擬似乱数ジェネレータの作成に関する課題はありますか? –

+0

こちらをご覧ください:https://en.wikipedia.org/wiki/Linear-feedback_shift_register – DimChtz

+0

https://stackoverflow.com/questions/3062746/special-simple-random-number-generator –

答えて

2

てみません。または、より良い疑似乱数ジェネレータであるC++のMercene Twisterエンジンを使用できるように、<random>を使用できるかどうかを尋ねてください。あなたは、あなたのようmy_srand()my_rand()MY_RAND_MAXを使用することができます

#define MY_RAND_MAX = 2147483647 
static unsigned long my_rand_state = 1; 

void my_srand(unsigned long seed) 
{ 
    my_rand_state = seed; 
} 

long my_rand() 
{ 
    my_rand_state = (my_rand_state * 1103515245 + 12345) % 2147483648; 
    return my_rand_state; 
} 

std::srand()std::rand()と:

あなたが本当に自分自身をロールバックする必要がある場合は、std::rand()ための最も簡単な交換がLCG(線形合同法)でありますそれぞれRAND_MAX

// Seed it with the current time. 
my_srand(std::time(nullptr)); 

// Print 1000 random numbers between 0 and MY_RAND_MAX. 
for (int i = 0; i < 1000; ++i) { 
    std::cout << my_rand() << ' '; 
} 
std::cout << '\n'; 

これは、(彼らは悪い分布を有する。)、低品質の乱数を生成し、注意そのstd::rand()にも悪い分布があります。高品質の乱数(良い分布を意味する)を使用したい場合は、std::mt19937エンジン(非常に良い分布と巨大な期間を持つMercene Twisterアルゴリズム)を使用してC++ <random>アルゴリズムを使用する必要があります。

一般的には、rand()を避けてください。そのコードにまだrand()を使用している人は、必ずこのコードを参照してください。Stephan T. Lavavej's 30min talk "rand() Considered Harmful"を参照してください。

+0

私は教授からより詳細な回答を得ようとします。その間、私は大量の割り当てで自分自身を占有すると思います。品質に関しては、この実装では数値の分布はあまり重要ではありません。私はこれと一緒に遊んで、私はそれで何ができるかを見ていきます。ありがとう。 – anthony

+0

@anthony私はあなたがフレーズ "ゴミを出して、ゴミを出す"という言葉を聞いたことを確信しています:-)意味は、乱数が本当に悪い場合は、シミュレーションの結果から悪い結論を引き出すことができます。もちろん、これの唯一のポイントは、結果から結論を引き出すのではなく、シミュレーションを実行する方法を学習している場合です。 –

+0

私はこの解決策が好きです。それはかなりシンプルで、シードをプリセットして前のセットの番号を再実行することができます。私はあなたにもう1つの説明を迷惑をかけることができたら、私は別のLCG番号を入れようとしましたが、私は奇妙な結果を得ました。 私は(my_rand_state * 134775813 + 1)%4294967296を試しましたが、my_rand_stateは符号なしlongであっても、負の数が出ることがあります。私は明示的にunsigned longを返すようにmy_rand()を変更しましたが、何も変更されませんでした。 – anthony

2

あなたは、あなたの子孫を初期化していない、あなたが本当にあなた自身の擬似乱数生成器を実装する必要があるかどうかをあなたはおそらくstd::rand()も除外されているかどうか、あなたの先生に尋ねるとすべきである

//notcstdlib.cpp 
<ctime> 
int rand(int mod) 
{ 
    static time_t seed = time(NULL); 
    return std::abs(seed * mod); 
} 
+1

それはうんざりして簡単な省略です。ありがとう。 – anthony

関連する問題