-1

C++ で rand() 関数を使用しようとしていますが、毎回同じ乱数が返されます。

メイン関数の最初の行にステートメントを入れましたがsrand(unsigned int(time(0)));、まだこの問題が発生しています。

srand()私は問題をグーグルで検索し、このサイトでいくつかの回答を見つけましたが、それらはすべて、私が行ったメイン関数の最初の行にステートメントを配置することを提案しています。

この問題を理解するのを手伝ってくれる人はいますか? ありがとう。

編集 @5:10pm:

プログラムは複雑なものです。トラブルシューティングを試みましたが、ここにいくつかの追加情報があります。

主な機能:

int main(int argc, char **argv) {
    srand(time(0));
    std::auto_ptr<simulation> sim_ptr;
    const double delta_t = 0.000002;
    if (argc != 2) {
        std::cerr << "Error: invalid number of arguments specified" << std::endl;
        exit(EXIT_FAILURE);
    } else if (strcmp(argv[1], "--random") == 0) {
        sim_ptr = std::auto_ptr<simulation>(create_random_simulation(delta_t));
    } else if (strcmp(argv[1], "--naive") == 0) {
        const double alpha = 1000;
        sim_ptr = std::auto_ptr<simulation>(create_naive_simulation(delta_t, alpha));
    } else if (strcmp(argv[1], "--tree") == 0) {
        const double alpha = 1000;
        sim_ptr = std::auto_ptr<simulation>(create_tree_simulation(delta_t, alpha));
    }

    const size_t time_steps = 200;
    const size_t particles_count = 2048;
    const size_t particles_shown = 2048;
    const size_t image_width = 512;
    const size_t image_height = 512;

    std::valarray<double> m  = random_valarray(particles_count);
    m = m * m * m;
    std::valarray<double> x  = random_valarray(particles_count);
    std::valarray<double> y  = random_valarray(particles_count);
    std::valarray<double> vx, vy;
    vx.resize(particles_count);
    vy.resize(particles_count);
    std::cout << "Simulation" << std::endl;
    for (size_t time_step = 1; time_step <= time_steps; time_step++) {
        std::cout << "\tFrame " << time_step << " / " << time_steps << std::endl;
        sim_ptr->step(x, y, vx, vy, m);
        std::vector<uint8_t> image;
        image.resize(image_width * image_height);
        for (size_t particle = 0; particle < particles_shown; particle++) {
            const uint8_t color = ((particle * 23297) % 255) + 1;
            draw_particle(x[particle], y[particle], m[particle], &image[0], image_width, image_height, color);
        }
        const std::string image_path = get_image_path(time_step);
        write_bmp_image(image_path, &image[0], image_width, image_height);
    }
    return 0;
}

毎回ゼロになる rand() を呼び出すクラス関数:

void random_simulation::step(std::valarray<double>& x, std::valarray<double>& y,
    std::valarray<double>& vx, std::valarray<double>& vy,
    std::valarray<double>& m) const
{
    const size_t particles_count = x.size();
    assert(particles_count == y.size());
    assert(particles_count == vx.size());
    assert(particles_count == vy.size());

    const double tau = 2.0 * sqrt(2.0 * this->delta_t);
    for (size_t i = 0; i < particles_count; i++) {
        x[i] = x[i] + tau * (((rand() % 2001 - 1000)/2000));
        y[i] = y[i] + tau * (((rand() % 2001 - 1000)/2000));
        if (i == 1){
            std::cout << x[i] << " ";
            std::cout << y[i] << " ";
        }

    }
}

simulation* create_random_simulation(double delta_t) {
    return new random_simulation(delta_t);
}

ループによると、x[i]y[i]反復で変更する必要がありますが、各反復で同じままです。

4

3 に答える 3

3
(rand() % 2001 - 1000)/2000

いつも0です。2000.0あなたはそれの間に値を持つことでそれを割ることができます[0.0, 1.0)


たとえば、C++11 ランダム ユーティリティを使用できますstd::uniform_real_distribution

std::default_random_engine generator(time(0));
std::uniform_real_distribution<double> distribution(0.0, 1.0);

double x = distribution(generator);
于 2013-11-09T21:57:56.900 に答える
0

XCodeで以下を実行すると、毎回異なる乱数が生成されました(C++静的キャストを使用)

#include <iostream>

int main(int argc, const char * argv[])
{
    srand(static_cast<unsigned int>(time(0)));

    int r = rand();

    std::cout << "Random number: " << r << std::endl;
    return 0;
}

// Random numbers:
// 2064544746
// 2064897693
// 2065132991
// 2065250640

i386 x86_64 アーキテクチャで Apple LLVM 4.2 コンパイラを使用する

于 2013-11-09T22:05:17.487 に答える
-1

rand()使用する場合、プログラムの最初のある時点でを呼び出して、srand()実行ごとに異なる疑似乱数を確保する必要があることは正しいです。ただし、正しい使用法は次のとおりです。

srand(time(NULL)); 

time(0)rand()0 を返します。これは、実行ごとに同じ方法でシードされ、問題を引き起こします。time(NULL)メモリに保存されているものは何でも返され、時間ポイントが発生し、ジェネレーターに適切にシードされます。

于 2013-11-09T22:02:20.057 に答える