p
u
b
l
i
c
i
t
é
publicité
  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 : 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é Sénior

    Inscrit en
    août 2006
    Messages
    3 623
    Détails du profil
    Informations forums :
    Inscription : août 2006
    Messages : 3 623
    Points : 4 768
    Points
    4 768

    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 !
    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
    176
    Détails du profil
    Informations forums :
    Inscription : août 2007
    Messages : 176
    Points : 430
    Points
    430

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

    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
    176
    Détails du profil
    Informations forums :
    Inscription : août 2007
    Messages : 176
    Points : 430
    Points
    430

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

    Homme Profil pro
    Network programmer
    Inscrit en
    juin 2010
    Messages
    2 699
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Network programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 2 699
    Points : 7 734
    Points
    7 734

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

    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

    Avatar de Neckara
    Homme Profil pro
    Étudiant
    Inscrit en
    décembre 2011
    Messages
    5 554
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2011
    Messages : 5 554
    Points : 16 422
    Points
    16 422

    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.
    On dit "chiffrer" pas "crypter" !

    On dit "bibliothèque" pas "librairie" !

    Ma page DVP : http://neckara.developpez.com/

  11. #11
    Expert Confirmé 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 : 14 018
    Points
    14 018

    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

    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 : 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, 15h10
  2. [Mail] Probleme fonction mail()
    Par tissot dans le forum Fonctions
    Réponses: 1
    Dernier message: 14/11/2005, 12h55
  3. problème fonctions callback
    Par youp_db dans le forum GTK+
    Réponses: 1
    Dernier message: 02/10/2005, 14h47
  4. probleme fonction gethostbyname
    Par oclone dans le forum Développement
    Réponses: 6
    Dernier message: 14/04/2005, 10h31
  5. probleme fonction syntaxe
    Par gIch dans le forum JavaScript
    Réponses: 8
    Dernier message: 28/02/2005, 09h52

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