Comment générer des nombres aléatoires dans Dart?

128

Comment générer des nombres aléatoires avec Dart?

Seth Ladd
la source
4
Comment savez-vous que ce sont de mauvais chiffres? Le problème avec le hasard, c'est que vous ne pouvez jamais vraiment dire ... i46.tinypic.com/2vw7237.gif
corsiKa
2
Croyez-moi, vous sauriez qu'ils sont mauvais si vous utilisez dart: core Math. :) Voici le bogue: code.google.com/p/dart/issues/detail?id=499
Seth Ladd
3
Si vous voulez savoir si vos nombres aléatoires sont mauvais, utilisez ma bibliothèque ChiSquare pour le savoir: github.com/kaisellgren/ChiSquare
Kai Sellgren

Réponses:

180

Utilisez la Randomclasse de dart:math:

import 'dart:math';

main() {
  var rng = new Random();
  for (var i = 0; i < 10; i++) {
    print(rng.nextInt(100));
  }
}

Ce code a été testé avec la machine virtuelle Dart et dart2js, au moment de la rédaction de cet article.

Seth Ladd
la source
1
Vous feriez mieux de lire /dev/urandomavec la Fileclasse si vous voulez des nombres aléatoires cryptographiquement forts.
Tour
Qu'en est-il des nombres aléatoires négatifs (doubles)? J'essaie d'implémenter une méthode randomRange qui générerait par exemple de -0,8 à 0,9 ... le résultat serait par exemple -0,32
just_a_dude
2
@just_a_dude qui ressemble à une question parfaite pour stackoverflow. Pensez à créer une nouvelle question :)
Seth Ladd
1
La méthode qui générerait par exemple de -0,8 à 0,9 est simple. Il vous suffit de mapper les valeurs. Votre plage est de 0,8 + 0,9 = 1,7. Donc, si vous mettez rng.nextInt (1700), vous obtiendrez un nombre compris entre 0 et 1700. Divisez par 100 et réduisez -0,8. Signification yourRnd = rng.nextInt (1700) /100.0-0.8. Il y a plus d'options que vous pouvez utiliser comme ne même pas utiliser nextInt mais plutôt doubler 0-1, multiplié par 1,7 et décalé de -0,8
Veljac
28

Vous pouvez y parvenir via Randomun objet de classe random.nextInt(max), qui se trouve dans la dart:mathbibliothèque. La nextInt()méthode nécessite une limite maximale. Le nombre aléatoire commence à partir de 0et la limite maximale elle-même est exclusive.

import 'dart:math';
Random random = new Random();
int randomNumber = random.nextInt(100); // from 0 upto 99 included

Si vous souhaitez ajouter la limite minimale, ajoutez la limite minimale au résultat

int randomNumber = random.nextInt(90) + 10; // from 10 upto 99 included
Samir Rahimy
la source
votre réponse ne comprend-elle pas les nombres de 10 à 109 inclus?
Tim
@Tim merci d'avoir remarqué, je venais de copier le code de la ligne précédente. Résolu.
Samir Rahimy
17

Si vous avez besoin de nombres aléatoires sécurisés par cryptographie (par exemple pour le cryptage) et que vous êtes dans un navigateur, vous pouvez utiliser l' API de cryptographie DOM :

int random() {
  final ary = new Int32Array(1);
  window.crypto.getRandomValues(ary);
  return ary[0];
}

Cela fonctionne dans Dartium, Chrome et Firefox, mais probablement pas dans d'autres navigateurs car il s'agit d'une API expérimentale.

Sam McCall
la source
17

Voici un extrait pour générer une liste de nombres aléatoires

import 'dart:math';

main() {
  var rng = new Random();
  var l = new List.generate(12, (_) => rng.nextInt(100));
}

Cela générera une liste de 12 entiers de 0 à 99 (inclus).

Mark E. Haase
la source
9

Une API aléatoire sécurisée vient d'être ajoutée à dart:math

new Random.secure()

dart:math Randoma ajouté un secureconstructeur renvoyant un générateur aléatoire cryptographiquement sécurisé qui lit à partir de la source d'entropie fournie par l'embedder pour chaque valeur aléatoire générée.

qui délègue à window.crypto.getRandomValues()dans le navigateur et à l'OS (comme urandomsur le serveur)

Günter Zöchbauer
la source
Cette nouvelle API est disponible en version 1.14-dev ou supérieure.
Seth Ladd du
7

Impossible de commenter car je viens de créer ce compte, mais je voulais m'assurer de souligner que la solution de @ eggrobot78 fonctionne, mais elle est exclusive dans Dart, donc elle n'inclut pas le dernier numéro. Si vous remplacez la dernière ligne par "r = min + rnd.nextInt (max - min + 1);", elle doit également inclure le dernier nombre.

Explication:

max = 5;
min = 3;
Random rnd = new Random();
r = min + rnd.nextInt(max - min);
//max - min is 2
//nextInt is exclusive so nextInt will return 0 through 1
//3 is added so the line will give a number between 3 and 4
//if you add the "+ 1" then it will return a number between 3 and 5
Chad McAdams
la source
4

essayez ceci, vous pouvez contrôler la valeur min / max:

import 'dart:math';

void main(){
  random(min, max){
    var rn = new Random();
    return min + rn.nextInt(max - min);
  }
  print(random(5,20)); // Output : 19, 6, 15..
}
Aymen
la source
3

Une solution alternative pourrait être d'utiliser le code DRandom suivant . Cette classe doit être utilisée avec une graine. Il fournit une interface familière à ce que vous attendez de .NET, il a été porté à partir de Random.cs de mono. Ce code n'est peut-être pas sûr pour la cryptographie et n'a pas été testé statistiquement.

adam-chanteur
la source
J'ai déjà utilisé DRandom. Bonne lib!
John Evans
3

Je viens d'écrire cette petite classe pour générer des nombres aléatoires normaux ... c'était un bon point de départ pour la vérification que je dois faire. (Ces ensembles se répartiront sur une courbe en forme de "cloche".) La graine sera placée au hasard, mais si vous voulez être capable de régénérer un ensemble, vous pouvez simplement passer une graine spécifique et le même ensemble sera généré.

S'amuser...

class RandomNormal {
  num     _min, _max,  _sum;
  int     _nEle, _seed, _hLim;
  Random  _random;
  List    _rNAr;

  //getter
  List get randomNumberAr => _rNAr;

  num _randomN() {
    int r0 = _random.nextInt(_hLim);
    int r1 = _random.nextInt(_hLim);
    int r2 = _random.nextInt(_hLim);
    int r3 = _random.nextInt(_hLim);

    num rslt = _min + (r0 + r1 + r2 + r3) / 4000.0;  //Add the OS back in...
    _sum += rslt; //#DEBUG ONLY
    return( rslt );
  }

  RandomNormal(this._nEle, this._min, this._max, [this._seed = null]) {
    if (_seed == null ) {
      Random r = new Random();
      _seed    = r.nextInt(1000);
    }
    _hLim   = (_max - _min).ceil() * 1000;
    _random = new Random(_seed);
    _rNAr   = [];
    _sum    = 0;//#DEBUG ONLY

    h2("RandomNormal with k: ${_nEle}, Seed: ${_seed}, Min: ${_min}, Max: ${_max}");//#DEBUG ONLY
    for(int n = 0; n < _nEle; n++ ){
      num randomN = _randomN();
      //p("randomN  = ${randomN}");
      LIST_add( _rNAr, randomN );
    }

    h3("Mean = ${_sum/_nEle}");//#DEBUG ONLY
  }
}


new RandomNormal(1000, 80, 120);
new RandomNormal(1000, 80, 120);
new RandomNormal(1000, 80, 120);
new RandomNormal(1000, 80, 120);
new RandomNormal(1000, 80, 120);
new RandomNormal(1000, 80, 120);
new RandomNormal(1000, 80, 120);

Ensuite, vous pouvez simplement l'utiliser comme ceci pour vérifier la moyenne des ensembles de 1000 nombres générés entre une limite basse et haute. Les valeurs sont stockées dans la classe afin d'être accessibles après l'instanciation.

_swarmii

George Koller
la source
1

Pour moi, le moyen le plus simple est de faire:

import 'dart:math';
Random rnd = new Random();
r = min + rnd.nextInt(max - min);
//where min and max should be specified.

Merci à l'explication @ adam-singer ici.

eggrobot78
la source
1

ça a marché pour moi new Random().nextInt(100); // MAX = number

il donnera 0 à 99 nombre aléatoire

Exemple:

import 'dart:math';
int MAX = 100;
print(new Random().nextInt(MAX));`
DV Yogesh
la source
0

Permettez-moi de résoudre cette question avec un exemple pratique sous la forme d'une simple application de lancer de dés qui appelle 1 des 6 images de visage de dés au hasard à l'écran lorsque vous appuyez dessus.

déclarez d'abord une variable qui génère des nombres aléatoires (n'oubliez pas d'importer dart.math). Déclarez ensuite une variable qui analyse le nombre aléatoire initial dans les contraintes comprises entre 1 et 6 comme un entier.

Les deux variables sont statiques privées afin d'être initialisées une seule fois. Ce n'est pas une grosse affaire mais ce serait une bonne pratique si vous deviez initialiser tout un tas de nombres aléatoires.

static var _random = new Random();
static var _diceface = _rnd.nextInt(6) +1 ;

Créez maintenant un widget de détection de gestes avec un ClipRRect en tant qu'enfant pour renvoyer l'une des six images de visage de dés à l'écran lorsque vous appuyez dessus.

GestureDetector(
          onTap: () {
            setState(() {
              _diceface = _rnd.nextInt(6) +1 ;
            });
          },
          child: ClipRRect(
            clipBehavior: Clip.hardEdge,
            borderRadius: BorderRadius.circular(100.8),
              child: Image(
                image: AssetImage('images/diceface$_diceface.png'),
                fit: BoxFit.cover,
              ),
          )
        ),

Un nouveau nombre aléatoire est généré chaque fois que vous appuyez sur l'écran et ce nombre est référencé pour sélectionner l'image du visage de dés choisie.

J'espérais que cet exemple a aidé :)

Application de roulage de dés utilisant des nombres aléatoires dans Dart

Nzuzo
la source