Précédent   Forum du club des développeurs et IT Pro > C et C++ > C > Débuter
Débuter Forum d'entraide pour débuter en langage C. Avant de poster -> FAQ C
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 04/05/2012, 15h17   #1
kvin1
 
Homme
Étudiant
Inscription : 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 : -1
Points : -1
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
}
kvin1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2012, 15h39   #2
droggo
Expert Confirmé
 
Inscription : août 2006
Messages : 3 413
Détails du profil
Informations forums :
Inscription : août 2006
Messages : 3 413
Points : 3 768
Points : 3 768
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.
droggo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2012, 15h48   #3
pythéas
Membre éclairé
 
Inscription : août 2007
Messages : 174
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 174
Points : 393
Points : 393
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.
pythéas est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2012, 15h55   #4
kvin1
 
Homme
Étudiant
Inscription : 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 : -1
Points : -1
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
kvin1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2012, 16h07   #5
kvin1
 
Homme
Étudiant
Inscription : 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 : -1
Points : -1
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...
kvin1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2012, 16h25   #6
pythéas
Membre éclairé
 
Inscription : août 2007
Messages : 174
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 174
Points : 393
Points : 393
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/
pythéas est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2012, 16h33   #7
Bousk
Modérateur
 
Homme Cyrille
Network programmer
Inscription : juin 2010
Messages : 1 535
Détails du profil
Informations personnelles :
Nom : Homme Cyrille
Âge : 25
Localisation : France

Informations professionnelles :
Activité : Network programmer

Informations forums :
Inscription : juin 2010
Messages : 1 535
Points : 4 059
Points : 4 059
Bonjour,

le problème c'est que le srand pour initialiser le seed doit être fait une fois par programme.
Bousk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2012, 16h40   #8
kvin1
 
Homme
Étudiant
Inscription : 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 : -1
Points : -1
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!
kvin1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2012, 16h41   #9
kvin1
 
Homme
Étudiant
Inscription : 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 : -1
Points : -1
auriez-vous d'autre idée d'algo plus simple qui fasse la même chose ?
kvin1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2012, 18h40   #10
Neckara
Rédacteur
 
Avatar de Neckara
 
Homme Denis
Étudiant
Inscription : décembre 2011
Messages : 2 529
Détails du profil
Informations personnelles :
Nom : Homme Denis
Localisation : France, Loire (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : décembre 2011
Messages : 2 529
Points : 6 801
Points : 6 801
Envoyer un message via MSN à Neckara Envoyer un message via Skype™ à Neckara
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.
__________________
Recherche devs C++ motivés et sérieux pour Last Dungeon.

Chaîne Youtube : Vidéos

Ma page DVP : http://neckara.developpez.com/
Neckara est actuellement connecté   Envoyer un message privé Réponse avec citation 10
Vieux 04/05/2012, 18h53   #11
diogene
Responsable Modération
 
Avatar de diogene
 
Homme Patrick Gonord
Enseignant Chercheur
Inscription : juin 2005
Messages : 5 427
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 427
Points : 12 914
Points : 12 914
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];
}
__________________
Publication : Concepts en C

Mon avatar : Glenn Gould

--------------------------------------------------------------------------
Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !
diogene est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 05/05/2012, 13h06   #12
kvin1
 
Homme
Étudiant
Inscription : 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 : -1
Points : -1
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 !=)
kvin1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 11h30.


 
 
 
 
Partenaires

Hébergement Web