需要一个正态分布的随机数发生器吗 我是C++新手,但有数学背景。我正在尝试创建一个随机数生成器,它将以近似正态分布(因此平均值为1.50)吐出1.00到2.00之间的小数(美元金额)

需要一个正态分布的随机数发生器吗 我是C++新手,但有数学背景。我正在尝试创建一个随机数生成器,它将以近似正态分布(因此平均值为1.50)吐出1.00到2.00之间的小数(美元金额),c++,normal-distribution,C++,Normal Distribution,现在,我从未尝试过这样的事情,也没有发现类似的问题,特别是从一组正态分布概率的数字中吐出一个元素。在这个模型中,1.50最有可能出现,1.00或2.00几乎没有出现的机会 对于均值为1.50、3*西格玛为0.5-->西格玛为1/6的正态分布,编写p.d.f.非常简单(因此几乎所有数据都在1.00和2.00之间)。然而,不仅仅是不知道如何在C++中用曲线来整合101个区域(我认为这是不可能解决的),对我来说听起来并不有效。我知道C++中有正态分布函数。 有人能帮我把这写出来,加上评论吗?谢谢你<

现在,我从未尝试过这样的事情,也没有发现类似的问题,特别是从一组正态分布概率的数字中吐出一个元素。在这个模型中,1.50最有可能出现,1.00或2.00几乎没有出现的机会

对于均值为1.50、3*西格玛为0.5-->西格玛为1/6的正态分布,编写p.d.f.非常简单(因此几乎所有数据都在1.00和2.00之间)。然而,不仅仅是不知道如何在C++中用曲线来整合101个区域(我认为这是不可能解决的),对我来说听起来并不有效。我知道C++中有正态分布函数。
有人能帮我把这写出来,加上评论吗?谢谢你

< p> C++标准库有一个-就是你所要求的。使用它-并剪裁该值,使其介于最小值和最大值之间:

#include <algorithm> // for std::clamp()
#include <iostream>
#include <random>

int main() {
    std::random_device randomness_device{};
    std::mt19937 pseudorandom_generator{randomness_device()};

    auto mean = 1.5;
    auto std_dev = 0.5;
    auto min_allowed = 1.0;
    auto max_allowed = 2.0;
    std::normal_distribution<> distribution{mean, std_dev};
    auto sample = distribution(pseudorandom_generator);
    auto clamped = 
        // C++17 and later
        std::clamp(sample, min_allowed, max_allowed);
        // C++14 or earlier:
        // std::max(min_allowed,std::min(sample, max_allowed));
        // 

    std::cout 
        << "A value from a normal distribution with mean " << mean
        << " and standard deviation " << std_dev << ": "   << sample
        << "; when clamped to [" << min_allowed << ", " 
        << max_allowed << "], we get: " << clamped << "\n";
}
#包含//用于std::clamp()
#包括
#包括
int main(){
std::随机性设备随机性设备{};
std::mt19937伪随机_生成器{随机性_设备()};
自动平均值=1.5;
自动标准偏差=0.5;
允许的自动最小值=1.0;
允许的自动最大值=2.0;
正态分布{mean,std_dev};
自动采样=分布(伪随机发生器);
自动夹紧=
//C++17及更高版本
标准:夹具(样品,允许最小值,允许最大值);
//C++14或更早版本:
//标准::最大值(允许最小值,标准::最小值(允许样本,允许最大值));
// 
标准::cout

您可以为此使用
std::normal_distribution

它从
double
数据类型的整个范围生成样本,但您可以在感兴趣的时间间隔之外丢弃样本,并且使用三西格玛仍将接近正态分布

#include <iostream>
#include <random>

using namespace std;

int main()
{
    auto mean   = 1.5,
         stddev = 1.0 / 6;

    // Create a normal distribution to pull samples from
    // The distribution has mean 1.5 and ~1/6 std dev
    random_device rd;
    mt19937_64 generator(rd());
    normal_distribution<> distribution(mean, stddev);

    cout << "some samples:" << endl;
    for (int i = 0; i < 10; ++i)
    {
        // Generate a sample.  The sample will be in (-infinity, infinity), so 
        // we throw away values that are outside of 3 std devs.
        // The distribution will no longer be normal, but close enough.
        double v;
        do
        {
            v = distribution(generator);
        } while (v < mean - 3 * stddev || v >= mean + 3 * stddev);

        cout << v << endl;
    }
    return 0;
}

除了其他答案之外,您还可以使用(伪)UNFM随机数生成器通过使用

示例代码:

#include <math.h>
#include <stdlib.h>

double
randn (double mu, double sigma)
{
  double U1, U2, W, mult;
  static double X1, X2;
  static int call = 0;

  if (call == 1)
    {
      call = !call;
      return (mu + sigma * (double) X2);
    }

  do
    {
      U1 = -1 + ((double) rand () / RAND_MAX) * 2;
      U2 = -1 + ((double) rand () / RAND_MAX) * 2;
      W = pow (U1, 2) + pow (U2, 2);
    }
  while (W >= 1 || W == 0);

  mult = sqrt ((-2 * log (W)) / W);
  X1 = U1 * mult;
  X2 = U2 * mult;

  call = !call;

  return (mu + sigma * (double) X1);
}
#包括
#包括
双重的
randn(双mu,双西格玛)
{
双U1,U2,W,mult;
静态双X1,X2;
静态int调用=0;
如果(调用==1)
{
呼叫=!呼叫;
返回值(μ+西格玛*(双)X2);
}
做
{
U1=-1+((双)兰德()/rand_MAX)*2;
U2=-1+((双)兰特()/rand_MAX)*2;
W=功率(U1,2)+功率(U2,2);
}
而(W>=1 | | W==0);
mult=sqrt(-2*log(W))/W);
X1=U1*mult;
X2=U2*mult;
呼叫=!呼叫;
返回值(μ+西格玛*(双)X1);
}

接下来,您可以使用它来获取应用程序的正态分布随机数。

如果您修改分布以生成[1,2]上的实际概率度量,则此答案将更有用。在这里会很有用。但是,将所有内容折叠到边界中可能不是一个理想的近似方法,而只是重新滚动,直到到达正确的间隔开始。@BaummitAugen:噢,我还没有意识到“钳夹”将其转换为C++17。至于分布,这取决于OP实际想要实现什么。当然,这只是我对“近似正态分布”的解释,我怀疑它不应该为点分配正概率。不过,我同意这在问题中定义不正确。应该是
std::mt19937伪随机发生器{rd()};
#include <math.h>
#include <stdlib.h>

double
randn (double mu, double sigma)
{
  double U1, U2, W, mult;
  static double X1, X2;
  static int call = 0;

  if (call == 1)
    {
      call = !call;
      return (mu + sigma * (double) X2);
    }

  do
    {
      U1 = -1 + ((double) rand () / RAND_MAX) * 2;
      U2 = -1 + ((double) rand () / RAND_MAX) * 2;
      W = pow (U1, 2) + pow (U2, 2);
    }
  while (W >= 1 || W == 0);

  mult = sqrt ((-2 * log (W)) / W);
  X1 = U1 * mult;
  X2 = U2 * mult;

  call = !call;

  return (mu + sigma * (double) X1);
}