std :: uniform_real_distribution重新生成相同的随机数

时间:2017-12-05 07:00:29

标签: c++ c++11 random uniform-distribution

在运行下面的代码时,arr的前半部分等于后半部分。为什么?我甚至试过各种种子,例如std::chrono::system_clock::now().time_since_epoch().count()。感谢。

#include <algorithm>
#include <iostream>
#include <random>


template<typename DistributionType>
class Rng 
{
public:
        template<typename ...Args>
        Rng(Args&&... args) : dist(args...) { } 

        typename DistributionType::result_type operator()()
        {
                return dist(gen);
        }

private:
        std::default_random_engine gen;

        DistributionType dist;
};


class UniformRealRng : public Rng<std::uniform_real_distribution<double>>
{
public:
        UniformRealRng(const double a, const double b) : Rng(a, b) { } 
};

int main()
{
        constexpr int sz = 6;
        constexpr int k  = sz / 2;
        double arr[sz];

        UniformRealRng rng(0.0, 1.0);
        std::generate(arr, arr + k, rng);
        std::generate(arr + k, arr + sz, rng);

        for (int i = 0; i < sz; ++i)
        {
                std::cout << arr[i];
        }
        std::cout << "\n";
}

2 个答案:

答案 0 :(得分:3)

std::generate按值获取第三个参数,因此正在复制rng

为安全起见,可以删除复制:

Rng(Rng&)             = delete;   
Rng& operator=(Rng&)  = delete;

答案 1 :(得分:0)

你的答案事实上是正确的,但它并没有解决问题。 当错误地(?)尝试复制随机数生成器时,它只会产生编译错误。

事实证明,使用 std::generate(arr, arr + k, std::ref(rng)); std::generate(arr + k, arr + sz, std::ref(rng)); 库功能可以使代码在语义上更正。

operator()

通过这种方式,你基本上强迫通过引用传递参数。 幸运的是引用包装器会重载#include <algorithm> #include <iostream> #include <random> #include <functional> //ref template<typename DistributionType> class Rng { public: template<typename ...Args> Rng(Args&&... args) : dist(args...) { } // Rng(Rng&) = delete; // this is not needed for it to work // Rng& operator=(Rng&) = delete; // you MAY want to copy the generator typename DistributionType::result_type operator()() { return dist(gen); } private: std::default_random_engine gen; DistributionType dist; }; class UniformRealRng : public Rng<std::uniform_real_distribution<double>> { public: UniformRealRng(const double a, const double b) : Rng(a, b) { } }; int main() { constexpr int sz = 6; constexpr int k = sz / 2; double arr[sz]; UniformRealRng rng(0.0, 1.0); std::generate(arr, arr + k, std::ref(rng)); std::generate(arr + k, arr + sz, std::ref(rng)); for (int i = 0; i < sz; ++i) { std::cout << arr[i]; } std::cout << "\n"; } ,因此可以在没有任何其他代码的情况下用于生成器。

完整代码:

def __repr__(self):
     return "Circle(center=Point({0}, {1}), radius={2})"
                .format(self.center.x,self.center.y,self.radius)