Vjerojatnost u Javi

1. Pregled

U ovom uputstvu pogledat ćemo nekoliko primjera kako vjerojatnost možemo implementirati s Javom.

2. Simuliranje osnovne vjerojatnosti

Da bismo simulirali vjerojatnost u Javi, prvo što moramo učiniti je generiranje slučajnih brojeva. Srećom, Java nam nudi puno generatori slučajnih brojeva.

U ovom ćemo slučaju koristiti SplittableRandom klase jer pruža visokokvalitetnu slučajnost i relativno je brz:

SplittableRandom random = novo SplittableRandom ();

Zatim moramo generirati broj u rasponu i usporediti ga s drugim brojem odabranim iz tog raspona. Svaki broj u rasponu ima jednake šanse za izvlačenje. Kako poznajemo domet, znamo i vjerojatnost crtanja odabranog broja. Na taj način kontroliramo vjerojatnost:

logička vjerojatnoFalse = random.nextInt (10) == 0

U ovom smo primjeru izvukli brojeve od 0 do 9. Stoga je vjerojatnost izvlačenja 0 jednaka 10%. Uzmimo slučajni broj i testiramo je li odabrani broj niži od izvučenog:

logička vrijednost WhoKnows = random.nextInt (1, 101) <= 50

Ovdje smo izvukli brojeve od 1 do 100. Šansa da naš slučajni broj bude manji ili jednak 50 iznosi točno 50%.

3. Ujednačena distribucija

Vrijednosti generirane do ovog trenutka spadaju u jednoliku raspodjelu. Ovo znači to svaki događaj, na primjer bacanje nekog broja na kocku, ima jednake šanse da se dogodi.

3.1. Pozivanje funkcije s danom vjerojatnošću

Recimo da želimo s vremena na vrijeme izvesti zadatak i kontrolirati njegovu vjerojatnost. Na primjer, upravljamo web stranicama za e-trgovinu i želimo dati popust za 10% naših korisnika.

Da bismo to učinili, primijenimo metodu koja će uzeti tri parametra: dobavljač koji se poziva u određenom postotku slučajeva, drugi dobavljač koji se poziva u ostatku slučajeva i vjerojatnost.

Prvo, izjavljujemo svoje SplittableRandom kao Lijen koristeći Vavr. Na ovaj ćemo ga način instancirati samo jednom, na prvi zahtjev:

privatni konačni Lazy random = Lazy.of (SplittableRandom :: new); 

Zatim ćemo implementirati funkciju upravljanja vjerojatnostima:

public withProbability (dobavljač positiveCase, dobavljač negativeCase, int vjerojatnost) {SplittableRandom random = this.random.get (); if (random.nextInt (1, 101) <= vjerojatnost) {return positiveCase.get (); } else {vratiti negativeCase.get (); }}

3.2. Vjerojatnost uzorkovanja Monte Carlo metodom

Vratimo postupak koji smo vidjeli u prethodnom odjeljku. Da bismo to učinili, vjerojatnost ćemo izmjeriti metodom Monte Carlo. Generira veliku količinu slučajnih događaja i broji koliko ih zadovoljava predviđeni uvjet. Korisno je kad je vjerojatnost teško ili je nemoguće analitički izračunati.

Na primjer, ako pogledamo šestostrane kocke, znamo da je vjerojatnost bacanja određenog broja 1/6. Ali, ako imamo misteriozne kockice s nepoznatim brojem strana, bilo bi teško reći kolika će biti vjerojatnost. Umjesto da analiziramo kocku, mogli bismo je baciti mnogo puta i izbrojati koliko se puta događaju određeni događaji.

Pogledajmo kako možemo primijeniti ovaj pristup. Prvo ćemo pokušati generirati broj 1 s vjerojatnošću od 10% milijun puta i brojati ih:

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

Tada će zbroj generiranih brojeva podijeljen s brojem uzoraka biti približna vjerojatnost događaja:

int monteCarloProbability = (howManyTimesInvoked * 100) / numberOfSamples; 

Imajte na umu da je izračunata vjerojatnost približna. Što je veći broj uzoraka, to će biti bolja aproksimacija.

4. Ostale distribucije

Ujednačena raspodjela dobro funkcionira za modeliranje stvari poput igara. Da bi igra bila poštena, svi događaji često moraju imati jednaku vjerojatnost da se dogode.

Međutim, u stvarnom su životu distribucije obično složenije. Šanse nisu jednake da se dogode različite stvari.

Na primjer, vrlo je malo izuzetno niskih ljudi, a vrlo malo izuzetno visokih. Većina ljudi je prosječne visine, što znači da visina ljudi prati normalnu raspodjelu. Ako trebamo generirati slučajne ljudske visine, tada neće biti dovoljno generirati slučajni broj stopa.

Srećom, osnovni matematički model ne trebamo implementirati sami. Moramo znati koju distribuciju koristiti i kako je konfigurirati, na primjer, koristeći statističke podatke.

Biblioteka Apache Commons pruža nam implementacije za nekoliko distribucija. Provedimo s njom normalnu distribuciju:

privatni statički završni dvostruki MEAN_HEIGHT = 176,02; privatni statički završni dvostruki STANDARD_DEVIATION = 7,11; privatna statička distribucija NormalDistribution = nova NormalDistribution (MEAN_HEIGHT, STANDARD_DEVIATION); 

Korištenje ovog API-ja vrlo je jednostavno - metoda uzorka crpi slučajni broj iz distribucije:

javna statička dvostruka generacijaNormalHeight () {return distribution.sample (); }

Na kraju, okrenimo proces:

javna statička dvostruka vjerovatnoćaOfHeightBetween (double heightLowerExclusive, double heightUpperInclusive) {return distribution.probability (heightLowerExclusive, heightUpperInclusive); }

Kao rezultat, dobit ćemo vjerojatnost da osoba ima visinu između dvije granice. U ovom slučaju, donja i gornja visina.

5. Zaključak

U ovom smo članku naučili kako generirati slučajne događaje i kako izračunati vjerojatnost da će se oni dogoditi. Koristili smo jednoliku i normalnu raspodjelu za modeliranje različitih situacija.

Cjelovit primjer možete pronaći na GitHubu.


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