Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2513 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Rand() me renvoit une fois sur deux la même valeur

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Rand() me renvoit une fois sur deux la même valeur

n°2108272
Terminapor
I'll see you rise.
Posté le 27-10-2011 à 00:31:28  profilanswer
 

Bonsoir :hello:  
 
J'ai un sacré problème avec la fonction rand(), la valeur de retour est une sur deux sur la même, en gros le résultat ressemble à ça :  
12.485366374706
0.14142277291177
12.485366374706
0.14142277291177
12.485366374706
0.14142277291177
12.485366374706
0.14142277291177
12.485366374706
0.14142277291177
 
J'comprends vraiment pas, le rand() est bidon où j'm'en sert mal ? :heink:  
 
mes fonctions pour avoir un nombre aléatoire :
 

Code :
  1. float random(float l,float h)
  2. {
  3. return rand()/(float)(RAND_MAX) * (h-1)+l;
  4. }
  5. int irandom(int l,int h)
  6. {
  7. return rand()%(h-l+1) + l;
  8. }


 
Et lors de l'initialisation du programme, j'utilise srand(time(NULL)) pour le seed.
J'ai tenté avec la SFML d'utiliser sf::Randomizer, mais j'avais pas de bon résultats non plus :sisicaivrai:
 
Quelqu'un aurait une idée ? Le boost::random fonctionne mieux ?
 
Merci à vous et bonne soirée/nuit :D  


---------------
Perhaps you don't deserve to breathe
mood
Publicité
Posté le 27-10-2011 à 00:31:28  profilanswer
 

n°2108275
WiiDS
20 titres en GC, 0 abandon, 0 DQ
Posté le 27-10-2011 à 04:58:14  profilanswer
 

On peut avoir le code source complet de ton truc ? :o


Message édité par WiiDS le 27-10-2011 à 05:04:01

---------------
"I can cry like Roger. It's just a shame I can't play like him" - Andy Murray, 2010
n°2108434
Terminapor
I'll see you rise.
Posté le 27-10-2011 à 18:37:49  profilanswer
 

Oui m'sieur :D
 
C'est un code lua qui appelle la fonction :  
 

Code :
  1. function strike()
  2. local e;
  3. for i=0,get_map_width()/16 do
  4. local r = irandom(0,5);
  5.   if (r==0) then
  6.    e = create_event(i*16+random(-20,20),irandom(-600,-10),"Events/MON/Lavarock" );
  7.    perform_event_function(e,"always_explode" );
  8.   end
  9. end
  10. end


 
Donc le principe c'est tout bête, lorsque cette fonction est appelée, elle est supposée créé plein de bouboules qui tombe au hasard sur la carte (la fonction qui créé un objet s'appelle create_event(x,y,fichier_lua)
 
Donc en gros, ce code me permettait normalement d'avoir une chance sur 5 d'avoir une pierre qui tombe, mais le 'irandom(0,5)' me renvoyait certaine fois plein de '0', du coups j'avais une belle tombée de pierres bien alignée..
 
J'ai réussi à palier ça en recréant une seed à chaque pas de i, via randomize(i), qui appelle cette fonction c++ :  

Code :
  1. void randomize(unsigned int s)
  2. {
  3. srand(time(NULL)+s);
  4. }


 
Et à la fin de la boucle, un randomize(0) pour remettre à time(NULL), mais j'ai entendu dire que régénérer une seed, c'était pas cool.. Mais ça semble mieux fonctionner :D


---------------
Perhaps you don't deserve to breathe
n°2108446
WiiDS
20 titres en GC, 0 abandon, 0 DQ
Posté le 27-10-2011 à 19:49:24  profilanswer
 

Hmm. Théoriquement t'es pas censé exécuter srand plus d'une fois.
 
Après désolé mais je vois pas trop ce qui pourrait te causer problème dans ton cas :D


---------------
"I can cry like Roger. It's just a shame I can't play like him" - Andy Murray, 2010
n°2108451
gilou
Modérateur
Modzilla
Posté le 27-10-2011 à 20:24:40  profilanswer
 

Je connais pas lua, mais si ça crée des threads avec create_event, alors dans chaque thread, les appels a rand vont générer la même séquence, donc il est logique que tu voies les mêmes valeurs.
Si tu veux des valeurs différentes pour chaque thread, lors des appels à rand, il faudrait seeder avec des valeurs différentes dans chaque thread (en utilisant le thread-id ou autre)
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2108465
Terminapor
I'll see you rise.
Posté le 27-10-2011 à 21:54:59  profilanswer
 

create_event est une fonction que j'ai faite, qui permet d'instancier une class c++ "EventClass"qui contient un lua_State, enregister celle-ci dans ma liste d'objet à traiter et elle renvoit son indentifier (sa "position" dans une std::map<int,EventClass*> ).
Mon programme n'utilise que 2 Threads : Un qui gère les packets en réseau (réception), un autre qui fait tout le reste (exécuter les fonctions lua qu'il faut, dessiner à l'écran, bref tout le bordel du moteur)
 
Donc normalement tout mon moteur n'utilise qu'une seul seed, celle qui est définie au début par "srand(time(NULL))", je m'y prend mal du coups?


---------------
Perhaps you don't deserve to breathe
n°2108471
gilou
Modérateur
Modzilla
Posté le 27-10-2011 à 22:25:05  profilanswer
 

Apparemment non, mais tout se passe comme si rand une fois appelée était déchargée de la mémoire et perdait son état (rand est une fonction qui doit avoir une variable statique quelque part, ce qui lui permet de ne pas renvoyer la même valeur à chaque appel).
Car rand est une fonction détermiste: pour une même valeur de seed, elle renvoie toujours la même suite de nombres aléatoires.
On dirait donc qu'a chaque fois, elle revoit la même seed, ou qu'elle voit pas sa variable de dernier état.
Si tu peux utiliser rand_r et faire exister la variable d'état dans ton code au lieu que ce soit une variable statique à la fonction rand, cela améliorera peut être les choses.
A+,


Message édité par gilou le 27-10-2011 à 22:34:35

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2108495
Terminapor
I'll see you rise.
Posté le 28-10-2011 à 02:14:24  profilanswer
 

Hm, rand_r() marchait pas chez moi, (undeclared alors que j'avais bien le #include<stdlibs> ) du coups j'ai choppé la fonction sur le net :

 
Code :
  1. int
  2.     rand_r (unsigned int *seed)
  3.     {
  4.       unsigned int next = *seed;
  5.       int result;
  6.       next *= 1103515245;
  7.       next += 12345;
  8.       result = (unsigned int) (next / 65536) % 2048;
  9.       next *= 1103515245;
  10.       next += 12345;
  11.       result <<= 10;
  12.       result ^= (unsigned int) (next / 65536) % 1024;
  13.       next *= 1103515245;
  14.       next += 12345;
  15.       result <<= 10;
  16.       result ^= (unsigned int) (next / 65536) % 1024;
  17.       *seed = next;
  18.       return result;
  19.     }
 

Et ça marche bien apparemment, merci :D

 

edit : Par contre je me demande, les diverses opérations appliqués à result et next sont faites au hasard, où y'a une logique à tout ça :??:

Message cité 1 fois
Message édité par Terminapor le 28-10-2011 à 02:19:54

---------------
Perhaps you don't deserve to breathe
n°2111036
Lightness1​024
Posté le 11-11-2011 à 23:18:47  profilanswer
 

oui les papiers de recherche sont accessibles. il existe bcp d'autres fonctions de pseudo random. il est admis de nos jour que mersenne twister devrait etre utilisé de préférence. (eg defaut dans boost)
la fonction que tu utilises ci dessus est une variation du rand implémenté dans la libc. en tout cas tu as les memes nombres.
j'aurais dit que ca aurait pu ressembler a un rand taus (taus88) mais tu n'as pas 3 variables next differentes donc ca ne doit pas etre ca.


---------------
http://projets.6mablog.com/
n°2111074
leonhard
Posté le 12-11-2011 à 10:54:56  profilanswer
 

Terminapor a écrit :

Hm, rand_r() marchait pas chez moi, (undeclared alors que j'avais bien le #include<stdlibs> ) du coups j'ai choppé la fonction sur le net :
[...]
 
Et ça marche bien apparemment, merci :D
 
edit : Par contre je me demande, les diverses opérations appliqués à result et next sont faites au hasard, où y'a une logique à tout ça :??:


 
Quand quelqu'un pose une question sur les générateur aléatoires et que je suis d'humeur taquine, je conseille de se référer au livre "The Art Of Computer Programming" de Donald Knuth, plus particulièrement le volume 2 (Semi-numerical algorithms)

mood
Publicité
Posté le 12-11-2011 à 10:54:56  profilanswer
 

n°2111156
Terminapor
I'll see you rise.
Posté le 12-11-2011 à 22:04:50  profilanswer
 

Je demandais juste ça comme ça, je veux pas écrire moi-même de fonctions aléatoire :D
 
Merci pour l'info quand même :jap:


---------------
Perhaps you don't deserve to breathe

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Rand() me renvoit une fois sur deux la même valeur

 

Sujets relatifs
[Graphe] Affecter une même valeur au nœuds reliés par un cheminretour de valeur en c
[PHP/MYSQL] comment connaitre la valeur d'un id autoincrementSécurité d'un système de points avec une valeur monétaire
[RESOLU] JQuery appel ajax, récuperer la valeur d'une selectboxRécupérer valeur d'un select en fonction de son id
recréer un tableau après modification d'une valeur[DOS] Récupération valeur dans un fichier
Comment récupérer la valeur choisie dans <select> ou <option>?[ACCESS 2007] Dupliquer des enregistrements selon la valeur d'un champ
Plus de sujets relatifs à : Rand() me renvoit une fois sur deux la même valeur


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR