Uniform int distribution c что это
Перейти к содержимому

Uniform int distribution c что это

класс std ::iform_int_distribution в C ++

В «Вероятности» дискретная равномерная функция распределения относится к распределению с постоянной вероятностью для дискретных значений в диапазоне и нулевой вероятностью вне диапазона. Функция плотности вероятности P (x) для равномерного дискретного распределения в интервале [a, b] постоянна для дискретных значений в диапазоне [a, b] и равна нулю в противном случае. Математически функция определяется как:

C ++ ввел класс random_int_distribution в случайную библиотеку , функция-член которой дает случайные целые числа или дискретные значения из заданного входного диапазона с равномерной вероятностью.

Открытые функции-члены в классеiform_int_distribution:

    operator (): эта функция возвращает случайное число из заданного диапазона распределения. Вероятность получения любого числа из этой функции одинакова. Функция Operator () занимает постоянное время для генерации.

// C ++ код для демонстрации работы
// оператор ()

// для функцииiform_int_distribution
#include <random>

using namespace std;

// Здесь объект default_random_engine

// используется как источник случайности

// Мы можем дать seed также default_random_engine

// если требуются псевдослучайные числа

uniform_int_distribution< int > distribution(a, b);

const int num_of_exp = 10000;

for ( int i = 0; i < num_of_exp; ++i) <

// используя функцию operator ()

// выдавать случайные значения

int number = distribution(generator);

cout << «Expected probability: «

// Отображение вероятности каждого числа

// после генерации значений 10000 раз.

for ( int i = 0; i < n; ++i)

<< ( float )p[i] / ( float )(num_of_exp)

Из результатов мы могли наблюдать, что вероятность каждого числа, полученного из случайного числа, намного ближе к вычисленной вероятности.

// C ++ код для демонстрации работы
// функция a (), b (), min (), max (), reset ()

// для функцииiform_int_distribution
#include <random>

Random Numbers In C++

We start by creating a default_random_engine from C++’s <random> library.

Now we can use myRandomEngine to generate some random numbers.

For me, this produces the output

As you can see, myRandomEngine() returns an unsigned integer. If you’re wondering the range of possible values that may be returned you can do

which, for me, yields

Let’s try running that first code snippet again.

Hmmm, the output is exactly the same as before.. This happens because every time we start our program, myRandomEngine is initialized to the same starting state, 1. You can see this by printing myRandomEngine before calling it.

If we want to produce a different set of random values when our program runs, we could initialize myRandomEngine with a different seed. For example,

Of course, the next time we run this program we’ll get those same values. This begs the question, How do we initialize our default_random_engine with a random seed? There are a couple of solutions to this problem..

  1. Use the computer’s internal clock to generate the seed.
  1. Use random_device.

random_device

Think of random_device as a tool that measures the current speed of you computer’s fans, multiplies that by the internal temparture of your computer, and then divides that by the amount of your computer’s used storage. Okay, that’s not exactly how random_device works, but the point I’m making is that random_device uses information about your computer’s hardware to generate true random values. Now, you might be asking, Why don’t I just use random_device as my random number generator? A few reasons..

  1. It’s not reproducible. You can’t seed random_device which means you can’t run the exact same program on your computer twice or on others’ computers. This can make debugging and performance testing difficult.
  2. It might be slow for generating many random values. Consider the fact that random_device has to reach into your computer’s hardware to generate random numbers.
  3. It can actually be a poor PRNG. If you request enough random numbers in a short timespan, the randomness (i.e. entropy) of those numbers might be low.

While we might not want to use random_device to generate a large sequence of random numbers, it’s a great solution for making a one-time truly random seed for our default_random_engine.

If I run this program again, I’ll get three totally different numbers.

Distributions

At this point we know how to generate random integers between myRandomEngine.min() and myRandomEngine.max() . On my machine, this means I can generate random integers between 1 and 2147483646. The obvious next question is How can I generate random integers within my own specified range? For example, suppose I want to generate 5 random integers between -10 and 10 inclusive with equal probability. In this case, I can use C++’s built in uniform_int_distribution.

Notice that we pass myRandomEngine as a parameter to myUnifIntDist() . myRandomDevice, myRandomEngine, and myUnifIntDist each play an important and distinct role.

  • myRandomDevice is responsible for creating a truly random value in order to seed myRandomEngine
  • myRandomEngine is responsible for quickly generating pseudo random integers between 1 and 2147483646
  • myUnifIntDist is responsible for converting those random integers into the range [-10, 10] such that they’re uniformly distributed.

This loose coupling of responsibilities makes it easy to plug in different devices, engines, and distributions. For example, suppose we wanted to generate uniform random real values in the range [0, 1]. We basically just have to change myUnifIntDist from a uniform_int_distribution to a uniform_real_distribution.

Sampling Without Replacement

At this point we know how to sample 3 integers from the range [1, 10] with replacement, but how do we do it without replacement? In other words, how do we sample 3 integers such that none of the results are repeated? The naive solution is to 1) create a vector with all the potential values, 2) shuffle it and 3) pick the first three elements from the result. Let’s see how this works.

The reason this is the naive solution is because, consider what would happen if we wanted to sample 3 integers out of 1 billion without replacement. First we’d have to create a vector with a billion values (memory-inneficient) and then we’d have to shuffle all of them (runtime-inneficient). Fortunately, the late Robert Floyd left us with a clever memory-efficient and runtime-efficient solution. In pseudocode…

In order to sample $ k $ distinct integers from the set $ [1, N] $ (where $ k \leq N $),

  1. Initialize samples = <>, an empty set to store sampled values
  2. For $ r = (N — k) $ to $ (N — 1) $:
    1. Set $ v $ equal to a random integer sampled in the range $ [1, r] $
    2. If $ v $ is not in samples, add it to the set. Otherwise add $ r $ to the set.

    Let’s code this up. (Thanks to Barry for his writeup about this on StackOverflow.)

    Boost C++ Libraries

    PrevUpHomeNext

    The class template uniform_int_distribution models a random distribution . On each invocation, it returns a random integer value uniformly distributed in the set of integers .

    The template parameter IntType shall denote an integer-like value type.

    uniform_int_distribution public construct/copy/destruct

    Constructs a uniform_int_distribution . min and max are the parameters of the distribution.

    Requires: min <= max

    Constructs a uniform_int_distribution from its parameters.

    uniform_int_distribution public member functions

    Returns the minimum value of the distribution

    Returns the maximum value of the distribution

    Returns the minimum value of the distribution

    Returns the maximum value of the distribution

    Returns the parameters of the distribution.

    Sets the parameters of the distribution.

    Effects: Subsequent uses of the distribution do not depend on values produced by any engine prior to invoking reset.

    Returns an integer uniformly distributed in the range [min, max].

    Returns an integer uniformly distributed in the range [param.a(), param.b()].

    uniform_int_distribution friend functions

    Writes the distribution to a std::ostream .

    Reads the distribution from a std::istream .

    Returns true if the two distributions will produce identical sequences of values given equal generators.

    Returns true if the two distributions may produce different sequences of values given equal generators.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *