Pravdepodobnosť v Jave

1. Prehľad

V tomto výučbe sa pozrieme na niekoľko príkladov, ako môžeme implementovať pravdepodobnosť v prostredí Java.

2. Simulácia základnej pravdepodobnosti

Ak chcete simulovať pravdepodobnosť v prostredí Java, prvá vec, ktorú musíme urobiť, je vygenerovať náhodné čísla. Našťastie nám Java poskytuje veľa generátory náhodných čísel.

V tomto prípade použijeme SplittableRandom triedy, pretože poskytuje vysoko kvalitnú náhodnosť a je pomerne rýchla:

SplittableRandom random = nový SplittableRandom ();

Potom musíme vygenerovať číslo v rozsahu a porovnať ho s iným číslom vybraným z tohto rozsahu. Každé číslo v rozmedzí má rovnakú šancu na vylosovanie. Keď poznáme rozsah, poznáme pravdepodobnosť nakreslenia nami vybraného čísla. Týmto spôsobom kontrolujeme pravdepodobnosť:

boolean probablyFalse = random.nextInt (10) == 0

V tomto príklade sme nakreslili čísla od 0 do 9. Preto je pravdepodobnosť čerpania 0 rovná 10%. Teraz si dajme náhodné číslo a otestujme, či je zvolené číslo nižšie ako vyžrebované:

boolean whoKnows = random.nextInt (1, 101) <= 50

Tu sme nakreslili čísla od 1 do 100. Šanca, aby naše náhodné číslo bolo menšie alebo rovné 50, je presne 50%.

3. Jednotná distribúcia

Hodnoty generované do tohto bodu spadajú do rovnomerného rozdelenia. To znamená, že každá udalosť, napríklad hodenie nejakého čísla na kocky, má rovnakú šancu na uskutočnenie.

3.1. Vyvolanie funkcie s danou pravdepodobnosťou

Teraz povedzme, že chceme z času na čas vykonať úlohu a riadiť jej pravdepodobnosť. Prevádzkujeme napríklad web elektronického obchodu a chceme poskytnúť zľavu 10% našich používateľov.

Aby sme to mohli urobiť, implementujme metódu, ktorá bude mať tri parametre: dodávateľ, ktorého sa dá vyvolať v niektorých percentách prípadov, druhý dodávateľ, ktorého sa dá dovolať, vo zvyšných prípadoch a pravdepodobnosť.

Najprv vyhlásime svoje SplittableRandom ako Lenivý pomocou Vavr. Týmto spôsobom vytvoríme inštanciu iba raz, na prvú žiadosť:

súkromné ​​finále Lazy random = Lazy.of (SplittableRandom :: new); 

Potom implementujeme funkciu riadenia pravdepodobnosti:

public withProbability (Supplier positiveCase, Supplier positiveCase, int pravdepodobnosť) {SplittableRandom random = this.random.get (); if (random.nextInt (1, 101) <= pravdepodobnosť) {return positiveCase.get (); } else {return negativeCase.get (); }}

3.2. Pravdepodobnosť vzorkovania metódou Monte Carlo

Obráťme proces, ktorý sme videli v predchádzajúcej časti. Aby sme to dosiahli, zmeriame pravdepodobnosť pomocou metódy Monte Carlo. Generuje veľké množstvo náhodných udalostí a počíta, koľko z nich spĺňa zadanú podmienku. Je to užitočné, keď je pravdepodobnosť, že je ťažké alebo nemožné analyticky vypočítať.

Napríklad, ak sa pozrieme na šesťstranné kocky, vieme, že pravdepodobnosť hádzania určitého čísla je 1/6. Ale ak máme záhadné kocky s neznámym počtom strán, ťažko by sme povedali, aká by bola pravdepodobnosť. Namiesto analýzy kocky by sme ich mohli len opakovane hodiť a spočítať, koľkokrát sa vyskytujú určité udalosti.

Pozrime sa, ako môžeme tento prístup implementovať. Najprv sa pokúsime miliónkrát vygenerovať číslo 1 s pravdepodobnosťou 10% a spočítať ich:

int numberOfSamples = 1_000_000; int pravdepodobnosť = 10; int howManyTimesInvoked = Stream.generate (() -> randomInvoker.withProbability (() -> 1, () -> 0, pravdepodobnosť)) .limit (numberOfSamples) .mapToInt (e -> e) .sum ();

Súčet vygenerovaných čísel vydelený počtom vzoriek bude potom aproximáciou pravdepodobnosti udalosti:

int monteCarloProbability = (howManyTimesInvoked * 100) / numberOfSamples; 

Nezabudnite, že vypočítaná pravdepodobnosť je aproximovaná. Čím vyšší je počet vzoriek, tým lepšia bude aproximácia.

4. Ostatné distribúcie

Jednotná distribúcia funguje dobre pri modelovaní vecí, ako sú hry. Aby bola hra spravodlivá, je pravdepodobné, že všetky udalosti musia mať rovnakú pravdepodobnosť.

V skutočnom živote sú však distribúcie zvyčajne komplikovanejšie. Šance nie sú rovnaké, aby sa mohli stať rôzne veci.

Napríklad je veľmi málo extrémne nízkych ľudí a veľmi málo extrémne vysokých ľudí. Väčšina ľudí má priemernú výšku, čo znamená, že výška ľudí zodpovedá normálnemu rozdeleniu. Ak potrebujeme generovať náhodné ľudské výšky, potom nestačí vygenerovať náhodný počet stôp.

Našťastie nemusíme sami implementovať základný matematický model. Potrebujeme vedieť, ktorú distribúciu použiť a ako ju nakonfigurovaťnapríklad pomocou štatistických údajov.

Knižnica Apache Commons nám poskytuje implementácie pre niekoľko distribúcií. Implementujme s ním normálne rozdelenie:

súkromné ​​statické konečné dvojité MEAN_HEIGHT = 176,02; súkromné ​​statické konečné dvojité STANDARD_DEVIATION = 7.11; súkromná statická distribúcia NormalDistribution = nová Normálna distribúcia (MEAN_HEIGHT, STANDARD_DEVIATION); 

Používanie tohto API je veľmi priame - vzorová metóda čerpá náhodné číslo z distribúcie:

public static double generateNormalHeight () {return distribution.sample (); }

Na záver obráťme postup:

public static double probabilityOfHeightB Between (double heightLowerExclusive, double heightUpperInclusive) {return distribution.probability (heightLowerExclusive, heightUpperInclusive); }

Vo výsledku dostaneme pravdepodobnosť, že človek bude mať výšku medzi dvoma hranicami. V tomto prípade dolná a horná výška.

5. Záver

V tomto článku sme sa naučili, ako generovať náhodné udalosti a ako vypočítať pravdepodobnosť ich výskytu. Na modelovanie rôznych situácií sme použili rovnomerné a normálne rozdelenie.

Celý príklad nájdete na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found