【问题标题】:Generate characters with given distribution生成具有给定分布的字符
【发布时间】:2017-03-08 14:40:58
【问题描述】:

我有两个关于使用给定分布生成数字/单个字符的问题。

  1. 如何在 C++ 中实现拉普拉斯分布?我知道它在 boost 库中可用,但假设我不能使用它。另外,我在 c+11 的标准库中没有看到它。
  2. 如果我必须生成具有正态分布的字符文本,将生成的双数转换为 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;
    

希望得到您的帮助。

【问题讨论】:

  • 为什么不创建一个从'A''Z'(或它们的小写等效项)的正态分布?请注意,它仅适用于例如ASCII 或其他字母连续编码的编码。
  • 你在那里试过吗?您对该解决方案有什么问题?
  • 如果您不能使用 Boost.org 的解决方案,为什么您认为可以使用 StackOverflow.com 的解决方案?许可证没有那么不同。

标签: c++ distribution


【解决方案1】:

1) 拉普拉斯分布具有显式密度(参见here),这是一个从 $\mathbf{R}$ 到 $[0,1]$ 的函数,带有参数,因此可以在 c++ 中实现作为一个类的成员函数,其成员变量将包括分布的参数。比如:

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}$ 中,它们的分布也是如此。我不是将doubles 转换为int,而是您,我宁愿通过二进制随机变量使用具有给定均值和方差的正常随机变量的离散近似值。 (例如参见this。)粗略地说,您希望看到一个正态分布,您的chars 的数量是否趋于无穷大。这正是上述二项式近似的用途。

更准确地说:考虑 $B(n,p)$ 分布(维基百科符号让我们有一个共同点)。当 n 收敛到 $+\infty$ 时,$B(n,p)$ 趋向于逼近正态分布 $N(np,np(1-p))$。你,你得到了正态分布的平均值 m 和方差 v,你的 chars 必须分布为。所以 m=np 并且 v =np(1-p)。由于 B(n,p) 具有集合 {0,...,n} 中的值,并且您的 chars 跨度 {97,...,122} = {0,...,25}+97 (+ 表示翻译),您将取 n = 25。这导致 p = m/25 和 v = m*(1-m/25)。因此,您将使用 {0,...,25} 中的值模拟 B(m/25,m*(1-m/25)),并在 {0,..., 25}你会加97,你会static_cast&lt;char&gt;这个int得到对应的char

此时剩下的就是用先前建立的 n 和 p 值来模拟 B(n,p)。为此,请随意使用:

http://www.cplusplus.com/reference/random/binomial_distribution/

【讨论】:

  • 感谢您的回复。 2. 然后我将使用二项分布。它也在标准库中实现,因此会更容易。 1. 我如何将它与std::default_random_engine generator 一起使用?或其他一些功能,以便我可以生成类似于 distribution(generator); 的随机字符?我也想用它来生成给定范围内的字符。我想唯一的方法是转换为 int 然后转换为 char 类型?
  • 我将编辑我的答案,使其包含对您评论问题的答案
  • 再次感谢。但是,我的意思是您对我的第一个问题的回答:P。如何使用您提供的 LaplaceRandomVariable 类生成具有拉普拉斯分布的字符/整数。我想实现类似于标准库提供的distribution(generator); 的东西。有可能吗?
  • 嗯,你有在&lt;random&gt; 生成器用于均匀分布,其值在[0,1],不是吗?并且你在en.wikipedia.org/wiki/Laplace_distribution 中有逆累积分布函数 F 的显式公式,所以你知道基本概率论如何模拟任何拉普拉斯分布,不是吗?
  • 我之前的评论对你有意义吗?
【解决方案2】:

虽然我完全使用二项式进行字母采样(您也可以查看 Poisson,但我认为方差有点偏离)

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 2020-02-19
    • 2019-12-09
    • 1970-01-01
    • 2021-02-27
    相关资源
    最近更新 更多