[c] génération uniforme de nombres aléatoires
Résolu/Fermé
A voir également:
- [c] génération uniforme de nombres aléatoires
- Generation mot de passe - Télécharger - Sécurité
- Generation ryzen - Guide
- Code binaire des nombres - Guide
- Réinitialiser chromecast 1ere génération - Guide
- Nombres faciles - Télécharger - Outils professionnels
7 réponses
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 844
20 avril 2011 à 21:26
20 avril 2011 à 21:26
Bonjour,
Non, il n'y a absolument aucune raison que 0 soit restiué plus de fois.
En utilisant : 20.0*rand()/(RAND_MAX+1.0);
Il faudrait voir le programme en entier, peut-être une petite erreur ailleurs...
Non, il n'y a absolument aucune raison que 0 soit restiué plus de fois.
En utilisant : 20.0*rand()/(RAND_MAX+1.0);
Il faudrait voir le programme en entier, peut-être une petite erreur ailleurs...
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
20 avril 2011 à 16:29
20 avril 2011 à 16:29
Salut.
à ma connaissance il n'y a pas de raison que 0 sorte plus souvent.
à lire : https://linux.die.net/man/3/rand
Sinon, comme tu travail sous Linux, il existe un générateur de nombre aléatoire intégré qu'il est possible d'utiliser en lisant le fichier /dev/urand
https://linux.die.net/man/4/random
à ma connaissance il n'y a pas de raison que 0 sorte plus souvent.
à lire : https://linux.die.net/man/3/rand
Sinon, comme tu travail sous Linux, il existe un générateur de nombre aléatoire intégré qu'il est possible d'utiliser en lisant le fichier /dev/urand
https://linux.die.net/man/4/random
KX
Messages postés
16754
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 020
Modifié par KX le 20/04/2011 à 17:04
Modifié par KX le 20/04/2011 à 17:04
rand() est un entier inférieur à RAND_MAX, donc quand tu fais la division ça devient 0...
Pour que ça marche tu dois caster rand()
Remarque : avoir fait le cast sur RAND_MAX aurait du suffire.
La confiance n'exclut pas le contrôle
Pour que ça marche tu dois caster rand()
double alea = (double) rand()/RAND_MAX*20;
Remarque : avoir fait le cast sur RAND_MAX aurait du suffire.
La confiance n'exclut pas le contrôle
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
20 avril 2011 à 18:06
20 avril 2011 à 18:06
Je suis plutôt d'accrod avec ta remarque. Normalement pour faire une division reelle avec des entier, il suffit de mettre double sur le diviseur. Ce que l'on peut d'ailleurs voir dans le man de rand avec une conversion réalisé en ajoutant 1.0 à RAND_MAX.
m-killer
Messages postés
21
Date d'inscription
mercredi 20 avril 2011
Statut
Membre
Dernière intervention
1 mai 2012
4
20 avril 2011 à 17:00
20 avril 2011 à 17:00
En utilisant time(NULL), tu genere tes nombres aléatoire selon un nombre de seconde, donc il se peu que tu ai plusieur fois le meme nombre a la suite si tu en tire plusieur a la suite car, si je ne me trompe pas, le type time_t est un entier.
Cependant il nous faudrai plus d'info concernant les nombres qui se repete (s'il se repete a la suite, regulierement, si c'est toujour 0 etc)
Cependant il nous faudrai plus d'info concernant les nombres qui se repete (s'il se repete a la suite, regulierement, si c'est toujour 0 etc)
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
20 avril 2011 à 18:02
20 avril 2011 à 18:02
???
D'où ça viens tout ça ? time sert juste à initialiser la graine, je ne vois pas le rapport avec le reste.
D'où ça viens tout ça ? time sert juste à initialiser la graine, je ne vois pas le rapport avec le reste.
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 844
Modifié par fiddy le 20/04/2011 à 21:14
Modifié par fiddy le 20/04/2011 à 21:14
@ Char Snipeur,
Il veut sans doute dire que si tu lances ton programme à des intervalles rapprochés, la graine sera la même et in fine la séquence des nombres tirés par rand sera la même. Mais hors sujet ^^.
Il veut sans doute dire que si tu lances ton programme à des intervalles rapprochés, la graine sera la même et in fine la séquence des nombres tirés par rand sera la même. Mais hors sujet ^^.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
bonjour,
j'ai du me tromper ailleurs alors sans doute... :(
Je dois étudier une diffusion (N=1/(4 pi K t )^3/2*exp(-r²/4Kt) avec comme variables r et t rentré par l'utilisateur. le reste sont des constantes.
La distribution de départ est uniforme, donc je dois tirer au hasard un (r2,theta) par rapport au centre d'un cercle de rayon 20.
La diffusion est regardée à partir d'un point se trouvant à 8 du centre, donc la formule est celle d'al kashi :
r²=r2²+8²-2*8*r2*cos(theta).
enfin je regarde la contribution de chaque anneau autour du point d'observation. C'est à ce moment que j'obtient une irrégularité au niveau de 8, alors que la courbe devrait être lisse.
voilà, j'espère avoir été claire sur la modélisation, voilà ce que j'ai fait. (je rappelle aque c'est mon premier programme, donc soyez indulgents....)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
//calcul de la diffusion dimension n;
double diff(double r, double t)
{
double D0,delta,N0;
double D,N,R;
int n;
D0=0.1 ;//kpc²/Myr
delta=0.5;
N0=1;
R=1; //GeV
n=2;
D=D0*pow(R,delta);
N=N0/pow(4*M_PI*D*t,(n/2)) *exp (-r*r/(4*D*t));
return N;
}
int main(int argc, char *argv[])
{
srand(time(NULL));
FILE* contribution = NULL;
contribution = fopen("contribution.txt", "w");
double deltat,tobs,dimension;
double rmax,tetamax,Nmax;
double N,r2,r,SN,teta;
double rsol;
int i,numero,j,Nb;
double a;
double tableau [280]; //contribution par rapport au rayon
deltat= atoi (argv[1]); //durée d'étude
tobs= atoi (argv[2]); //temps de l'observateur
//initialisation des paramètres
for (j=1;j<=280;j++)
{
tableau[j]=0;
}
Nmax=0;
tetamax=0;
rmax=0;
rsol=8.; //kpc
Nb=deltat/(pow(10,-4));
//calcul de toutes les SN
for (i=1;i<=Nb;i++)
{ a=0;
SN=(rand()/(double)RAND_MAX )*(deltat); //temps d'explosion de la ieme SN
if(SN<tobs) //observation à un temps SN< tems total d'étude
{
//position de la ieme SN
r2=(rand()/(double)RAND_MAX )*(20);
teta=(rand()/(double)RAND_MAX )*(2*M_PI);
r=sqrt(pow(r2,2)-(2*rsol*r2*cos(teta))+pow(rsol,2));
//calcul de N a la ieme SN
N=diff(r2,SN);
//contribution par rapport au rayon
for (j=1;j<=280;j++)
{
if (r>a && r<=(a+0.1))
{
tableau[j]=tableau[j]+N;
}
a=a+0.1;
}
// recherche de la SN qui contribue le plus
if (N>Nmax)
{
Nmax=N;
tetamax=teta;
rmax=r;
numero=i;
}
}
}
a=0;
for (j=1;j<=279;j++)
{
a=a+0.1;
fprintf(contribution,"%f %f\n",a,tableau[j]);
}
fclose(contribution);
return 0;
}
j'ai du me tromper ailleurs alors sans doute... :(
Je dois étudier une diffusion (N=1/(4 pi K t )^3/2*exp(-r²/4Kt) avec comme variables r et t rentré par l'utilisateur. le reste sont des constantes.
La distribution de départ est uniforme, donc je dois tirer au hasard un (r2,theta) par rapport au centre d'un cercle de rayon 20.
La diffusion est regardée à partir d'un point se trouvant à 8 du centre, donc la formule est celle d'al kashi :
r²=r2²+8²-2*8*r2*cos(theta).
enfin je regarde la contribution de chaque anneau autour du point d'observation. C'est à ce moment que j'obtient une irrégularité au niveau de 8, alors que la courbe devrait être lisse.
voilà, j'espère avoir été claire sur la modélisation, voilà ce que j'ai fait. (je rappelle aque c'est mon premier programme, donc soyez indulgents....)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
//calcul de la diffusion dimension n;
double diff(double r, double t)
{
double D0,delta,N0;
double D,N,R;
int n;
D0=0.1 ;//kpc²/Myr
delta=0.5;
N0=1;
R=1; //GeV
n=2;
D=D0*pow(R,delta);
N=N0/pow(4*M_PI*D*t,(n/2)) *exp (-r*r/(4*D*t));
return N;
}
int main(int argc, char *argv[])
{
srand(time(NULL));
FILE* contribution = NULL;
contribution = fopen("contribution.txt", "w");
double deltat,tobs,dimension;
double rmax,tetamax,Nmax;
double N,r2,r,SN,teta;
double rsol;
int i,numero,j,Nb;
double a;
double tableau [280]; //contribution par rapport au rayon
deltat= atoi (argv[1]); //durée d'étude
tobs= atoi (argv[2]); //temps de l'observateur
//initialisation des paramètres
for (j=1;j<=280;j++)
{
tableau[j]=0;
}
Nmax=0;
tetamax=0;
rmax=0;
rsol=8.; //kpc
Nb=deltat/(pow(10,-4));
//calcul de toutes les SN
for (i=1;i<=Nb;i++)
{ a=0;
SN=(rand()/(double)RAND_MAX )*(deltat); //temps d'explosion de la ieme SN
if(SN<tobs) //observation à un temps SN< tems total d'étude
{
//position de la ieme SN
r2=(rand()/(double)RAND_MAX )*(20);
teta=(rand()/(double)RAND_MAX )*(2*M_PI);
r=sqrt(pow(r2,2)-(2*rsol*r2*cos(teta))+pow(rsol,2));
//calcul de N a la ieme SN
N=diff(r2,SN);
//contribution par rapport au rayon
for (j=1;j<=280;j++)
{
if (r>a && r<=(a+0.1))
{
tableau[j]=tableau[j]+N;
}
a=a+0.1;
}
// recherche de la SN qui contribue le plus
if (N>Nmax)
{
Nmax=N;
tetamax=teta;
rmax=r;
numero=i;
}
}
}
a=0;
for (j=1;j<=279;j++)
{
a=a+0.1;
fprintf(contribution,"%f %f\n",a,tableau[j]);
}
fclose(contribution);
return 0;
}
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
Modifié par Char Snipeur le 21/04/2011 à 10:21
Modifié par Char Snipeur le 21/04/2011 à 10:21
Bon, je ne vois rien qui pourrait mettre la merde.
juste quelques remarque : les tableaux en C vont de 0 à N-1 et non de 0 à N, du coup tu risques des erreurs (c'est une grosse erreur en C).
attention à la division d'entiers dans diff() (n/2). Lorsque tu veux utiliser des doubles, utilise un point à la fin : 3./2. te donnera 1.5, c'est une bonne méthode à prendre. Aussi, au lieu d'écrire pow(10,-4), écrit simplement 1e-4.
pour afficher les double j'utilise %e, il me semble que %f c'est pour les float.
ton programme n'est pas simple pour quelqu'un qui n'est pas du domaine. explique nous où ça merde dans ton programme. Il est possible que tu es une erreur d'algorithme (et pas de programmation).
Utilise les balises de code pour mettre ton source :
La vrai soumission c'est quand les esclaves s'inquiètent du cours du coton.
Char Snipeur
juste quelques remarque : les tableaux en C vont de 0 à N-1 et non de 0 à N, du coup tu risques des erreurs (c'est une grosse erreur en C).
attention à la division d'entiers dans diff() (n/2). Lorsque tu veux utiliser des doubles, utilise un point à la fin : 3./2. te donnera 1.5, c'est une bonne méthode à prendre. Aussi, au lieu d'écrire pow(10,-4), écrit simplement 1e-4.
pour afficher les double j'utilise %e, il me semble que %f c'est pour les float.
ton programme n'est pas simple pour quelqu'un qui n'est pas du domaine. explique nous où ça merde dans ton programme. Il est possible que tu es une erreur d'algorithme (et pas de programmation).
Utilise les balises de code pour mettre ton source :
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #include <string.h> //calcul de la diffusion dimension n; double diff(double r, double t) { double D0,delta,N0; double D,N,R; int n; D0=0.1 ;//kpc²/Myr delta=0.5; N0=1; R=1; //GeV n=2; D=D0*pow(R,delta); N=N0/pow(4*M_PI*D*t,(n/2)) *exp (-r*r/(4*D*t)); return N; } int main(int argc, char *argv[]) { srand(time(NULL)); FILE* contribution = NULL; contribution = fopen("contribution.txt", "w"); double deltat,tobs,dimension; double rmax,tetamax,Nmax; double N,r2,r,SN,teta; double rsol; int i,numero,j,Nb; double a; double tableau [280]; //contribution par rapport au rayon deltat= atoi (argv[1]); //durée d'étude tobs= atoi (argv[2]); //temps de l'observateur //initialisation des paramètres for (j=1;j<=280;j++) { tableau[j]=0; } Nmax=0; tetamax=0; rmax=0; rsol=8.; //kpc Nb=deltat/(pow(10,-4)); //calcul de toutes les SN for (i=1;i<=Nb;i++) { a=0; SN=(rand()/(double)RAND_MAX )*(deltat); //temps d'explosion de la ieme SN if (SN<tobs) //observation à un temps SN< tems total d'étude { //position de la ieme SN r2=(rand()/(double)RAND_MAX )*(20); teta=(rand()/(double)RAND_MAX )*(2*M_PI); r=sqrt(pow(r2,2)-(2*rsol*r2*cos(teta))+pow(rsol,2)); //calcul de N a la ieme SN N=diff(r2,SN); //contribution par rapport au rayon for (j=1;j<=280;j++) { if (r>a && r<=(a+0.1)) { tableau[j]=tableau[j]+N; } a=a+0.1; } // recherche de la SN qui contribue le plus if (N>Nmax) { Nmax=N; tetamax=teta; rmax=r; numero=i; } } } a=0; for (j=1;j<=279;j++) { a=a+0.1; fprintf(contribution,"%f %f\n",a,tableau[j]); } fclose(contribution); return 0; }
La vrai soumission c'est quand les esclaves s'inquiètent du cours du coton.
Char Snipeur
merci déjà pour toutes ces précisions.
Je ne comprends pas exactement ce que tu entend par erreur d'algorithme...:)
mon programme fonctionne, je peux tracer une courbe une fois qu'il a terminé. Seulement cette courbe n'est pas lisse, elle a un pic en 8. Lorsque dans la définition de r (r²=r2²+8²+2*8*r2*cos), j'enlève le 8² (juste par test, la fonction est exacte), l'irrégularité disparait, ce qui me poussait à croire à un problème avec rand.
Lorsque je tire deux nombres aléatoires et que je les fait agir ensemble dans une fonction, peut-être y a t il un effet qui fait cette augmentation en 8?
en tous cas, merci déjà, je suis contente de n'avoir pas fait de grosse erreur dans le code!!
Je ne comprends pas exactement ce que tu entend par erreur d'algorithme...:)
mon programme fonctionne, je peux tracer une courbe une fois qu'il a terminé. Seulement cette courbe n'est pas lisse, elle a un pic en 8. Lorsque dans la définition de r (r²=r2²+8²+2*8*r2*cos), j'enlève le 8² (juste par test, la fonction est exacte), l'irrégularité disparait, ce qui me poussait à croire à un problème avec rand.
Lorsque je tire deux nombres aléatoires et que je les fait agir ensemble dans une fonction, peut-être y a t il un effet qui fait cette augmentation en 8?
en tous cas, merci déjà, je suis contente de n'avoir pas fait de grosse erreur dans le code!!
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
21 avril 2011 à 11:42
21 avril 2011 à 11:42
Je ne comprend rien à ce que tu cherches à faire (les histoires de distribution). si tu met un rsol différent de 8, comment se comporte ta courbe ?