"Math.random() " czy faktycznie z niego taki random ?

0

Witam mam pytanie :

Na potrzeby programu potrzebuję zasymulować rzut monetą zakładając że prawdopodobieństwo na wystąpienie każdego z wyniku wynosi 1/2.
Wydało mi się to banalne i użyłem takiej składni

int x=(int)(Math.random()*2);
boolean flipCoin=(x==0)? (true):(false);

Podczas symulacji częściej otrzymywałem wynik 0 niż 1 . Czy taka składnia daje mi faktycznie 50% szans na wystąpienie konkretnego wyniku ?

3

Skoro Konwertujesz do integera liczbę z zakresu: [0.0, 1.0) (mniejsze od jeden), to nie dziwne, że Masz więcej zer:). Z dokumentacji:

Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0

Użyj Random.nextInt(int bound).
https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#nextInt-int-

5
okon66113 napisał(a):

Czy taka składnia daje mi faktycznie 50% szans na wystąpienie konkretnego wyniku ?

Jak już wspomniał @lion137, to nie daje.
Ale poza tym losowość rzutu monetą też nie daje konkretnych wyników. Możesz rzucić 10 razy monetą i mieć 9 razy reszkę :]

9

A ile tych losowań zrobiłeś? Tak naprawdę dopiero przy dużej ilości (idącej w dziesiątki tysięcy losowań) możemy mówić o w miarę równomiernym rozkładzie.

Jest sobota, mam trochę więcej wolnego czasu z rana, więc na szybko zrobiłem symulację proporcji wyników w zależności od ilości losowań. Jak widać na załączonych poniżej obrazkach (wykonałem kilka prób), dopiero w okolicy 10k losowań wyniki są w miarę równomiernie rozłożone.

screenshot-20200208082958.png

screenshot-20200208083104.png

screenshot-20200208083128.png

screenshot-20200208083237.png


P.S. Java nie jest moją technologią, więc swoją drogą - mógłby się wypowiedzieć ktoś, kto się zna na tym języku, czy podana w pierwszym poście metoda losowania jest prawidłowa.
Jak koledzy napisali powyżej - podana metoda jednak nie była wolna od błędu ;)

3
cerrato napisał(a):

A ile tych losowań zrobiłeś? Tak naprawdę dopiero przy dużej ilości (idącej w dziesiątki tysięcy losowań) możemy mówić o w miarę równomiernym rozkładzie.

Słusznie prawisz. Dodam, że duża ilość losowań sprawia, że różnica między częstością, a prawdopodobieństwem staje się malutka. W literaturze fachowej można szukać pod hasłem "prawo wielkich liczb Bernoulliego".

7

Prawdziwego randoma to trzeba sobie samemu zrobić:

public class TrueRandom {
    private boolean next = Math.random() >= 0.5;

    public boolean nextBoolean() {
        return (next ^= true);
    }

    public static void main(String[] args) {
        TrueRandom random = new TrueRandom();
        int orzełki = 0;
        int reszki = 0;
        for (int i = 0; i < 100; i++) {
            if (random.nextBoolean()) {
                orzełki++;
            } else {
                reszki++;
            }
        }
        System.out.println("Orzełki: " + orzełki);
        System.out.println("Reszki: " + reszki);
    }
}

Wynik:

Orzełki: 50
Reszki: 50

Ideał.

PS:

boolean flipCoin=(x==0)? (true):(false);

Ciekawy kod, ale mam pomysł na ulepszenie:

boolean flipCoin=(x==0)? (x==0):(x==0);

Teraz jest znacznie lepiej.

/s

0

Jestem bardzo początkujący i nie rozumiem tylko jednego zapisu w twoim kodzie "(next ^= true)" co to oznacza ???

3

XOR w połączeniu z przypisaniem. PS: cały kod to satyra.

0
Wibowit napisał(a):

XOR w połączeniu z przypisaniem. PS: cały kod to satyra.

Przepraszam ale dalej nie rozumiem .

2

@Wibowit: skoro jest początkujący, to lepiej dać mu wędkę, nie rybę.

@okon66113: wpisujesz w google: ^= operator java
I przeglądasz kilka pierwszych wyników.


edit: na dole strony z wynikami ma naprowadzenie na inne frazy wyszukiwania:

screenshot-20200210181956.png

1 użytkowników online, w tym zalogowanych: 0, gości: 1