Генерация случайных чисел: один и тот же код C ++, два разных поведения

Мой коллега и я вместе работаем над проектом в Монте-Карло на C ++. Она использует Visual Studio, я использую Xcode, мы делимся кодом через git.
Мы рассчитываем американские цены опционов благодаря данному методу, который требует генерации случайных чисел. Мы поняли, что получаем неправильные результаты для определенного параметра K (чем выше параметр, тем больше неправильный ответ), и мой коллега обнаружил, что изменение случайного источника для Mersenne Twister на rand () (хотя плохой генератор) делает результаты хорошими для всего диапазона К.

Но когда я изменил исходный код моей версии кода, он ничего не сделал.

Еще более загадочно для меня, я создал новый проект Xcode, скопировал в него весь ее источник, и он все еще дает мне неправильные результаты (пока она получает хорошие). Так что это не может происходить из самого кода.
Я очистил проект, перезапустил Xcode, даже перезапустил мой компьютер (…), но ничего не изменилось: наши проекты ведут себя согласованно, но по-разному, с тем же кодом.
(РЕДАКТИРОВАТЬ: по-разному, но последовательно, я не имею в виду, что мы не имеем одинаковую последовательность чисел. Я имею в виду, что ее оценка Монте-Карло сходится к 4. и мой к 3.)

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

Вот случайный код генерации:

double loiuniforme() //uniform law
{
return (double)((float)rand() / (float)RAND_MAX);
}vector<double> loinormale() //normal law
{
vector<double> loinormales(2, 0.);

double u1 = loiuniforme();
double v1 = loiuniforme();

loinormales[0] = sqrt(-2 * log(u1))*cos(2 * M_PI*v1);
loinormales[1] = sqrt(-2 * log(u1))*sin(2 * M_PI*v1);

return(loinormales);

}

РЕДАКТИРОВАТЬ: MT RNG, используемый ранее был:

double loiuniforme()
{
mt19937::result_type seed = clock();
auto real_rand = std::bind(std::uniform_real_distribution<double>(0,1), mt19937(seed));
return real_rand();
}

-1

Решение

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

2

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

Вы должны создать только один генератор и использовать его для каждого числа.

mt19937::result_type seed = clock();

а также

mt19937(seed)

создайте новый генератор с новым начальным числом каждый раз, когда вы вызываете функцию.
Это приводит к тому, что случайность искажается.

Вы можете использовать статические переменные в функции, так как они инициализируются при первом вызове:

double loiuniforme()
{
static std::mt19937 generator(clock());
static std::uniform_real_distribution<double> distribution(0, 1);
return distribution(generator);
}

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

2

Вам нужно посеять rand функция с одинаковым номером на обоих компьютерах. И даже тогда я не уверен, что базовый код на компьютерах и операционных системах будет возвращать одно и то же значение.

Что еще более важно, если вы хотите идентичные результаты, не используйте случайную функцию.

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