Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 12 sur 12
  1. #1

    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 : -2
    Points
    -2

    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 :
    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é Sénior
    Inscrit en
    août 2006
    Messages
    3 561
    Détails du profil
    Informations forums :
    Inscription : août 2006
    Messages : 3 561
    Points : 4 569
    Points
    4 569

    Par défaut

    Joa,

    Quand tu fais ceci :
    Code :
    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 !
    Il court en ce moment une espèce de grippe, mais elle ne court pas très vite, car on peut l'attraper sans courir.

  3. #3
    Membre éprouvé

    Inscrit en
    août 2007
    Messages
    174
    Détails du profil
    Informations forums :
    Inscription : août 2007
    Messages : 174
    Points : 429
    Points
    429

    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

    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 : -2
    Points
    -2

    Par défaut

    Citation Envoyé par droggo Voir le message
    Joa,

    Quand tu fais ceci :
    Code :
    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

    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 : -2
    Points
    -2

    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 éprouvé

    Inscrit en
    août 2007
    Messages
    174
    Détails du profil
    Informations forums :
    Inscription : août 2007
    Messages : 174
    Points : 429
    Points
    429

    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 :
    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
    Modérateur

    Homme Profil pro Cyrille
    Network programmer
    Inscrit en
    juin 2010
    Messages
    2 162
    Détails du profil
    Informations personnelles :
    Nom : Homme Cyrille
    Âge : 27
    Localisation : France

    Informations professionnelles :
    Activité : Network programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 2 162
    Points : 5 594
    Points
    5 594

    Par défaut

    Bonjour,

    le problème c'est que le srand pour initialiser le seed doit être fait une fois par programme.

  8. #8

    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 : -2
    Points
    -2

    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 :
    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

    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 : -2
    Points
    -2

    Par défaut

    auriez-vous d'autre idée d'algo plus simple qui fasse la même chose ?

  10. #10
    Expert Confirmé Sénior


    Homme Profil pro Denis
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    4 996
    Détails du profil
    Informations personnelles :
    Nom : Homme Denis
    Âge : 21
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 4 996
    Points : 14 895
    Points
    14 895

    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 :
    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 Confirmé Sénior

    Homme Profil pro Patrick Gonord
    Enseignant Chercheur
    Inscrit en
    juin 2005
    Messages
    5 664
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrick Gonord
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2005
    Messages : 5 664
    Points : 13 489
    Points
    13 489

    Par défaut

    Peut être comme ceci :
    Code :
    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];
    }

  12. #12

    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 : -2
    Points
    -2

    Par défaut

    Citation Envoyé par diogene Voir le message
    Peut être comme ceci :
    Code :
    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 !=)

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •