5

現在、-32.768 から 32.768 の間で乱数を生成するのに問題があります。それは私に同じ値を与え続けますが、小数フィールドに小さな変化があります。例: 27.xxx.

Heres私のコード、助けていただければ幸いです。

#include <iostream>
#include <ctime>
#include <cstdlib>

using namespace std;

int main()
{
    srand( time(NULL) );
    double r = (68.556*rand()/RAND_MAX - 32.768);
    cout << r << endl;
    return 0;
}
4

5 に答える 5

12

C++11 コンパイラを使用している場合は、次のようなものを使用できます。これは、実際には読みやすく、混乱しにくいものです。

#include <random>
#include <iostream>
#include <ctime>


int main()
{
    //Type of random number distribution
    std::uniform_real_distribution<double> dist(-32.768, 32.768);  //(min, max)

    //Mersenne Twister: Good quality random number generator
    std::mt19937 rng; 
    //Initialize with non-deterministic seeds
    rng.seed(std::random_device{}()); 

    // generate 10 random numbers.
    for (int i=0; i<10; i++)
    {
      std::cout << dist(rng) << std::endl;
    }
    return 0;
}

bames53 が指摘したように、c++11 をフルに活用すれば、上記のコードをさらに短くすることができます。

#include <random>
#include <iostream>
#include <ctime>
#include <algorithm>
#include <iterator>

int main()
{
    std::mt19937 rng; 
    std::uniform_real_distribution<double> dist(-32.768, 32.768);  //(min, max)
    rng.seed(std::random_device{}()); //non-deterministic seed
    std::generate_n( 
         std::ostream_iterator<double>(std::cout, "\n"),
         10, 
         [&]{ return dist(rng);} ); 
    return 0;
}
于 2013-02-01T02:38:30.520 に答える
-1

明らかに明らかなようですが、いくつかの例ではそうではありません...しかし、1つのintを別のintで割ると、常にintになると思いましたか? 分割する前に、各 int を double/float に型キャストする必要があります。

すなわち: double r = (68.556* (double)rand()/(double)RAND_MAX - 32.768);

また、rand() を呼び出すたびに srand() を呼び出すと、シードがリセットされ、「ランダム」な値ではなく、毎回同様の値が返されます。

于 2013-02-01T03:28:01.510 に答える
-1

forあなたのプログラムにループを追加しました:

#include <iostream>
#include <ctime>
#include <cstdlib>

using namespace std;

int main () {
    srand(time (NULL));

    for (int i = 0; i < 10; ++i) {
        double r = ((68.556 * rand () / RAND_MAX) - 32.768);

        cout << r << endl;
    }

    return 0;
}

出力例:

 31.6779 
-28.2096
 31.5672
 18.9916 
-1.57149 
-0.993889
-32.4737
 24.6982
 25.936 
 26.4152

私には大丈夫のようです。Ideoneにコードを追加しました。

以下に 4 つの実行を示します。

 Run 1:
    -29.0863
    -22.3973
     34.1034
    -1.41155
    -2.60232
    -30.5257
     31.9254
    -17.0673
     31.7522
     28.227

Run 2:
    -14.2872
    -0.185124
    -27.3674
     8.12921
     22.4611
    -0.414546
    -21.4944
    -11.0871
     4.87673
     5.4545

Run 3:
    -23.9083
    -6.04738
    -6.54314
     30.1767
    -16.2224
    -19.4619
     3.37444
     9.28014
     25.9318
    -22.8807

Run 4:
     25.1364
     16.3011
     0.596151
     5.3953
    -25.2851
     10.7301
     18.4541
    -18.8511
    -0.828694
     22.8335

おそらく、実行の合間に少なくとも 1 秒も待っていませんか?

于 2013-02-01T02:26:34.657 に答える
-1

したがって、これは「 time(NULL) を使用することは、近くで開始される実行に乱数をシードするための優れた方法ではない」という典型的なケースだと思います。ある呼び出しから次の呼び出しに変化するビットはそれほど多くないtime(NULL)ため、乱数はかなり似ています。これは新しい現象ではありません。「私の乱数はあまりランダムではありません」とググると、これがたくさん見つかります。

いくつかの異なる解決策があります-マイクロ秒またはナノ秒の時間を取得するのが最も簡単な選択gettimeofdayです-Linuxでは、構造体の一部としてマイクロ秒の時間を提供します。

于 2013-02-01T02:31:31.353 に答える