4

我需要生成X均匀分布在两个区间 [a,b] 之间的随机双数,其中ab也是双数。

这些X数字需要在类函数内部生成,比如myclass::doSomething(a,b). 问题是,每次函数被另一个类函数调用时,[a,b]传递给函数的间隔都会发生变化,比如.doSomething(a,b)doSomething(a,b)doThat()

我想要一个允许我的解决方案:
1. 拥有engine一个更大范围的,理想情况下,每次应用程序运行时它应该只播种一次。
2.X每次调用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);
                ...
         }
4

1 回答 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;
}
于 2012-04-08T07:31:29.197 回答