生成具有给定分布的字符
Generate characters with given distribution
我有两个关于生成具有给定分布的 numbers/single 个字符的问题。
- 如何在 C++ 中实现拉普拉斯分布?我知道它在 boost 库中可用,但假设我不能使用它。另外,我没有在c+11的标准库中看到它。
如果我必须生成具有正态分布的字符文本,将生成的双数转换为 int 然后再转换为 char 类型是否可行?
std::default_random_engine generator;
std::normal_distribution<double> distribution(112.0,5.0);
int number = (int)distribution(generator);
// a-z characters
if(number >= 97 && number <= 122) return (char)number;
else generate once again;
希望得到您的帮助。
1) 拉普拉斯分布具有显式密度(参见 here),这是一个从 $\mathbf{R}$ 到 $[0,1]$ 的函数,带有参数,因此您可以实现在 c++
作为 class 的成员函数,其成员变量例如包括分布的参数。像 :
class LaplaceRandomVariable
{
double _b;
double _mu;
public:
LaplaceRandomVariable(double b, double mu)
{
_b = b;
_mu = mu;
}
double Distribution(double x) const
{
return (0.5 / _b) * exp(-abs(x - _mu) / _b); //you'll need error checking for _b could be zero
}
};
给你一张图
2) 至于正态分布,正态随机变量的值在$\mathbf{R}$中,它们的分布也是如此。我不是将 double
转换为 int
,我宁愿使用二进制随机变量对具有给定均值和方差的正态随机变量进行离散近似。 (例如参见 [=21=]。)粗略地说,您希望看到正态分布,您的 char
数量是否趋于无穷大。这正是上述二项式近似的目的。
更准确地说:考虑 $B(n,p)$ 分布(我们有共同点的维基百科符号)。当 n 收敛到 $+\infty$ 时,$B(n,p)$ 趋向于近似正态分布 $N(np,np(1-p))$。你,你得到了正态分布的均值 m 和方差 v,你的 char
s 必须被分配为。所以 m=np 并且 v =np(1-p)。由于 B(n,p) 具有集合 {0,...,n} 中的值并且您的 char
s 跨度 {97,...,122} = {0,...,25} +97(+ 表示翻译),您将取 n = 25。这导致 p = m/25 和 v = m*(1-m/25)。因此,您将使用 {0,...,25} 中的值模拟 B(m/25,m*(1-m/25)),并在 { 中生成每个 int
0,...,25}你会加上97,你会static_cast<char>
这个int得到对应的char
.
此时剩下的就是用先前建立的 n 和 p 值来模拟 B(n,p)。为此,请随意使用:
http://www.cplusplus.com/reference/random/binomial_distribution/
虽然我一直都在使用二项式进行字母采样(您也可以看看泊松,但我认为方差有点偏差)
Wrt Laplace 分布,它可以从 c++11 标准片段沿线构造
std::default_random_engine generator;
template <typename gen> double
sample_laplace(double mu, double b, gen& generator) {
std::uniform_real_distribution<double> rng(0.0, 1.0);
double x = -std::log(1.0 - rng(generator)) * b;
if (rng(generator) < 0.5)
x = -x;
return x + mu;
}
我有两个关于生成具有给定分布的 numbers/single 个字符的问题。
- 如何在 C++ 中实现拉普拉斯分布?我知道它在 boost 库中可用,但假设我不能使用它。另外,我没有在c+11的标准库中看到它。
如果我必须生成具有正态分布的字符文本,将生成的双数转换为 int 然后再转换为 char 类型是否可行?
std::default_random_engine generator; std::normal_distribution<double> distribution(112.0,5.0); int number = (int)distribution(generator); // a-z characters if(number >= 97 && number <= 122) return (char)number; else generate once again;
希望得到您的帮助。
1) 拉普拉斯分布具有显式密度(参见 here),这是一个从 $\mathbf{R}$ 到 $[0,1]$ 的函数,带有参数,因此您可以实现在 c++
作为 class 的成员函数,其成员变量例如包括分布的参数。像 :
class LaplaceRandomVariable
{
double _b;
double _mu;
public:
LaplaceRandomVariable(double b, double mu)
{
_b = b;
_mu = mu;
}
double Distribution(double x) const
{
return (0.5 / _b) * exp(-abs(x - _mu) / _b); //you'll need error checking for _b could be zero
}
};
给你一张图
2) 至于正态分布,正态随机变量的值在$\mathbf{R}$中,它们的分布也是如此。我不是将 double
转换为 int
,我宁愿使用二进制随机变量对具有给定均值和方差的正态随机变量进行离散近似。 (例如参见 [=21=]。)粗略地说,您希望看到正态分布,您的 char
数量是否趋于无穷大。这正是上述二项式近似的目的。
更准确地说:考虑 $B(n,p)$ 分布(我们有共同点的维基百科符号)。当 n 收敛到 $+\infty$ 时,$B(n,p)$ 趋向于近似正态分布 $N(np,np(1-p))$。你,你得到了正态分布的均值 m 和方差 v,你的 char
s 必须被分配为。所以 m=np 并且 v =np(1-p)。由于 B(n,p) 具有集合 {0,...,n} 中的值并且您的 char
s 跨度 {97,...,122} = {0,...,25} +97(+ 表示翻译),您将取 n = 25。这导致 p = m/25 和 v = m*(1-m/25)。因此,您将使用 {0,...,25} 中的值模拟 B(m/25,m*(1-m/25)),并在 { 中生成每个 int
0,...,25}你会加上97,你会static_cast<char>
这个int得到对应的char
.
此时剩下的就是用先前建立的 n 和 p 值来模拟 B(n,p)。为此,请随意使用:
http://www.cplusplus.com/reference/random/binomial_distribution/
虽然我一直都在使用二项式进行字母采样(您也可以看看泊松,但我认为方差有点偏差)
Wrt Laplace 分布,它可以从 c++11 标准片段沿线构造
std::default_random_engine generator;
template <typename gen> double
sample_laplace(double mu, double b, gen& generator) {
std::uniform_real_distribution<double> rng(0.0, 1.0);
double x = -std::log(1.0 - rng(generator)) * b;
if (rng(generator) < 0.5)
x = -x;
return x + mu;
}