c++ - 表示任意枚举类型范围内的均匀分布

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

我在很多地方都使用了 C++ 随机数实用程序库。它可能不是很舒服(例如,没有用于任意分布的基类),但是 - 我已经学会了接受它。

现在我碰巧需要从枚举类型中统一采样值。我知道,SO 上已经有一个问题:

generating random enums

但是,那个:

  1. 假设所有枚举值都是连续的,即它不适用于

    enum Color { Red = 1, Green = 2, Blue = 4 }
    

    我们希望以 1/3 的概率对这三个值中的每一个进行采样。

  2. 不提供 std::uniform_distribution<> 的功能,即它不适用于您传递给它的随机引擎等等。

显然我不能使用 std::uniform_int_distribution<Color> ,如果仅出于上述原因 1。我应该怎么做?

注意事项:

  • 代码必须是通用的,即枚举类型将是模板参数。
  • 由于我很可能只需要对粗略的枚举进行一些检测,您可以假设我有;只需明确说明您的假设即可。
  • 具体来说,如果有帮助的话,假设我使用 Better Enums ,让我完全装扮成所有的花里胡哨。
  • 如果有某种不涉及任何此类仪器的惯用方法来执行此操作,那将是一个很好的答案,但我对此表示怀疑。
  • 仅 C++11/14 的解决方案是可以接受的。
  • 具有相同值的多个枚举标识符不会获得两倍的频率,它们只是彼此的别名。如果您有一个假设这些不存在的简单解决方案,那也将是相关的,尽管不是最优的。

最佳答案

使用Better Enums ,这个问题可以这样解决:

template<typename T>
typename T get_uniform_value(std::default_random_engine& eng)
{
    std::uniform_int_distribution<int> dist(0, T::_size() - 1);
    return T::_values()[dist(eng)];
}

使用示例:

BETTER_ENUM(Channel, int, Red, Green = 2, Blue) // Enum to generate random values of
...
std::default_random_engine rng(std::random_device{}());
Channel r = get_uniform_value<Channel>(rng); // Uniformly distributed between 0, 2 and 3

关于c++ - 表示任意枚举类型范围内的均匀分布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38956386/

相关文章:

c++ - Qt 录像机

c++ - 将代码从 gcc 移植到 clang

C++ Builder/Winapi 不同的加载/进度条类型

c++ - 我应该从使用 boost::shared_ptr 切换到 std::shared_ptr 吗?

c++ - 我可以使用 `int arr[N]` 或 `typedef` 更改 `using` 的含义吗?

尽管有随机组件,但当我多次调用一个函数时,Python 给出相同的结果

PHP 的 array_rand() 不是真正随机的?

c++ - 在 C++/C 中生成多个不同的随机数?

c++ - 两个数相减时的小数

c# - Swig C++ 到 C# : How to wrap classes from C++ to make methods from template class available in derived class in C#?