随机分布,如discrete_distribution<float>

Random distribution like discrete_distribution<float>

本文关键字:lt float gt distribution 分布 discrete 随机      更新时间:2023-10-16

discrete_distribution只能与整数类型一起使用,浮点数有类似的东西吗?

我想写类似的东西

distribution<float> myDistribution = {0.1, 0.2, 0.5, 0.2};
int index = myDistribution(generator);

重要的是,随机数生成为 O(log(N))。

std::discrete_distribution的签名如下:

template< class IntType = int >
class discrete_distribution;

如前所述:

IntType- 生成器生成的结果类型。如果不是shortintlonglong longunsigned shortunsigned intunsigned longunsigned long long之一,则效果是不确定的。

因此,结果类型应为整数。但权重不是这样,他们可以是浮点数。实际上,此类的一个构造函数的签名是:

discrete_distribution( std::initializer_list<double> weights );

因此,我们可以使用浮点数作为权重:

#include <iostream>
#include <random>
#include <map>
#include <vector>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::discrete_distribution<int> myDistribution = {0.1, 0.2, 0.5, 0.2};
std::map<int, int> m;
for(int n=0; n<10000; ++n) {
++m[myDistribution(gen)];
}
for(auto p : m) {
std::cout << p.first << " generated " << p.second << " timesn";
}
return 0;
}

结果如下:

0 generated 1023 times
1 generated 1969 times
2 generated 5005 times
3 generated 2003 times

我们可以看到std::initializer_list中指示的权重得到了尊重。

我宁愿找到使它们全部为整数的公共倍数并在discrete_distribution中使用它。

或者,如果您确实需要,您可以使用piecewise_constant_distribution。权重将是您的浮点数,间隔只是单位间隔。

std::vector<double> i{0.0,  1.0, 2.0, 3.0, 4.0};
std::vector<double> w{0.1, 0.2, 0.5, 0.2};
std::piecewise_constant_distribution<> d(i.begin(), i.end(), w.begin());

(然后将结果投射到地板的 int)

但是,我认为该标准不能保证任一生成器的复杂性。