web-dev-qa-db-fra.com

Obtenir un booléen aléatoire dans Java

Ok, j’ai implémenté cette SO question dans mon code: renvoie True ou False au hasard

Mais j'ai un comportement étrange: je dois exécuter dix instances simultanément, chaque instance retournant vrai ou faux une seule fois par exécution. Et étonnamment, peu importe ce que je fais, chaque fois que je reçois juste false

Y a-t-il quelque chose à améliorer avec cette méthode pour avoir au moins environ 50% de chances d'obtenir true?


Pour que cela soit plus compréhensible: mon application est construite dans un fichier JAR qui est ensuite exécuté via une commande batch.

 Java -jar my-program.jar
 pause

Contenu du programme - pour le rendre aussi simple que possible:

public class myProgram{

    public static boolean getRandomBoolean() {
        return Math.random() < 0.5;
        // I tried another approaches here, still the same result
    }

    public static void main(String[] args) {
        System.out.println(getRandomBoolean());  
    }
}

Si j'ouvre 10 lignes de commande et que je l'exécute, j'obtiens false comme résultat à chaque fois ...

61
Pavel Janicek

Je recommande d'utiliser Random.nextBoolean()

Ceci étant dit, Math.random() < 0.5 tel que vous l'avez utilisé fonctionne également. Voici le comportement sur ma machine:

$ cat myProgram.Java 
public class myProgram{

   public static boolean getRandomBoolean() {
       return Math.random() < 0.5;
       //I tried another approaches here, still the same result
   }

   public static void main(String[] args) {
       System.out.println(getRandomBoolean());  
   }
}

$ javac myProgram.Java
$ Java myProgram ; Java myProgram; Java myProgram; Java myProgram
true
false
false
true

Inutile de dire qu'il n'y a aucune garantie d'obtenir des valeurs différentes à chaque fois. Dans votre cas cependant, je soupçonne que

A) vous ne travaillez pas avec le code que vous pensez être (comme éditer le mauvais fichier)

B) vous n'avez pas compilé vos différentes tentatives lors des tests, ou

C) vous travaillez avec une implémentation non standard cassée.

91
aioobe

Vous pouvez aussi essayer la méthode nextBoolean()-

Voici un exemple: http://www.tutorialspoint.com/Java/util/random_nextboolean.htm

29
Sagi

Avez-vous essayé de consulter la documentation de Sun (Oracle)?

http://docs.Oracle.com/javase/1.4.2/docs/api/Java/util/Random.html#nextBoolean ()

quoi qu'il en soit, voici un exemple de code:

    Java.util.Random

    Random random = new Random();
    random.nextBoolean();
24
TheNewOne

Java 8 : utilise un générateur aléatoire isolé du thread actuel: ThreadLocalRandom nextBoolean ()

À l'instar du générateur aléatoire global utilisé par la classe Math, un ThreadLocalRandom est initialisé avec une graine générée en interne qui ne pourrait autrement pas être modifiée. Le cas échéant, l'utilisation de ThreadLocalRandom plutôt que des objets aléatoires partagés dans des programmes concurrents générera généralement beaucoup moins de surcharge et de conflits.

Java.util.concurrent.ThreadLocalRandom.current().nextBoolean();
5
wildloop

Pourquoi ne pas utiliser la classe Random , qui a une méthode nextBoolean:

import Java.util.Random;

/** Generate 10 random booleans. */
public final class MyProgram {

  public static final void main(String... args){

    Random randomGenerator = new Random();
    for (int idx = 1; idx <= 10; ++idx){
      boolean randomBool = randomGenerator.nextBoolean();
      System.out.println("Generated : " + randomBool);
    }
  }
}
2
fanf

Le moyen le plus simple d'initialiser un générateur de nombres aléatoires consiste à utiliser le constructeur sans paramètre, par exemple

Random generator = new Random();

Cependant, en utilisant ce constructeur, vous devez reconnaître que les générateurs algorithmiques de nombres aléatoires ne sont pas vraiment aléatoires, mais bien des algorithmes qui génèrent une séquence de nombres fixe mais d'apparence aléatoire.

Vous pouvez le rendre plus "aléatoire" en donnant au constructeur Random le paramètre "seed", que vous pouvez construire de manière dynamique en utilisant par exemple l'heure système en millisecondes (qui sera toujours différente).

0
PoeHaH

Vous pouvez utiliser les éléments suivants pour obtenir un résultat non biaisé:

Random random = new Random();
//For 50% chance of true
boolean chance50oftrue = (random.nextInt(2) == 0) ? true : false;

Remarque: random.nextInt (2) signifie que le nombre 2 est la limite. le comptage commence à 0. Nous avons donc 2 nombres possibles (0 et 1) et la probabilité est donc de 50%!

Si vous voulez donner plus de probabilité à votre résultat d'être vrai (ou faux), vous pouvez ajuster ce qui précède comme suit!

Random random = new Random();

//For 50% chance of true
boolean chance50oftrue = (random.nextInt(2) == 0) ? true : false;

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

//For 40% chance of true
boolean chance40oftrue = (random.nextInt(5) < 2) ? true : false;
0
christouandr7

Vous pouvez également créer deux entiers aléatoires et vérifier s'ils sont identiques, ce qui vous permet de mieux contrôler les probabilités.

Random Rand = new Random();

Déclarez une plage pour gérer la probabilité aléatoire. Dans cet exemple, il y a 50% de chances d'être vrai.

int range = 2;

Génère 2 entiers aléatoires.

int a = Rand.nextInt(range);
int b = Rand.nextInt(range);

Ensuite, il suffit de comparer renvoyer la valeur.

return a == b; 

J'ai aussi un cours que vous pouvez utiliser. RandomRange.Java

0
Angel Fernandez

vous pouvez obtenir votre valeur clock () et vérifier si elle est impair ou pair. Je ne sais pas si c'est 50% de vrai

Et vous pouvez créer votre fonction aléatoire de manière personnalisée:

static double  s=System.nanoTime();//in the instantiating of main applet
public static double randoom()
{

s=(double)(((555555555* s+ 444444)%100000)/(double)100000);


    return s;
}

les nombres 55555 .. et 444 .. sont les grands chiffres pour obtenir une fonction de portée étendue, veuillez ignorer cette icône de skype: D

0

Les mots dans un texte sont toujours une source de hasard. Étant donné une certaine Parole, rien ne peut être déduit de la prochaine Parole. Pour chaque mot, nous pouvons prendre les codes de ses lettres ASCII, ajouter ces codes pour former un nombre. La parité de ce nombre est un bon candidat pour un booléen aléatoire.

Inconvénients possibles:

  1. cette stratégie est basée sur l'utilisation d'un fichier texte comme source pour les mots. À un moment donné, la fin du fichier sera atteinte. Cependant, vous pouvez estimer le nombre de fois où vous êtes appelé à appeler la fonction randomBoolean () à partir de votre application. Si vous devez l'appeler environ 1 million de fois, un fichier texte de 1 million de mots suffira. En guise de correction, vous pouvez utiliser un flux de données provenant d'une source en direct, comme un journal en ligne.

  2. en utilisant une analyse statistique des expressions et des idiomes communs dans une langue, on peut estimer le mot suivant dans une phrase, étant donné les premiers mots de la phrase, avec un certain degré de précision. Mais statistiquement, ces cas sont rares, quand on peut prédire avec précision le prochain mot. Ainsi, dans la plupart des cas, le mot suivant est indépendant des mots précédents.

    l'emballage p01;

    importer Java.io.File; importer Java.nio.file.Files; importer Java.nio.file.Paths;

    classe publique Main {

    String words[];
    int currentIndex=0;
    
    public static String readFileAsString()throws Exception 
      { 
        String data = ""; 
        File file = new File("the_comedy_of_errors");
        //System.out.println(file.exists());
        data = new String(Files.readAllBytes(Paths.get(file.getName()))); 
        return data; 
      } 
    
    public void init() throws Exception
    {
        String data = readFileAsString(); 
        words = data.split("\\t| |,|\\.|'|\\r|\\n|:");
    }
    
    public String getNextWord() throws Exception
    {
        if(currentIndex>words.length-1)
            throw new Exception("out of words; reached end of file");
    
        String currentWord = words[currentIndex];
        currentIndex++;
    
        while(currentWord.isEmpty())
        {
            currentWord = words[currentIndex];
            currentIndex++;
        }
    
        return currentWord;
    }
    
    public boolean getNextRandom() throws Exception
    {
        String nextWord = getNextWord();
        int asciiSum = 0;
    
        for (int i = 0; i < nextWord.length(); i++){
            char c = nextWord.charAt(i);        
            asciiSum = asciiSum + (int) c;
        }
    
        System.out.println(nextWord+"-"+asciiSum);
    
        return (asciiSum%2==1) ;
    }
    
    public static void main(String args[]) throws Exception
    {
        Main m = new Main();
        m.init();
        while(true)
        {
            System.out.println(m.getNextRandom());
            Thread.sleep(100);
        }
    }
    

    }

Dans Eclipse, à la racine de mon projet, il y a un fichier appelé 'the_comedy_of_errors' (sans extension) - créé avec Fichier> Nouveau> Fichier, où j'ai collé du contenu à partir d'ici: http://shakespeare.mit .edu/comedy_errors/comedy_errors.1.1.html

0
wile the coyote