Тема: Випадкове число з певною ймовірністью

Функцією rand() можна згенерувати випадкове число, а як згенерувати випадкове число з певною ймовірністю ? Наприклад
1 - випадає з ймовірністю 90% (із 100%), 1 випадає майже весь час
2 - випадає з ймовірністю 8%, рідко випадає 2
3 - випадає з ймовірністю 1.9%, дуже рідко випадає 3
4 - випадає з ймовірність 0.1%, 4 побачити майже неможливо

2

Re: Випадкове число з певною ймовірністью

imho треба на графік Гауса дивитись, і вже від того відштовхуватись.

Подякували: Betterthanyou1

3 Востаннє редагувалося koala (25.03.2015 20:59:44)

Re: Випадкове число з певною ймовірністью

Маємо значення 90, 8, 1.9, 0.1 (перевіряємо: сума - 100).
1. Приводимо до цілих (наприклад, множенням на 10^n): 900, 80, 19, 1.
2. Знаходимо суму S = 900+80+19+1 = 1000.
3. Генеруємо рівномірно розподілене випадкове число R від 0 до S-1.
4. Якщо 0 <= R < 900, то 1. Якщо 900 <= R < 980, то 2. Якщо 980 <= R < 999, то 3. Інакше (R = 999) 4.

Подякували: Betterthanyou, Arete2

4 Востаннє редагувалося P.Y. (25.03.2015 21:42:36)

Re: Випадкове число з певною ймовірністью

int myrand()
{
int rnd=rand()%1000;
if(rnd<900) 
    return 1;
rnd-=900;
if(rnd<80) 
    return 2;
rnd-=80;
if(rnd<19) 
    return 3;
return 4;
}

P.S. Виправлено.

5 Востаннє редагувалося Betterthanyou (25.03.2015 21:36:25)

Re: Випадкове число з певною ймовірністью

P.Y. написав:
int myrand()
{
int rnd=rand()%1000;
if(rnd<=900) 
    return 1;
rnd-=900;
if(rnd<=80) 
    return 2;
rnd-=80;
if(rnd<=19) 
    return 3;
return 4;
}

напевно ваша функція не вірна, якщо 100000000 згенерувати випадкове число хоча б один раз має випасти 4

#include <iostream>
#include <conio.h>

using namespace std;

int myrand()
{
    int rnd = rand() % 1000;
    if (rnd <= 900)
        return 1;
    rnd -= 900;
    if (rnd <= 80)
        return 2;
    rnd -= 80;
    if (rnd <= 19)
        return 3;
    return 4;
}

int main()
{
    for (int i = 0; i < 100000000; i++)
        if (4 == myrand())
            cout << i << endl;
    cout << "end";
    _getch();
    return 0;
}

rand() % 1000; генерує від 0 до 999
тому не <= а < ?

Подякували: P.Y.1

6 Востаннє редагувалося P.Y. (25.03.2015 21:37:47)

Re: Випадкове число з певною ймовірністью

Або так:

int myrand()
{
int rnd=rand()%1000;
if((rnd-=900)<0) 
    return 1;
if((rnd-=80)<0) 
    return 2;
if((rnd-=19)<0) 
    return 3;
return 4;
}
Подякували: Betterthanyou1

7

Re: Випадкове число з певною ймовірністью

http://ideone.com/ltHG3Y

std::default_random_engine generator( std::chrono::system_clock::now().time_since_epoch().count() );

int irregularRand( std::vector< std::pair< int, int > > &probabilities ) {
  int sum = 0;
  for( auto &p : probabilities ) {
      sum += p.first;
  }
  std::uniform_int_distribution<int> distribution( 0, sum - 1);
  int rnd = distribution( generator );
  for( auto &p : probabilities )    {
      rnd -= p.first;
      if( rnd < 0 ) {
        return p.second;
      }
  }
  return -1;//щось дуже сильно не так
}
Подякували: Betterthanyou1

8

Re: Випадкове число з певною ймовірністью

P.Y. написав:

Або так:

int myrand()
{
int rnd=rand()%1000;
if((rnd-=900)<0) 
    return 1;
if((rnd-=80)<0) 
    return 2;
if((rnd-=19)<0) 
    return 3;
return 4;
}

Нащо міняти змінну там де її можна не міняти?

9 Востаннє редагувалося P.Y. (26.03.2015 10:00:54)

Re: Випадкове число з певною ймовірністью

Щоб зробити код трохи більш наглядним. Якщо певне значення випадає з імовірністю 1,9%, логічніше порівнювати змінну з 19, а не 999.

Крім того, з точки зору процесора, порівняння (cmp) є лише аналогом віднімання (sub) без запису результату. Таким чином, оптимізований машинний код, де відбувається серія віднімань, може бути таким же продуктивним, як код із серією порівнянь.