Генерация случайного двойника между диапазонами значений

У меня сейчас проблемы с генерацией случайных чисел в диапазоне от -32,768 до 32,768. Он продолжает давать мне те же значения, но с небольшим изменением в десятичном поле. например: 27.xxx.

Вот мой код, любая помощь будет оценена.

#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

Решение

Я должен отметить, что если вы используете компилятор 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;
}
7

Другие решения

Итак, я думаю, что это типичный случай, когда «использование времени (NULL) не является отличным способом заполнения случайных чисел для прогонов, которые начинаются близко друг к другу». Там не так много битов, которые меняются в time(NULL) от одного звонка до следующего, поэтому случайные числа довольно похожи. Это не новое явление — если вы Google «мои случайные числа не очень случайные», вы найдете много этого.

Есть несколько разных решений — в микросекундах или наносекундах было бы самым простым выбором — в Linux gettimeofday даст вам микросекундное время как часть структуры.

0

Это кажется очевидным, но некоторые примеры говорят об обратном … но я думал, что когда вы делите 1 int на другое, вы всегда получаете int? и вам нужно набрать cast каждый int, чтобы удвоить / плавать, прежде чем разделить их.

то есть: double r = (68,556 * (double) rand () / (double) RAND_MAX — 32,768);

Кроме того, если вы вызываете srand () каждый раз, когда вызываете rand (), вы сбрасываете начальное число, что приводит к тому, что аналогичные значения возвращаются каждый раз вместо «случайных».

0

Я добавил 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 для тебя.

Вот четыре прогона:

 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

Возможно, вы не ждете хотя бы секунды между пробежками?

0
По вопросам рекламы [email protected]