我在很多地方都使用了 C++ 随机数实用程序库。它可能不是很舒服(例如,没有用于任意分布的基类),但是 - 我已经学会了接受它。
现在我碰巧需要从枚举类型中统一采样值。我知道,SO 上已经有一个问题:
但是,那个:
假设所有枚举值都是连续的,即它不适用于
enum Color { Red = 1, Green = 2, Blue = 4 }
我们希望以 1/3 的概率对这三个值中的每一个进行采样。
- 不提供
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/