Vary range of uniform_int_distribution
所以我有一个随机对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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); } |
我可以(通过另一个函数或其他功能)改变分布上限的最佳方法是什么?
(也愿意就其他样式问题提出建议)
分发对象是轻量级的。需要随机数时,只需构造一个新的分布。我在游戏引擎中使用了这种方法,并且在进行基准测试后,可以媲美使用良好的旧版
此外,我还问过如何在GoingNative 2013直播中更改发行范围,标准委员会成员Stephen T. Lavavej建议仅创建新发行版,因为这不应该是性能问题。
这是我编写代码的方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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); } |
您可以简单地创建
1 2 | decltype(uniform_dist.param()) new_range (0, upper); uniform_dist.param(new_range); |
我为示例制作了
根据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. Moreover, for each of the member functions ofD that return values corresponding to parameters of the distribution,P shall have a corresponding member function with the identical name, type, and semantics.
其中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #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; } |