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 :

Fonction aléatoire, une fois pour toute ...


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 15
    Points : 6
    Points
    6
    Par défaut Fonction aléatoire, une fois pour toute ...
    Bonjour,

    Je sais que cette question à été traité des centaines de fois sur les forums de programmation.
    Cependant, aucune fonction de random que j'ai pu trouver n'est fiable.

    Je m'explique :

    Celle que j'utilise (entre autre) est la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
         long nomdelavariable = 10;
         const long MAX = 3000, MIN = 1;
     
         srand(time(NULL));
         nomdelavariable = (rand() % (MAX - MIN + 1)) + MIN;
    Elle génère effectivement un nombre aléatoire MAIS, si par exemple elle génère le nombre 2200, si je ferme le programme et le réxécute, le nombre aléatoire sera 2210, si je ferme et le relance 2220 et ainsi de suite de 10 en 10 (suivant le laps de temps pour relancer le programme). Je sais que un tel algorithme se base sur l'horloge interne du PC, c'est donc par conséquent logique.

    Mais travaillant dans la programmation de jeu video ou la fonction aléatoire est primordiale, j'ai besoin d'une fonction qui soit vraiment aléatoire (dans les grands jeux video, on va pas me dire qu'ils utilisent une fonction aussi buggé que ça tout de même ?

    J'ai fait un test en plus dans le programme avec une boucle FOR qui génère un nombre aléatoire puis l'affiche, et bien il affiche toujours le même ...

    Si quelqu'un me montre une fonction aléatoire optimale je le remerci d'avance.
    Merci de m'avoir lu.

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour et bienvenu,
    1/Effectivement, si tu initialises avec une graine légèrement différentes, srand semble avoir un comportement prédictif. Mais posons la question autrement: ton jeux va se lancer toutes les 10 secondes?
    2/Pour une vrai fonction aléatoire, le logiciel ne sait pas faire! Il faut forcément passer par du matériel!
    3/Mais pour ne pas te décourager, tu peux utiliser des générateurs ne nombre pseudo aléatoires.
    4/Il existe un boost.Random.

  3. #3
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    On peut connaitre le compilateur? J'ai le vague souvenir qu'il y en avait un (Borland?) pour lequel le premier resultat de rand() etait la valeur passee a srand(), ce qui expliquerait le comportement que tu vois. Ce n'est pas le cas des bibliotheques que je connais.

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    1/Effectivement, si tu initialises avec une graine légèrement différentes, srand semble avoir un comportement prédictif. Mais posons la question autrement: ton jeux va se lancer toutes les 10 secondes?
    Normalement, même si la graine change très peu, le générateur aléatoire change beaucoup; c'est tout l'intérêt du truc.

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 15
    Points : 6
    Points
    6
    Par défaut
    Je ne sais pas quel compilateur j'utilise, cependant je travail sous dev c++ telechargé sur telecharger.com ....

    Ceci dit je viens de créer ma propre fonction random (a partir de srand), et cela génère un nombre TOTALEMENT aleatoire (et ce même si j'utilise un mauvais compilateur). Je vous invite à la tester (je pense que ça servira à des personnes qui avaient le même soucis que moi) :

    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
    29
    30
    31
    32
    33
    34
    35
    #include <stdio.h>
    #include <stdlib.h>
    #include <dos.h>
    #include <time.h>
     
    int fonctionaleatoire()
    {
    int nombre, i;
    int tableau[51]; // Taille de la liste à générer
    long nomdelavariable = 0;
     
        for (i=0;i<=50;i++) //Le i doit correspondre au nombre de case du tableau
            {
                const long MAX = 100, MIN = 1; //Tranche de nombre genere
                nomdelavariable = (rand() % (MAX - MIN + 1)) + MIN;
                tableau[i]=nomdelavariable; //Chaque nombre genere s'inscrit dans les cases du tableau
            }
            //On genere un autre aleatoire representant les cases du tableau pour choisir un nombre
            //au hasard parmis la liste genere.
            const long MAX = 50, MIN = 1;
            nomdelavariable = (rand() % (MAX - MIN + 1)) + MIN;
            //le nombre prends la valeur de la case du tableau seelectionner
            nombre=tableau[nomdelavariable]; 
            return nombre;
    }
     
    main ()
    {
            int nombrealeatoire;
            srand(time(NULL));
            nombrealeatoire=fonctionaleatoire();
            printf("%d\n", nombrealeatoire);
     
            system("pause");
    }
    En gros je genere une liste de 51 nombres aleatoires (seul le premier géneré bug et va de 10 en 10) que j'insère dans un tableau du même nombre de case

    Je génère ensuite un autre nombre aléatoire compris entre 1 et 51 (le nombre de case du tableau, sans prendre l'indice 0 qui est "bugger").

    Ce deuxième nombre aléatoire represente un indice aléatoire du premier tableau du quel je prends la valeur.

    J'ai fais de multiple test et cela est completement aléatoire.

    Voilà qu'en pensez vous ?

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 581
    Points
    41 581
    Par défaut
    Disons que...
    Ça me fait penser à ça.

    Si tu veux un truc plus aléatoire que rand(), ne fais pas les choses à moitié, utilise la CryptoAPI et sa fonction CryptGenRandom(). Là au moins, tu auras des vraies données bien aléatoires sans de casser la tête avec un algo bizarroïde...

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 15
    Points : 6
    Points
    6
    Par défaut
    Pourrais tu me donner un lien qui montre une exemple de cette fonction stp ?

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Normalement, même si la graine change très peu, le générateur aléatoire change beaucoup; c'est tout l'intérêt du truc.
    Ben, je pensais comme toi, mais j'ai essayé ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int main()
    {
         const long MAX = 3000, MIN = 1;
         srand(time(NULL));
          std::cout<<(rand() % (MAX - MIN + 1)) + MIN<<std::endl;
       return 0;
    }
    Et, en le lançant à qqs secondes d'intervalles avec VCExpress, j'obtiens une jolie suite espacée de 3 en 3 environ.

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Nothingness0x Voir le message
    Pourrais tu me donner un lien qui montre une exemple de cette fonction stp ?
    MSDN est ton ami

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 581
    Points
    41 581
    Par défaut
    ET en affichant le résultat d'un second appel à rand() ? Comme dit plus haut, certaines plate-formes ne gèrent pas toujours au mieux le premier appel qui suit le srand()...

  11. #11
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    ET en affichant le résultat d'un second appel à rand() ? Comme dit plus haut, certaines plate-formes ne gèrent pas toujours au mieux le premier appel qui suit le srand()...
    Effectivement, le second appel prend un air plus aléatoire. Enfin, sur wiki, ils recommandent l'utilisation de rand_s.

  12. #12
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 15
    Points : 6
    Points
    6
    Par défaut
    le CryptoAPI et sa fonction CryptGenRandom(). c'est en fait la fonction rand_s dont tu parle ?? Si tel est le cas j'ai essayé celle sur le lien http://msdn.microsoft.com/en-us/libr...a8(VS.80).aspx
    et elle ne marche pas .

  13. #13
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Ca veut dire quoi 'elle marche pas'?

  14. #14
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 15
    Points : 6
    Points
    6
    Par défaut
    ca veut dire qu'il ne reconnait pas le "rand_s" undecleared first use in this function.

    CryptoAPI et sa fonction CryptGenRandom() = rand_s ?

    J'aimerais au moin avoir cette confirmation même si vous ne me donnez pas de lien précis , au moins je serais sur de ce que je dois chercher.

    Merci.

  15. #15
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    CryptGenRandom() n'a rien à voir avec rand_s()

    rand_s() est dans Run-Time Library et génère des nombres pseudo aléatoires.
    CryptGenRandom() est dans la CryptoApi et génère des nombres cryptographiquement aléatoires.

  16. #16
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Nothingness0x Voir le message
    ca veut dire qu'il ne reconnait pas le "rand_s" undecleared first use in this function.
    rand_s nécessite Visual. Il faut définir _CRT_RAND_S comme indiqué sur le site MSDN: ceci fonctionne parfaitement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #define _CRT_RAND_S
    #include <stdlib.h>
    #include<iostream>
     
    int main()
    {
         const long MAX = 3000, MIN = 1;
         unsigned int l_uiRand(0);
         rand_s(&l_uiRand);
          std::cout<<(l_uiRand % (MAX - MIN + 1)) + MIN<<std::endl;
       return 0;
    }
    Après, il se peut que ce soit un problème d'ordre dans les includes. Tu peux alors définir _CRT_RAND_S dans les options du projet.

    Citation Envoyé par Nothingness0x Voir le message
    CryptoAPI et sa fonction CryptGenRandom() = rand_s ?
    J'aimerais au moin avoir cette confirmation même si vous ne me donnez pas de lien précis , au moins je serais sur de ce que je dois chercher.
    Merci.
    As tu lus les liens fournis précédemment: celui sur rand_s et celui sur Wiki:
    Citation Envoyé par wiki
    Microsoft-provided cryptography providers share the same implementation of CryptGenRandom, currently based on an internal function called RtlGenRandom.
    Citation Envoyé par wiki
    In fact, the new Whidbey CRT function, rand_s calls RtlGenRandom
    Citation Envoyé par MSDN
    rand_s depends on the RtlGenRandom API, which is only available in Windows XP and later.

  17. #17
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 15
    Points : 6
    Points
    6
    Par défaut
    da'ccord , ben apparement CryptGenRandom() est ultra fiable, je demande simplement si vous connaissez un lien ou je peu voir la syntaxe pour l'utiliser, parce que j'ai cherché sans succès.

  18. #18
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 581
    Points
    41 581
    Par défaut
    CryptAcquireContext() au début, CryptGenRandom() tant que tu en as besoin, CryptReleaseContext() à la fin...

  19. #19
    Futur Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 15
    Points : 6
    Points
    6
    Par défaut
    Ok , mais quel librairie déclarer au début ? Et puis je suis sur que la syntaxe ne se limite pas à "CryptGenRandom() "

  20. #20
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 581
    Points
    41 581
    Par défaut


    ou MSDN.

Discussions similaires

  1. Modifier le PATH une fois pour toute
    Par elitost dans le forum Linux
    Réponses: 8
    Dernier message: 06/09/2009, 13h21
  2. expliquer variable une fois pour tout le code
    Par mumu64 dans le forum IHM
    Réponses: 4
    Dernier message: 01/08/2008, 12h08
  3. Chargement de mes collections une fois pour toutes
    Par lbrun79 dans le forum Langage
    Réponses: 2
    Dernier message: 14/11/2007, 13h17
  4. Réponses: 4
    Dernier message: 06/04/2007, 13h48
  5. declarer une variable une fois pour toute
    Par rober dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 07/11/2006, 18h35

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