Вопрос по c++, c++11, random – генерация случайных чисел двойников между двумя интервалами [a, b]

4

Мне нужно сгенерироватьX случайные двойные числа, равномерно распределенные между двумя интервалами [a, b], гдеa а такжеb также двойные числа.

ТеX числа должны быть сгенерированы внутри функции класса, скажемmyclass::doSomething(a,b), Дело в том, что интервалы[a,b] перешел кdoSomething(a,b) функция меняется каждый раз, когдаdoSomething(a,b) функция вызывается другой функцией класса, скажемdoThat().

Я хотел бы решение, которое позволяет мне:
1. Иметьengine с большей областью действия, в идеале, он должен быть посеян только один раз за запуск приложения.
2. TheX случайные двойные числа, генерируемые внутри каждого отдельного вызоваdoSomething() функция, должна быть равномерно распределена.

Мое решение, приведенное ниже, не позволяетengine и кажется, что сгенерированные числа не обязательно распределены равномерно.

//file: utilities.h
template <typename Generator>
double randomDoubleEngine(Generator& engine, double low_bound, double high_bound )
{
        if (low_bound > high_bound){
                std::swap(low_bound, high_bound);
        }

        return std::uniform_real_distribution<>( low_bound, high_bound )( engine );
}

//file: myclass.h
       void myclass::doThat(param1, param2){

            for(int i=0; i < myclass.iter; i++){
                ...
                ...
                doSomething(a,b);
                ...
            }

        }

        void myclass::doSomething(double a, double b)
        {
                std::random_device rd;
                static std::mt19937 engine(rd());
                .....
                double curThreshold = randomDoubleEngine(engine, a, b);
                ...
         }
Какой тест вы использовали для определения равномерности распределения, и каков был ваш размер выборки? Кстати, следует отметить, что разница между двумя сгенерированными числамиnot равномерно распределены, когда два числа. MSalters
Ваше решение работает? Если да, то какую проблему вам нужно решить? Другими словами, какой вопрос для SO-аудитории? Oliver Charlesworth
@ OliCharlesworth, мое решение не работает полностью. Я обновил свой оригинальный пост. Во-первых,engine не является глобальным, и, во-вторых, сгенерированные числа, кажется, не распределены равномерно. Tin

Ваш Ответ

1   ответ
2

вы хотите, чтобы двигатель был статическим членом myclass. Я не уверен, что это будет реально отличаться от того, что у вас есть, если только вам не нужно использовать двигатель другими способами. Я вставил возможное решение ниже.

Также обратите внимание, что gcc выглядит неправильно по сравнению со стандартом (см. Ссылки в комментариях к коду), поэтому, если вы используете его, это может объяснить, почему любой тест, который вы применяете к этим числам (для проверки равномерного распределения), дает сбой. Как я понимаю, gcc хочет, чтобы механизм возвращал числа в [0,1), в то время как стандарт говорит, что это должны быть одинаковые целые числа в некотором диапазоне.

Я боюсь, что смогу протестировать это только с помощью gcc 4.4, так как я использую более старую версию Ubuntu, а ideone, похоже, не разрешает std :: random_device.

#include <random>
#include <iostream>

/* In GCC 4.4, uniform_real_distribution is called uniform_real; renamed in 4.5
 *
 * However, GCC's description here
 *
 * http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-api-4.6/a00731.html
 *
 * doesn't match expectation here
 *
 * http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution
 *
 * which seems to match 26.5.8.2.2 of N3337
 *
 */
#if defined(__GNUC_MINOR__) && (__GNUC_MINOR__ <= 4)
#  define uniform_real_distribution uniform_real
#endif

template <typename Generator>
double randomDoubleEngine(Generator& engine, double low_bound, double high_bound)
{
  if (low_bound > high_bound){
    std::swap(low_bound, high_bound);
  }
  return std::uniform_real_distribution<double>(low_bound, high_bound)(engine);
}

class myclass
{
  double curThreshold;
  static std::mt19937 engine;
  void doSomething(double a, double b)
  {
    curThreshold= randomDoubleEngine(engine, a, b);
  }
public:
  myclass(): curThreshold(0) {}

  void doThat(){
    doSomething(0,10);
    std::cout << "threshold is " << curThreshold << std::endl;
  }
};

std::mt19937 myclass::engine=std::mt19937(std::random_device()());

int
main()
{
  myclass m;
  m.doThat();
  m.doThat();
  return 0;
}
похоже на то, что ищет OP.
Это не то же самое. Равномерное_реальное_распределение генерируется в диапазоне [a, b), а не [a, b]

Похожие вопросы