2013-11-09 2 views
-1

Я пытаюсь использовать функцию rand() в C++, но каждый раз возвращает одинаковое случайное число.такое же случайное число каждый раз в C++

Я поставил заявление srand(unsigned int(time(0))); в самой первой строке основной функции, но у меня все еще есть эта проблема.

У меня проблема с Google и нашел несколько ответов на этом сайте, но все они предлагают поместить оператор srand() в первую строку основной функции, которую я сделал.

Есть ли кто-нибудь, кто может помочь мне разобраться в этой проблеме? Благодарю.

EDITED @ 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] должны меняться с каждой итерацией, но они остаются неизменными с каждой итерацией.

+3

Разве что * только * место вы его положили? [SSCCE] (http://sscce.org) действительно поможет. – chris

+3

Если у вас есть поддержка C++ 11, не используйте 'rand()' на первом месте. – LihO

+0

@LihO, даже pre-C++ 11 имеет случайную библиотеку Boost. – chris

ответ

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); 
+0

да, почему он всегда равен нулю? У меня был тот же код в отдельной программе, и он дал мне случайное число от -0,5 до 0,5. – user2826735

+3

@ user2826735: Он равен нулю, потому что он использует целочисленную арифметику. Он не может дать вам случайное число «от -0,5 до 0,5». Так что нет, в вашей «отдельной программе» код был другим. В вашей «отдельной программе» вы использовали арифметику с плавающей запятой. – AnT

+0

@AndreyT: Извините, если я являюсь n00b. Исходным кодом было следующее: 'x [i] = x [i] + tau * (drand48() - 0.5);' , Как воспроизвести это без использования «drand()»? – user2826735

-1

Вы правы, что при использовании rand() нужно иметь вызов до srand() в какой-то момент в начале их программы, чтобы обеспечить выполнение различных псевдослучайных чисел. Тем не менее, правильное использование является:

srand(time(NULL)); 

time(0) возвращает 0, семена которых rand() таким же образом, при каждом запуске, в результате чего ваш вопрос. time(NULL) возвращает все, что хранится в памяти, где точки времени, и будет правильно засеять генератор.

+3

0 отлично работает как нулевой указатель. Не то, чтобы я защищаю то, когда есть «nullptr». – chris

+0

'NULL' оценивается в 0. Между ними нет никакой разницы. – deepmax

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 

Использование Apple LLVM 4.2 компилятора на i386 x86_64 архитектуры

Смежные вопросы