简体   繁体   English

更改uniform_int_distribution的范围

[英]Vary range of uniform_int_distribution

So i have a Random object: 所以我有一个Random对象:

typedef unsigned int uint32;

class Random {
public:
    Random() = default;
    Random(std::mt19937::result_type seed) : eng(seed) {}

private:
    uint32 DrawNumber();
    std::mt19937 eng{std::random_device{}()};
    std::uniform_int_distribution<uint32> uniform_dist{0, UINT32_MAX};
};

uint32 Random::DrawNumber()
{
    return uniform_dist(eng);
}

What's the best way I can vary (through another function or otherwise) the upper bound of of the distribution? 什么是我可以改变(通过另一个函数或其他方式)分布的上限的最佳方式?

(also willing to take advice on other style issues) (也愿意就其他风格问题提出建议)

Distribution objects are lightweight. 分发对象是轻量级的。 Simply construct a new distribution when you need a random number. 当您需要随机数时,只需构建一个新的分布。 I use this approach in a game engine, and, after benchmarking, it's comparable to using good old rand() . 我在游戏引擎中使用这种方法,并且在基准测试之后,它与使用好的旧rand()相当。

Also, I've asked how to vary the range of distribution on GoingNative 2013 live stream, and Stephen T. Lavavej, a member of the standard committee, suggested to simply create new distributions, as it shouldn't be a performance issue. 此外,我已经询问如何改变GoingNative 2013直播流的分发范围,标准委员会成员Stephen T. Lavavej建议简单地创建新的发行版,因为它不应该是性能问题。

Here's how I would write your code: 以下是我编写代码的方法:

using uint32 = unsigned int;

class Random {
public:
    Random() = default;
    Random(std::mt19937::result_type seed) : eng(seed) {}
    uint32 DrawNumber(uint32 min, uint32 max);

private:        
    std::mt19937 eng{std::random_device{}()};
};

uint32 Random::DrawNumber(uint32 min, uint32 max)
{
    return std::uniform_int_distribution<uint32>{min, max}(eng);
}

You can simply create a std::uniform_int_distribution<uint32>::param_type and modify the range using the param() method. 您只需创建一个std::uniform_int_distribution<uint32>::param_type并使用param()方法修改范围。 You can cut down the template noise with decltype : 您可以使用decltype减少模板噪音:

decltype(uniform_dist.param()) new_range (0, upper);
uniform_dist.param(new_range);

I'm making the DrawNumber function public for my example. 我正在为我的例子public DrawNumber函数。 You can provide an overload that takes an upper bound, and then pass a new uniform_int_distribution::param_type to uniform_int_distribution::operator() 您可以提供一个占用上限的重载,然后将一个新的uniform_int_distribution::param_typeuniform_int_distribution::operator()

The param_type can be constructed using the same arguments as the corresponding distribution. 可以使用与相应分布相同的参数来构造param_type

From N3337, §26.5.1.6/9 [rand.req.dist] 来自N3337, §26.5.1.6/ 9 [rand.req.dist]

For each of the constructors of D taking arguments corresponding to parameters of the distribution, P shall have a corresponding constructor subject to the same requirements and taking arguments identical in number, type, and default values. 对于D参数的每个构造函数,该参数对应于分布的参数, P应具有相应的构造函数,这些构造函数具有相同的要求并且在数量,类型和默认值方面具有相同的参数。 Moreover, for each of the member functions of D that return values corresponding to parameters of the distribution, P shall have a corresponding member function with the identical name, type, and semantics. 此外,对于返回对应于分布参数的值的D每个成员函数, P应具有相同的成员函数,其具有相同的名称,类型和语义。

where D is the type of a random number distribution function object and P is the type named by D 's associated param_type 其中D是随机数分布函数对象的类型, P是由D的相关param_type命名的类型

#include <iostream>
#include <random>

typedef unsigned int uint32;

class Random {
public:
    Random() = default;
    Random(std::mt19937::result_type seed) : eng(seed) {}

    uint32 DrawNumber();
    uint32 DrawNumber(uint32 ub);

private:
    std::mt19937 eng{std::random_device{}()};
    std::uniform_int_distribution<uint32> uniform_dist{0, UINT32_MAX};
};

uint32 Random::DrawNumber()
{
    return uniform_dist(eng);
}

uint32 Random::DrawNumber(uint32 ub)
{
    return uniform_dist(eng, decltype(uniform_dist)::param_type(0, ub));
}

int main()
{
  Random r;
  std::cout << r.DrawNumber() << std::endl;
  std::cout << r.DrawNumber(42) << std::endl;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM