2013-06-28 17 views
15

Potrzebuję wygenerować losowe wartości logiczne. Jednak muszę być w stanie określić prawdopodobieństwo zwrotu true. W rezultacie:Losowa wartość logiczna z wagą lub odchyleniem

private Random random = new Random(); 
random.nextBoolean(); 

nie będzie działać.

Możliwym rozwiązaniem byłoby:

private Random random = new Random() 

public boolean getRandomBoolean(float p){ 
return random.nextFloat() < p; 
} 

Zastanawiałem się, czy istnieje lepszy lub bardziej naturalny sposób to zrobić.

EDIT: Chyba pytam, czy istnieje klasa biblioteki, która zapewnia metodę nextBoolean (prawdopodobieństwo float).

+3

Jakie „lepsze” szukasz? Wydaje mi się to rozsądne ... –

+1

To są dwa (zasadniczo) oddzielne problemy, więc powinno być zadawane w dwóch oddzielnych postach ... –

+0

@JonSkeet Sądzę, że miałem nadzieję na coś podobnego do Random.nextBoolean (długie prawdopodobieństwo) – maxf130

Odpowiedz

9

Zastanawiam się, czy istnieje lepszy lub bardziej naturalny sposób robienia tego.

Podejście, którego już używasz, jest w porządku. * AFAIK, nie ma standardowej metody Java, która spowoduje, że ten kod będzie krótszy.


* Do celów innych niż kryptograficzne.

+2

czy to nie jest komentarz? –

+0

@Baadshah: Hmm, tak. Przeformułowałem już teraz! –

+0

Yeah..perfect !!!! +1. –

-1

Twoja droga jest chyba lepiej, kod golf-mądry, ale inny sposób to zrobić to tak:

public boolean getRandomBoolean() { 
    Random random = new Random(); 
    //For 1 in 5 
    int chanceOfTrue = 5; 

    if (random.nextInt(chanceOfTrue) == 0) { 
     return true; 
    } else { 
     return false; 
    } 
} 

Lub 2 w 5, spróbuj tego:

public boolean getRandomBoolean() { 
    Random random = new Random(); 
    //For 2 in 5 
    int chanceOfTrue = 5; 
    int randInt = random.nextInt(chanceOfTrue); 

    if (randInt == 0 || randInt == 1) { 
     return true; 
    } else { 
     return false; 
    } 
} 
-1

Losowy obiekt musi być już zaimplementowany.

public static boolean flipRandom(double probability) { 
    Validate.isBetween(probability, 0, 1, true); 
    if(probability == 0) 
     return false; 
    if(probability == 1) 
     return true; 
    if(probability == 0.5) 
     return random.nextBoolean(); 
    return random.nextDouble() < probability ? true : false; 
} 
+0

Walidacja jest uzasadniona, reszta czyni kod niepotrzebnie mniej czytelnym. Niech będzie proste – Oneiros

0
public boolean getBiasedRandom(int bias) { 
     int c; 
     Random t = new Random(); 
    // random integers in [0, 100] 
     c=t.nextInt(100); 
     if (c>bias){return false; 
     } 
     else{return true;} 
     } 

Ta jedna jest oparta na procentach ...

0

Oto co używam. Bardzo podobny do odpowiedzi FracturedRetina.

Random random = new Random(); 

// 20% chance 
boolean true20 = (random.nextInt(5) == 0) ? true : false; 

// 25% chance 
boolean true25 = (random.nextInt(4) == 0) ? true : false; 

// 40% chance 
boolean true40 = (random.nextInt(5) < 2) ? true : false; 
+1

Operator trójskładnikowy jest całkowicie nadmiarowy. Dlaczego nie tylko 'boolean true20 = (random.nextInt (5) == 0)'? – Oneiros

+0

Wiesz, kiedy uczysz się czegoś nowego, jest przydatna w każdej sytuacji? Całkowicie się zgadzam, że jest zbędny. – bobanahalf

0

Rozwijając na odpowiedź user2495765'S, można utworzyć funkcję, która pobiera wskaźnik wejścia (jako dwie wartości szansa: Przedział patrz kod)

public class MyRandomFuncs { 
    public Random rand = new Random(); 

    boolean getBooleanAsRatio(int chance, int range) { 
     int c = rand.nextInt(range + 1); 
     return c > chance; 
    } 

}

zależności od tego co zamierzasz aby to zrobić, prawdopodobnie nie chcesz inicjalizować losowego z twojej metody, ale raczej użyj jako zmiennej klasy (jak w powyższym kodzie) i wywołaj nextInt() z twojej funkcji.

0

Biblioteka MockNeat implementuje tę funkcję.

Przykład generowania wartość logiczną, która posiada 99,99% jest prawdziwe:

MockNeat m = MockNeat.threadLocal(); 
boolean almostAlwaysTrue = m.bools().probability(99.99).val();