IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Random génération de nombre aléatoire: quelque chose m'échappe [Débutant]


Sujet :

C#

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2017
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2017
    Messages : 16
    Points : 9
    Points
    9
    Par défaut Random génération de nombre aléatoire: quelque chose m'échappe
    Bonjour, toujours dans mes premiers pas en c# et Poo.

    Quand je crée mes animaux, je veux qu'ils aient 5 attributs obligatoirement connus.

    Ce qui donne dans mon constructeur le plus simple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    class Chien : MammifereTerrestre, IDomesticable, Inageant, IPopulationVariable 
        {
     public Chien()
            {
              this.Id_guid = Guid.NewGuid();
              this.vivant = true;
              this.sexe = Cl_St_MethodesPartagees.AffecterSexeAlea(50);
              this.dateCreation = DateTime.Now;
     
              if (this.sexe == 'F') { this.AppellationAnimal = "une chienne"; }  //définition de l'appellation  animal selon le sexe
                else { this.AppellationAnimal = "un chien"; }
     
     
              lstAnimaux.Add(this);} // peuplement de la faune dans la list static de la super Classe Animaux
             }
          }
    La seule subtilité, c'est que je veux une affectation aléatoire du sexe selon un ratio M/F qui peut varier selon les espèces.
    J'ai donc créé ailleurs une fonction pour me fournir cela.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    static class Cl_St_MethodesPartagees
        {
            public static char AffecterSexeAlea(int proportionMaleSur100)
            {
                Random aleatoire = new Random();
                int sexe = aleatoire.Next(100);
                    if (sexe < proportionMaleSur100) return 'M';
                    else return 'F';
            }
    Cela marche très bien, circulez y'a rien à voir...

    Sauf que j'ai une méthode qui me permet d'instancier un grand nombre d'animaux: public static void CreerSerieChiens(int nombre)

    Et là ça foire lamentablement.

    Que me dit MS ?
    Éviter plusieurs instanciations
    L’initialisation de deux générateurs de nombres aléatoires dans une boucle étroite ou en succession rapide crée deux générateurs de nombres aléatoires qui peuvent produire des séquences identiques de nombres aléatoires. Dans la plupart des cas, cela n’est pas intention du développeur et peut entraîner des problèmes de performances, car l’instanciation et initialisation d’un générateur de nombres aléatoires sont un processus relativement coûteux.
    À la fois pour améliorer les performances et d’éviter de créer par inadvertance les générateurs de nombres aléatoires distincts qui génèrent des séquences numériques identiques, nous vous recommandons de créer un Random objet pour générer des nombres aléatoires au fil du temps, au lieu de créer de nouveaux Random objets pour générer un nombre aléatoire.
    Bon, mon petit cerveau a fini par comprendre et trouver une solution:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public static List<char> RenvoyerListSexesAleatoires(int nbreVoulu, int proportionMaleSur100)
            {
                List<char> listAlea = new List<char>();
                char sx;
                int nbralea;
                Random rnd = new Random();
                for (int i = 0; i < nbreVoulu; i++)
                {
                    nbralea = rnd.Next(0, 100);
                    if (nbralea < proportionMaleSur100) { sx = 'M'; }
                    else { sx = 'F'; }
                    listAlea.Add(sx);
                }
                return listAlea;
            }

    A mon créateur de série de chiens de gérer cette liste. Il le fait très bien. Merci pour lui...


    Mais je ne comprends toujours pas pourquoi initialiser en succession rapide des new Random() les fait générer des nombres identiques ? Quelque chose m'échappe...

  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2008
    Messages
    381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Août 2008
    Messages : 381
    Points : 766
    Points
    766
    Par défaut
    C'est qu'il utilise le temps (using a time-dependent default seed value) du système comme seed. Si tu en instancie plusieurs dans le même interval de temps, tu aura le même seed.
    Les fautes d'orthographes sus-citées sont déposées auprès de leurs propriétaires respectifs. Aucune responsabilité n'est engagée sur la lisibilité du message ou les éventuels dommages qu'il peut engendrer.

  3. #3
    Membre éprouvé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Septembre 2005
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 462
    Points : 1 056
    Points
    1 056
    Par défaut
    On est tous tombé sur ce genre de problème

    La réponse de PatteDePoule est parfaite.

    Résolution :
    Si tu déclare une variable "Aleatoire" de type "Ramdom" en static dans ta classe tu ne rencontrera plus le problème.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    static class Cl_St_MethodesPartagees
        {
            private static Ramdom Aleatoire = new Random();
            public static char AffecterSexeAlea(int proportionMaleSur100)
            {
                int sexe = Aleatoire.Next(100);
                    if (sexe < proportionMaleSur100) return 'M';
                    else return 'F';
            }

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2017
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2017
    Messages : 16
    Points : 9
    Points
    9
    Par défaut
    Un grand merci à vous deux pour vos explications limpides.


    Citation Envoyé par katkiller
    On est tous tombé sur ce genre de problème
    Oui, apparemment c'est un grand classique: j'ai trouvé ceci:http://csharpindepth.com/Articles/Chapter12/Random.aspx

    Où l'on apprend aussi qu'il existe un autre générateur de nombre aléatoire, utilisé pour la cryptographie.

    Me restent deux questions subsidiaires:

    - Katkiller, tu mets le Random aleatoire en private, mais je pourrais aussi bien le mettre en public. Ainsi si j'ai besoin ailleurs que dans cette classe d'un random, j'utilise celui-ci. Je n'en ai donc qu'un seul dans tout mon programme ?

    - Par pure curiosité, à quoi pourrait bien servir un random dans une boucle (comme j'avais fait au départ) qui me génère des tirages aléatoires... similaires ?

  5. #5
    Expert confirmé
    Avatar de wallace1
    Homme Profil pro
    Administrateur systèmes
    Inscrit en
    Octobre 2008
    Messages
    1 966
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 966
    Points : 4 005
    Points
    4 005
    Billets dans le blog
    7
    Par défaut
    bonsoir,

    Cela n'a rien a voir avec la portée de random. Il ne faut pas instancier ton objet random au meme endroit ou tu appelles ta methode Next, je veux dire par la qu il ne faut pas qu ils se situent dans un meme corps de methode.
    De plus si tu veux que ton nombre soit aleatoire dans l ensemble de ton programme alors il faudra instancier une seule fois random pour ensuite appeler autant de fois que tu veux la methode next (depuis l unique instance de ton objet random).

    je sais pas si c assez clair.....

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2017
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2017
    Messages : 16
    Points : 9
    Points
    9
    Par défaut
    Oui c'est très clair, Wallace, merci.

    J'ai ma solution. En fait j'en ai même deux.

    J'ai ma classe cl_st_MethodesPartagees que vous connaissez déjà où je déclare un random Aleatoire.

    J'ai aussi une classe statique Constantes où je déclare un random Alea (forcément non const, j'aime les paradoxes...)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    public static class Cl_St_MethodesPartagees
     
        {          
            public static Random Aleatoire ;
    //blabla
    }
     
    public static class Constantes
        {
           public static Random Alea ;
            public const string fichierAnimauxTxt = @"c:\animaux.txt";
            public const string fichierClimatTxt = @"c:\climat.txt";
            public const string fichierLogSession= @"c:\logSessions.txt";
            public const string wikiLapin = @"https://fr.wikipedia.org/wiki/Lapin";
            public const string wikiChien = @"https://fr.wikipedia.org/wiki/Chien";
        }
    J'ai une classe statique appelée au lancement du programme. C'est là que j'initialise ces random:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    public static  class cl_st_LancementPrg
     
        {
     public static Environnement LancerPrg()
            {   ParametrerConsole();
                InitialiserFichierLogSession();
                CreerUser();
                InitialiserRandomAlea();
                InitialiserRandomAleatoire();
     
               Environnement env = InstancierEnv();
                return env;
            }
     
           //blabla def des méthodes
     
     
            private static void InitialiserRandomAlea()
            {
                Constantes.Alea = new Random();
            }
            private static void InitialiserRandomAleatoire()
            {
                Cl_St_MethodesPartagees.Aleatoire = new Random();
            }
     
        }
    Cela tourne bien.

    En bonne logique Poo, si je comprends bien, c'est la solution classe Constantes que je dois privilégier ?

  7. #7
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    Citation Envoyé par jp2popu Voir le message
    Mais je ne comprends toujours pas pourquoi initialiser en succession rapide des new Random() les fait générer des nombres identiques ? Quelque chose m'échappe...
    un ordinateur ne sait pas faire quelque chose d'aléatoire
    pour faire du pseudo aléatoire, soit ca se base sur des infos matérielles, soit ca génère une chaine de nombre qui est mélangée
    enfin j'ai pas regardé en détail et récemment, mais c'est déterministe

    plus d'infos par là je pense :
    https://en.wikipedia.org/wiki/Pseudo...mber_generator

    les processeurs quantiques pourraient faire du vrai random à priori
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2017
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2017
    Messages : 16
    Points : 9
    Points
    9
    Par défaut
    Merci pour votre aide. J'ai bien avancé dans ma compréhension.

    Je peux marquer ce fil comme parfaitement résolu.


    PS pour Pol63, pas besoin d'aller sur wiki, on trouve tout ici.

    J'ai trouvé cet excellent article de Yahiko : http://yahiko.developpez.com/tutorie...bre-aleatoire/

    Vraiment très instructif. Merci à lui pour ce travail.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 10
    Dernier message: 19/01/2012, 12h56
  2. défaut des fonctions de génération de nombres aléatoire type rand()
    Par Christophe30 dans le forum Langages de programmation
    Réponses: 3
    Dernier message: 17/02/2008, 20h21
  3. Génération de nombre aléatoires
    Par rebaudo dans le forum Smalltalk
    Réponses: 1
    Dernier message: 29/11/2007, 12h54
  4. Réponses: 4
    Dernier message: 12/09/2006, 16h42
  5. recherche algo de génération de nombre aléatoire
    Par Pascale38 dans le forum MFC
    Réponses: 2
    Dernier message: 26/01/2004, 14h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo