[Delphi] tirage aléatoire suivant une loi normale ?

tirage aléatoire suivant une loi normale ? [Delphi] - Delphi/Pascal - Programmation

Marsh Posté le 31-10-2003 à 19:48:31    

bien l'bonjour tous :)
 
vala, je me demandais s'il etait possible sous delphi d'effectuer un tirage aleatoire suivant une loi normal ?
 
je m'explique : je voudrais tirer des nombres aleatoirement de 100 à 600, en favorisant les tirages autour de 250. existe-t-il un algorithme qui permette de faire ca ? ou qq a-t-il une idée pour le réaliser ?
 
ou plus simplement, existe-t-il des tirages autres qu'en utilisant la fonction random ?
 
merci :hello:


Message édité par BoBoToTo le 31-10-2003 à 19:49:18
Reply

Marsh Posté le 31-10-2003 à 19:48:31   

Reply

Marsh Posté le 02-11-2003 à 21:52:54    

meme pas une petite suggestion ? :D


---------------
TOPIC - le son sur PC | pm 5.1 | pm ultra 5.1
Reply

Marsh Posté le 02-11-2003 à 23:01:52    

Reply

Marsh Posté le 03-11-2003 à 01:49:27    

hola magnifique :D
 
sinon j'avais pensé a un truc tout bete : une somme de random.
 
par exemple :
 

Code :
  1. j:= 0;
  2. for i:= 1 to 10 do
  3.   j:= j + random(11)


 
dans cet exemple, on obtient de nombreuses valeurs proches de 50, et tres rarement (jamais ?) les extremes (0 ou 100). ca me suffirait p etre... sachant k'on peut ensuite réajuster un peu le tout pour "décaler" la courbe (avoir un maximum de valeur a 30 plutot k'a 50). il est également possible de jouer sur "l'ecart type" en jouant sur le nombre de répétitions de la boucle (pour i allant de 1 a 10, les valeurs sont assez proches de 50 ; pour i allant de 1 à 5 avec un random(21), les valeurs s'en éloignent un peu plus, et la cloche est plus plate)
 
mais sinon juste pour essayer qqch de plus mathématique, l'exponentiel dans delphi ca se passe comment ?
 
 
edit : ok ya un algorythme dans le lien ke tu as fournis... j'avais pas vu :p
merci bcp :jap:
 
et heu... le ln dans delphi ? :whistle:


Message édité par BoBoToTo le 03-11-2003 à 02:20:15

---------------
TOPIC - le son sur PC | pm 5.1 | pm ultra 5.1
Reply

Marsh Posté le 03-11-2003 à 08:22:07    

J'avais fait ca a l'epoque (en DESS):

Code :
  1. uses math;
  2. .....
  3. procedure normale(var x:tableau;taille:integer;m:double=0;s:double=1);
  4. var i:integer;
  5.     u,v:double;
  6. begin
  7. for i:=0 to taille-1 do
  8. begin u:=random;
  9.       v:=random;
  10.       x[i]:=sqrt(-2*ln(u))*cos(2*Pi*v);
  11.       x[i]:=s*x[i]+m;
  12. end;
  13. end;


 
où m est la moyenne et s l'ecart type
 
si ca peut aider...


Message édité par xinxang le 03-11-2003 à 08:23:48
Reply

Marsh Posté le 03-11-2003 à 19:24:28    

zion a écrit :

Tu peux aussi faire un genre de round-robin simplifié...
 
Le principe est simple, tu as disons 5 valeurs, chacune à un coefficient (disons 1 pour 1, 2 pour 2, etc, etc...). Tu fais la somme des coéfficients (1+2+3+4+5 = 15) et tu fais un random sur 15, tu détermines alors le nombre choisis (si tu as 13 à random, 6 est dans le range du 5 donc ce sera 5).
 
L'avantage c'est que tu donnes une priorité max aux nombres voulus tout en laissant une chance aux autres de sortir quand même :D


oué j'ai essayé des trucs du genre :D
mais bon c pas trop valable qd tu ne connais pas le nombre de valeurs ke tu veux utiliser ni celles ke tu veux favoriser :sweat:
 
ton premier algorithme a l'air sympa
ca correspond vraiment a l'ecart type et a la moyenne ? testé et approuvé par la communauté mathematicienne ? :whistle:
 
merci :jap:


Message édité par BoBoToTo le 03-11-2003 à 19:29:38

---------------
TOPIC - le son sur PC | pm 5.1 | pm ultra 5.1
Reply

Marsh Posté le 04-11-2003 à 12:33:49    

Si tu parles du mien vivi ça marche très bien (testé, approuvé, démontré ;) )
Ca vient d'un de mes projet de DESS ingé maths sur la simulation de tirage de variables aléatoires suivant plein de lois.
 
Pour ceux que ça intéresse voilà ttes les lois que j'avais implantées :
 

Code :
  1. uses math;
  2. type tableau=array of double;
  3. ........
  4. procedure uniform(var x:tableau;taille:integer;a:double=0;b:double=1);
  5. var i:integer;
  6. begin
  7. for i:= 0 to taille-1 do x[i]:=(b-a)*random+a;
  8. end;
  9. procedure binomiale(var x:tableau;taille:integer;n:integer=10;p:double=0.5);
  10. var i,j:integer;
  11. begin
  12. for i:=0 to taille-1 do
  13. begin x[i]:=0;
  14.       for j:=1 to n do
  15.           if random<p then x[i]:=x[i]+1;
  16. end;
  17. end;
  18. procedure exponentielle(var x:tableau;taille:integer;lambda:double=1);
  19. var i:integer;
  20.     u:double;
  21. begin
  22. for i:=0 to taille-1 do
  23. begin u:=random;
  24.       x[i]:=-ln(u)/lambda;
  25. end;
  26. end;
  27. procedure ppoisson(var x:tableau;taille:integer;lambda:double=1);
  28. var i:integer;
  29.     a,u:double;
  30. begin
  31. a:=exp(-lambda);
  32. for i:=0 to taille-1 do
  33. begin x[i]:=0;
  34.       u:=random;
  35.       while u>a do
  36.       begin u:=u*random;
  37.             x[i]:=x[i]+1;
  38.       end;
  39. end;
  40. end;
  41. procedure geometrique(var x:tableau;taille:integer;p:double=0.5);
  42. var i:integer;
  43.     u:double;
  44. begin
  45. for i:=0 to taille-1 do
  46. begin x[i]:=0;
  47.       repeat u:=random;
  48.              x[i]:=x[i]+1;
  49.       until u<=p;
  50. end;
  51. end;
  52. procedure normale(var x:tableau;taille:integer;m:double=0;s:double=1);
  53. var i:integer;
  54.     u,v:double;
  55. begin
  56. for i:=0 to taille-1 do
  57. begin u:=random;
  58.       v:=random;
  59.       x[i]:=sqrt(-2*ln(u))*cos(2*Pi*v);
  60.       x[i]:=s*x[i]+m;
  61. end;
  62. end;
  63. procedure chi2(var x:tableau;taille:integer;n:integer=5);
  64. var u:tableau;
  65.     i,j:integer;
  66. begin
  67. setlength(u,n);
  68. for i:=0 to taille-1 do
  69. begin x[i]:=0;
  70.       normale(u,n);
  71.       for j:=0 to n-1 do x[i]:=x[i]+sqr(u[j]);
  72. end;
  73. end;
  74. procedure student(var x:tableau;taille:integer;n:integer=5);
  75. var i,j:integer;
  76.     u:tableau;
  77.     temp:double;
  78. begin
  79. setlength(u,n+1);
  80. for i:=0 to taille-1 do
  81. begin temp:=0;
  82.       normale(u,n+1);
  83.       for j:=0 to n-1 do temp:=temp+sqr(u[j]);
  84.       x[i]:=u[n]/sqrt(temp);
  85. end;
  86. end;
  87. procedure fischer(var x:tableau;taille:integer;n1:integer=5;n2:integer=10);
  88. var i,j:integer;
  89.     u,v:tableau;
  90.     tmp1,tmp2:double;
  91. begin
  92. setlength(u,n1);
  93. setlength(v,n2);
  94. for i:=0 to taille-1 do
  95. begin normale(u,n1);
  96.       normale(v,n2);
  97.       tmp1:=0;tmp2:=0;
  98.       for j:=0 to n1-1 do tmp1:=tmp1+sqr(u[j]);
  99.       for j:=0 to n2-1 do tmp2:=tmp2+sqr(v[j]);
  100.       x[i]:=(n2/n1)*(tmp1/tmp2);
  101. end;
  102. end;
  103. procedure DeNFaces(var x:tableau;taille:integer;n:integer=6);
  104. var i:integer;
  105. begin
  106. for i:=0 to taille-1 do
  107.   x[i]:=random(n)+1;
  108. end;
  109. procedure cauchy(var x:tableau;taille:integer;a:double=1);
  110. var i:integer;
  111. begin
  112. for i:=0 to taille-1 do
  113.   x[i]:=a*tan(Pi*(random-0.5));
  114. end;
  115. procedure LogNormale(var x:tableau;taille:integer;m:double=0;s:double=1);
  116. var i:integer;
  117. begin
  118. normale(x,taille,m,s);
  119. for i:=0 to taille-1 do
  120.     x[i]:=exp(x[i]);
  121. end;
  122. procedure pareto(var x:tableau;taille:integer;r:double=2;lambda:double=1);
  123. var i:integer;
  124. begin
  125. exponentielle(x,taille,lambda);
  126. for i:=0 to taille-1 do
  127.    x[i]:=r*exp(x[i]);
  128. end;
  129. procedure weibull(var x:tableau;taille:integer;a:double=2;lambda:double=1);
  130. var i:integer;
  131. begin
  132. exponentielle(x,taille,lambda);
  133. for i:=0 to taille-1 do
  134.    x[i]:=exp(1/a*ln(x[i]));
  135. end;


Message édité par xinxang le 04-11-2003 à 12:42:20
Reply

Marsh Posté le 04-11-2003 à 17:48:47    

oula :whistle:
ben je te remercie, voila ki fera mon affaire :D
 
juste a titre d'exemple, voila un petit qqch ki marche pas mal (meme si ca n'a rien d'une loie normale, ca a le mérite de faire ce dont g besoin ;))
 

Code :
  1. Function LoiNormale(min,max,centre,ecart: integer): integer;
  2. var
  3.   i,resultat: integer;
  4. begin
  5.   if (min < max) and (ecart <= (max-min)) and (centre >= min) and (centre <= max) then
  6.     begin
  7.       repeat
  8.         resultat:=0;
  9.         for i:=1 to ecart do
  10.           resultat:= resultat + random(max-min+1);
  11.         resultat:=(resultat div ecart) - (max-min) div 2 + centre;
  12.       until (resultat >=min) and (resultat <= max);
  13.       result:= resultat
  14.     end
  15.   else result:= -1;
  16. end;


biensur la variable "ecart" n'a rien d'un ecart type. ca permet juste de jouer sur la forme de la courbe (à 1 on a un seul random -> tirage aleatoire normal, a 2 on a 2 random -> 2 pentes avec un max à la valeur choisie pour le centre, puis en augmentant on a une courbe en cloche de plus en plus marquée... oué c de la magouille, mais ca marche :p)


Message édité par BoBoToTo le 04-11-2003 à 17:51:19

---------------
TOPIC - le son sur PC | pm 5.1 | pm ultra 5.1
Reply

Marsh Posté le 04-11-2003 à 18:24:43    

xinxang a écrit :

J'avais fait ca a l'epoque (en DESS):

Code :
  1. uses math;
  2. .....
  3. procedure normale(var x:tableau;taille:integer;m:double=0;s:double=1);
  4. var i:integer;
  5.     u,v:double;
  6. begin
  7. for i:=0 to taille-1 do
  8. begin u:=random;
  9.       v:=random;
  10.       x[i]:=sqrt(-2*ln(u))*cos(2*Pi*v);
  11.       x[i]:=s*x[i]+m;
  12. end;
  13. end;


 
où m est la moyenne et s l'ecart type
 
si ca peut aider...


 
Je confirme l'algo... j'avais utilisé le même (en fait ça se retrouve facilement avec des projections) pour tester mon Kurtosis dans mon TIPE

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed