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 :

probleme fonction rand()


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2012
    Messages : 9
    Points : 0
    Points
    0
    Par défaut probleme fonction rand()
    Bonjour,

    j'aimerais un peu d'aide sur une fonction en c que j'essaie de coder,
    en gros :

    j'ai 4 choix possibles et chaque choix peut être a "0" ou "1"

    je dois faire une fonction qui choisit aléatoirement(enfin le plus possible bien-sur) un des choix parmi ceux qui sont a 1

    mon idée était de faire un rand() basé sur le time() pour générer un chiffre entre 1 et 4 puis tester si le choix est bien a la valeur "1"
    mai problème ! ça ne marche pas!
    je pense que la cause est que le rand marche sur la base des seconde et donc que la fonction boucle des centaines de fois(pour une même seconde) avant que le rand() génère un nouveau chiffre
    ma solution a été de mettre un délai sleep(1000) et cela marche mai mon programme met parfois plus 30 a utiliser cette fonction lol

    j'ai donc besoin d'une autre solution la plus simple possible pour pouvoir optimiser mon code un maximum

    merci a vous!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int choi_position(int a, int b, int c, int d)
    {
    int t[4];
    int i;
     
    t[0]=a;t[1]=b;t[2]=c;t[3]=d;
    srand(time(NULL));
    i=rand()%4;
    Sleep(1000);//pause obligatoire pour ne pas boucler sur la meme seconde
    if(t[i]==1)
    return i+1;//retourne le choix qui est fait ex: 1,2,3,4
    else
    choi_position(a,b,c,d);//boucle si le choix fait n'est au final pas valide
    }

  2. #2
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 941
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 941
    Points : 5 652
    Points
    5 652
    Par défaut
    Joa,

    Quand tu fais ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    choi_position(a,b,c,d);//boucle si le choix fait n'est au final pas valide
    ce n'est pas une boucle comme tu l'écris, mais un appel récursif !
    Si les cons volaient, il ferait nuit à midi.

  3. #3
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2007
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 178
    Points : 451
    Points
    451
    Par défaut
    Salut,

    Après un coup d'oeil rapide :

    Pour ce qui est d'"optimiser (t)on code un maximum", je ne sais pas trop d'autant que la manière de faire me semble assez compliquée : "faire le tirage d'abord puis tester, en passant par les cases d'un tableau pas forcément indispensable, et éventuellement faire un appel récursif", essaye de voir si tu ne peux pas concevoir ton algo différement.

    En attendant, pour une "solution la plus simple possible" tu peux déjà sortir srand(time(NULL)); de la fonction et le mettre avant son premier appel ça devrait au moins éviter les boucles infines.

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2012
    Messages : 9
    Points : 0
    Points
    0
    Par défaut
    Citation Envoyé par droggo Voir le message
    Joa,

    Quand tu fais ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    choi_position(a,b,c,d);//boucle si le choix fait n'est au final pas valide
    ce n'est pas une boucle comme tu l'écris, mais un appel récursif !
    C'est vrai =) j'ai écris les commentaires a la va-vite mai bon c'est juste pour me rappeler le fonctionnement

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2012
    Messages : 9
    Points : 0
    Points
    0
    Par défaut
    Citation Envoyé par pythéas Voir le message
    Salut,

    Après un coup d'oeil rapide :

    Pour ce qui est d'"optimiser (t)on code un maximum", je ne sais pas trop d'autant que la manière de faire me semble assez compliquée : "faire le tirage d'abord puis tester, en passant par les cases d'un tableau pas forcément indispensable, et éventuellement faire un appel récursif", essaye de voir si tu ne peux pas concevoir ton algo différement.

    En attendant, pour une "solution la plus simple possible" tu peux déjà sortir srand(time(NULL)); de la fonction et le mettre avant son premier appel ça devrait au moins éviter les boucles infines.
    salut et merci d'avoir répondu!

    je suis d'accord avec toi que mon algo est pas top c'est justement ça mon problème mais je ne trouve pas d'autres manières de le faire
    il faudrait premièrement ne garder que les choix valide puis faire un rand() seulement pour ces choix la ce qui m'éviterais de devoir utiliser l’appel récursif
    sauf que je n'ai aucune idée de comment le mettre en œuvre en c
    ou carrément utiliser une autre façon que le rand() mai je suis très loin d’être un expert ! help !

    pour ce qui est de sortir le srand(time(NULL)); je l'ai fait et l'ai placer juste avant le premier appel a cette fonction mai aucun changement d’ailleurs je ne comprends pas pourquoi cela devrait changer quelque chose...

  6. #6
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2007
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 178
    Points : 451
    Points
    451
    Par défaut
    Désolé, je n'ai pas trop le temps de regarder plus avant, simplement si tu ré-initialises à la même seconde tu obtiendras le même résultat sur le rand suivant. Sortir le srand et le faire (une seule fois) avant permet au moins d'éviter ce problème.

    Du coup je suis étonné que ça ne change rien chez toi et j'ai fais un test rapide en tapant simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main(void)
    {
      srand(time(NULL));
      printf ("le res : %d\n",choi_position(0, 1, 0, 1));
    }
    J'ai laissé ta fonction telle quelle (en enlevant seulement srand -et sleep par la même occasion-) et là plus de boucle infinie.

    PS : ce topic devrait t'apporter un éclairage plus intéressant sur rand : http://www.developpez.net/forums/d12...-aleatoires-c/

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 113
    Points : 32 958
    Points
    32 958
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    le problème c'est que le srand pour initialiser le seed doit être fait une fois par programme.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2012
    Messages : 9
    Points : 0
    Points
    0
    Par défaut
    Citation Envoyé par pythéas Voir le message
    Désolé, je n'ai pas trop le temps de regarder plus avant, simplement si tu ré-initialises à la même seconde tu obtiendras le même résultat sur le rand suivant. Sortir le srand et le faire (une seule fois) avant permet au moins d'éviter ce problème.

    Du coup je suis étonné que ça ne change rien chez toi et j'ai fais un test rapide en tapant simplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main(void)
    {
      srand(time(NULL));
      printf ("le res : %d\n",choi_position(0, 1, 0, 1));
    }
    J'ai laissé ta fonction telle quelle (en enlevant seulement srand -et sleep par la même occasion-) et là plus de boucle infinie.

    PS : ce topic devrait t'apporter un éclairage plus intéressant sur rand : http://www.developpez.net/forums/d12...-aleatoires-c/
    alors autant pour moi j'avais simplement oublier de supprimer le sleep() lol
    et c'est effectivement mieux j'ai mit le srand() carrément au début du main() et plus de problème merci pour l'aide!

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2012
    Messages : 9
    Points : 0
    Points
    0
    Par défaut
    auriez-vous d'autre idée d'algo plus simple qui fasse la même chose ?

  10. #10
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 209
    Points
    23 209
    Par défaut
    Tes possibilités sont présentes ou non, tu n'a donc besoin que d'un bit et non d'un int complet.
    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
     
    #define Zero 1
    #define Un 2
    #define Deux 4
    #define Trois 8
     
    fonction(Zero | Deux); //valeurs possibles : 0 et 2
     
    unsigned char fonction(unsigned long int valeursPossibles)
         unsigned char resultat[sizeof(unsigned long int)];//la taille des long int ne varie pas selon les compilateur?
         unsigned char i = 0;
         unsigned char j = 0;
         while(valeursPossibles != 0)
         {
               if(valeursPossibles%2)
               {
                   resultat[j] = i;
                   j++;
               }
                valeursPossibles <<= 1;
                i++;
          }
          return resultat[rand()%j];
    }
    Sachant que ce n'est pas tout à fait exact vu qu'il faudrait théoriquement faire partie entière de rand()/RANDMAX * j; pour avoir une réelle équiprobabilité des résultats.

  11. #11
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Peut être comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int choi_position(int a, int b, int c, int d)
    {
    int t[4];
    int n = 0;
    if(a==1)t[n++]= 1 ;
    if(b==1)t[n++]= 2 ;
    if(c==1)t[n++]= 3 ;
    if(d==1)t[n++]= 4 ;
    return n==0 ? 0 : t[rand()%n];
    }
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  12. #12
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2012
    Messages : 9
    Points : 0
    Points
    0
    Par défaut
    Citation Envoyé par diogene Voir le message
    Peut être comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int choi_position(int a, int b, int c, int d)
    {
    int t[4];
    int n = 0;
    if(a==1)t[n++]= 1 ;
    if(b==1)t[n++]= 2 ;
    if(c==1)t[n++]= 3 ;
    if(d==1)t[n++]= 4 ;
    return n==0 ? 0 : t[rand()%n];
    }

    Parfait !!!
    j'aurais jamais penser au "t[n++]"
    merci !=)

Discussions similaires

  1. [XSL]Probleme fonction recursive
    Par Le-Cortex dans le forum XSL/XSLT/XPATH
    Réponses: 9
    Dernier message: 12/12/2005, 16h10
  2. [Mail] Probleme fonction mail()
    Par tissot dans le forum Langage
    Réponses: 1
    Dernier message: 14/11/2005, 13h55
  3. problème fonctions callback
    Par youp_db dans le forum GTK+ avec C & C++
    Réponses: 1
    Dernier message: 02/10/2005, 15h47
  4. probleme fonction gethostbyname
    Par oclone dans le forum Développement
    Réponses: 6
    Dernier message: 14/04/2005, 11h31
  5. probleme fonction syntaxe
    Par gIch dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 28/02/2005, 10h52

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