【问题标题】:Generating pseudo-random integers from a changing interval efficiently从变化的区间有效地生成伪随机整数
【发布时间】:2013-03-31 19:15:05
【问题描述】:

我编写了以下类,用于从给定间隔 [lower, upper] 生成随机整数。

 class RandomInteger {

protected:

    std::random_device randomDevice;
    std::default_random_engine randomEngine;
    std::uniform_int_distribution<> distribution;

public:

    RandomInteger(int64_t lower, int64_t upper);

    virtual ~RandomInteger();

    virtual int64_t generate();
};


RandomInteger::RandomInteger(int64_t lower, int64_t upper) : randomEngine(this->randomDevice()), distribution(lower, upper) {
}

RandomInteger::~RandomInteger() {
    // TODO Auto-generated destructor stub
}

int64_t RandomInteger::generate() {
    int64_t i = this->distribution(this->randomEngine);
    return i;
}

如果间隔保持不变并且多次调用generate,这没关系。但是,现在我的用例是从一个总是变化的间隔生成整数(上限每次都增加)。

首先,这需要快速。这与密码学无关,因此非常伪随机数是可以的(可能不需要std::random_device)。如果可能的话,我也想避免使用 C 风格并使用现代 C++11 风格。

您能提出有效的方法吗?

【问题讨论】:

  • 更改分布是否不够高效? uniform_int_distribution 是一个非常薄的包装器,不应该有任何显着的开销。还有,为什么你们班的函数是virtual
  • OOP 被高估了,C++ 支持它,但在大多数情况下,它具有解决问题的优越机制(面向算法的编程)——参见大多数标准库。虚函数确实有很大的成本,不要被误导。它们的实际开销相对较小,但它们对内联构成了障碍,这可能对性能产生更大的影响。关于你的第二个问题:是的,完全正确。其成本实际上应该与分配两个整数相同(因为在内部发生了这种情况),仅此而已。
  • @cls FWIW 您还会看到许多使用其他所谓 OOP 语言的知名人士告诉您“为继承而设计或禁止它”。对我来说,这听起来像是同样的想法。您无法通过简单地在其中添加关键字来获得可重用性。实际的可重用性和可扩展性来自设计,而不是神奇地来自语言特性(尽管缺乏正确的语言特性可能会阻碍设计)。
  • @cls:这个建议适用于任何语言。 “OOP 语言”毫无意义。虚拟功能不是一个神奇的可扩展性按钮——你需要更多。简单的事实是,你不需要virtual,所以不要使用它。
  • @cls 我会回复的。但是,我不能说它比 @R.MF 已经做得更好了。同时,让我赞扬您实际上 提出问题 而不仅仅是 :shrug: 并认为人们是错误的。这就是让(将)获得它的人与没有获得它的人区分开来的原因。

标签: c++ random c++11 integer


【解决方案1】:

使用接受const param_type &amp;uniform_int_distribution::operator() 的重载:

int64_t RandomInteger::generate(int64_t lower, int64_t upper) {
    int64_t i = this->distribution(this->randomEngine,
      std::uniform_int_distribution<int64_t>{lower, upper}.param());
    return i;
}

(注意你应该初始化distribution,因为你对设置它的param不感兴趣。另外,distribution应该用int64_t模板化,而不是int。)

如果uniform_int_distribution 保留任何状态,那么这将有效地使用它。

事实上,uniform_int_distribution 的大多数实现都不保留任何状态;参见例如libstdc++ random.tcc: http://gcc.gnu.org/onlinedocs/gcc-4.6.0/libstdc++/api/a01001_source.html#l00832

【讨论】:

    猜你喜欢
    • 2018-01-10
    • 1970-01-01
    • 2012-01-06
    • 2013-10-10
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    相关资源
    最近更新 更多