Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

PROBABILITÉ DANS LES RANDOM (NOMBRES ALÉATOIRES)


Information sur la source

Description

Cliquez pour voir la capture en taille normale
Une petite fonction boolean qui retourne true dans 86,7985% des cas par exemple et false dans les cas restant.
On passe en parametre la probabilité que la fonction retourne true et on laisse le random choisir ;-)

(voir commentaires dans le zip)
 

Source

  • function RandomProba(Proba:real):boolean;
  • var Probabilite,Total,Sel:integer;
  • NbChiffres:byte;
  • begin
  • if (Proba<0) or (Proba=0) then
  • begin
  • RandomProba:=false;
  • Exit;
  • end;
  • if (Proba>1) or (Proba=1) then
  • begin
  • RandomProba:=true;
  • Exit;
  • end;
  • RandomProba:=false;
  • NbChiffres:= 9;
  • Total := round(IntPower(10,NbChiffres));
  • probabilite :=round(frac(Proba)*Total);
  • Sel:=random(Total);
  • if Sel < probabilite then
  • begin
  • RandomProba:=true;
  • end;
  • end;
function RandomProba(Proba:real):boolean;
var Probabilite,Total,Sel:integer;
    NbChiffres:byte;
begin
  if (Proba<0) or (Proba=0) then
    begin
      RandomProba:=false;
      Exit;
    end;
  if (Proba>1) or (Proba=1) then
    begin
      RandomProba:=true;
      Exit;
    end;
  RandomProba:=false;
  NbChiffres:= 9;
  Total := round(IntPower(10,NbChiffres));
  probabilite :=round(frac(Proba)*Total);
  Sel:=random(Total);
  if Sel < probabilite then
    begin
      RandomProba:=true;
    end;
end;

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !
  •   Probabilite Aleatoire
    • Probab.cfgTélécharger ce fichier [Réservé aux membres club]Voir ce fichier434 octets
    • Probab.dofTélécharger ce fichier [Réservé aux membres club]Voir ce fichier2 362 octets
    • Probab.dprTélécharger ce fichier [Réservé aux membres club]Voir ce fichier192 octets
    • Probab.exeTélécharger ce fichier [Réservé aux membres club]394 752 octets
    • Probab.resTélécharger ce fichier [Réservé aux membres club]876 octets
    • Unit1.dcuTélécharger ce fichier [Réservé aux membres club]5 762 octets
    • Unit1.ddpTélécharger ce fichier [Réservé aux membres club]51 octets
    • Unit1.dfmTélécharger ce fichier [Réservé aux membres club]950 octets
    • Unit1.pasTélécharger ce fichier [Réservé aux membres club]Voir ce fichier3 559 octets

Télécharger le zip

Commentaires et avis

signaler à un administrateur
Commentaire de WhiteHippo le 02/04/2005 12:37:36

Quelques petites remarques en passant :
  if (Proba<0) or (Proba=0) then
peut être remplacé par
  if (Proba<=0.0) then
idem pour
  if (Proba>1) or (Proba=1) then
qui peut être remplacé par
  if (Proba<=1.0) then

N.B. 0.0 et 1.0 juste histoire de clarifier le code et pour montrer que tu travailles avec des réels.

Dans MultiEssaisClick
Tu utilises les variables total, ok et bad. Toutes ne sont pas nécessaire. Tu sais que tu fais une boucle de i fois (i=100)  donc ton total est égal à i. De plus soit ton résultat est bon soit il est mauvais, donc si tu comptabilises uniquement les bons (ok) les mauvais se deduisent simplement comme etant bad=total-ok ou encore bad=i-ok
Donc en supprimant bad et total, puis en remplaçant total par i tu obtiendras les mêmes résultats.

Un dernier point, tu désactives tes boutons ce qui est une très bonne chose, cependant si une exception intervient dans ton code, le bouton sera définitevement inactif...
Pense à encadre ton code avec un try finally.
  bouton.enabled := false ;
  try
     // .... ton code ici
  finally
    bouton.enabled := true ;
  end ;

Cordialement.

  

signaler à un administrateur
Commentaire de Theos le 02/04/2005 16:00:56

* Mouai, effectivement, tu as raison, on peut économiser une variable dans MultiEssaisClick mais c'est pas très important... Le seul but de ce prog c'est la fonction RandomProba :-)

*Pour ce qui est d'utiliser 0.0 au lieu de 0, je vois vraiment pas l'intêret... On sait qu'on travaille avec des reel, il suffit de regarder le type de variable passée en parametre...
Et en plus, une probabilité est généralement comprise entre 0 et 1 donc c'est obligatoirement un reel...

Pour ce qui est des try catch, on peut effectivement en mettre à toutes les lignes...
Plus on en met, mieux c'est ;-) mais ce n'était pas ici le but de ma fonction...
Quand on traite un sujet précis, mieux vaut faire des fonctions simples en rapport directe avec ce sujet... C'est ensuite à celui qui utilise la fonction de gerer la manière dont il va la lancer....
J'aurais aussi pu intégrer un chronometre qui compte la durée de fonctionnement... Et Aussi une gestion des sockets pour faire du grid computing (calcul distribué)... Un module qui regarde si si il y a pas de keyloggers...
Et après, ca fait une usine à gaz, et on s'y retrouve plus...
Non, je crois qu'il faut pas trop s'écarter du sujet ;-) Il y a des sources qui expliquent le fonctionnement des try except et d'autres qui servent à faire des randoms...
Effectivement, j'aurais pu mettre un petit try mais je les garde généralement pour des fonctions ou je ne peux pas vraiment pas controler l'erreur... (genre du réseau principalement et des erreurs de sockets)
Ici l'erreur est partiellement controlée car tu peux passer n'importe quel paramêtre à RandomProba, elle ne fera jamais d'exception car elle traite les nombre négatifs... Le seul cas qui peut générer une exception, est un cas extreme : Si il y a plus de mémoire ou plus de ressources systêmes... Et là, si  on gère ce cas, on est bon pour le gêrer à chaque instruction y compris celle du genre a:=1; C'est tomber dans la parano. Et d'ailleurs, try except utilise surement un peu de mémoire donc si il y en a plus, c'est le try lui même qui va planter...
Bref, on peut mettre un try, ca coute rien mais on rencontrera surement jamais d'exception.
Il faut distinguer les exceptions qui sont créés par des beugs, de celle qui sont crées par des erreurs légitimes.
Pour les premières, le traitement est simple, on doit se démerder pour qu'elles n'existent pas ;-)) donc pas besoin de les catcher.

A++
Theos

signaler à un administrateur
Commentaire de WhiteHippo le 03/04/2005 00:16:03

>* Mouai, effectivement, tu as raison, on peut >économiser une variable dans MultiEssaisClick mais >c'est pas très important... Le seul but de ce prog c'est >la fonction RandomProba :-)

non déjà pas 1 mais 2 (total et bad), et puis si pour un tout petit programme comme celui là, il ya en déjà 2 de trop, imagines ce que ce sera pour un gros projet...
De plus, ce code est destiné aux débutants, faut pas leur donner de mauvaises habitudes

>*Pour ce qui est d'utiliser 0.0 au lieu de 0, je vois >vraiment pas l'intêret... On sait qu'on travaille avec >des reel, il suffit de regarder le type de variable >passée en parametre...

ok, mais comme je l'ai dit précédemment, "juste histoire de clarifier le code"

>Et en plus, une probabilité est généralement comprise >entre 0 et 1 donc c'est obligatoirement un reel...

non, tu peux etre amené à utiliser uniquement des entiers pour représenter une probabilité (calcul en virgule fixe, ou bien en pourcentage par exemple)

>Pour ce qui est des try catch, on peut effectivement en >mettre à toutes les lignes...
>Plus on en met, mieux c'est ;-) mais ce n'était pas ici le >but de ma fonction...
>Quand on traite un sujet précis, mieux vaut faire des >fonctions simples en rapport directe avec ce sujet... >C'est ensuite à celui qui utilise la fonction de gerer la >manière dont il va la lancer....
>J'aurais aussi pu intégrer un chronometre qui compte >la durée de fonctionnement... Et Aussi une gestion >des sockets pour faire du grid computing (calcul >distribué)... Un module qui regarde si si il y a pas de >keyloggers...
>Et après, ca fait une usine à gaz, et on s'y retrouve >plus...

Tu serais pas de Marseilles, toi :P

>Non, je crois qu'il faut pas trop s'écarter du sujet ;-) Il >y a des sources qui expliquent le fonctionnement des >try except et d'autres qui servent à faire des >randoms...
>Effectivement, j'aurais pu mettre un petit try mais je >les garde généralement pour des fonctions ou je ne >peux pas vraiment pas controler l'erreur... (genre du >réseau principalement et des erreurs de sockets)
>Ici l'erreur est partiellement controlée car tu peux >passer n'importe quel paramêtre à RandomProba, elle >ne fera jamais d'exception car elle traite les nombre >négatifs... Le seul cas qui peut générer une exception, >est un cas extreme : Si il y a plus de mémoire ou plus >de ressources systêmes... Et là, si  on gère ce cas, on >est bon pour le gêrer à chaque instruction y compris >celle du genre a:=1; C'est tomber dans la parano. Et >d'ailleurs, try except utilise surement un peu de >mémoire donc si il y en a plus, c'est le try lui même qui >va planter...
>Bref, on peut mettre un try, ca coute rien mais on >rencontrera surement jamais d'exception.
>Il faut distinguer les exceptions qui sont créés par des >beugs, de celle qui sont crées par des erreurs >légitimes.
>Pour les premières, le traitement est simple, on doit >se démerder pour qu'elles n'existent pas ;-)) donc pas >besoin de les catcher.

Tout ça, c'est bien beau mais qui te parle d'un try..except ???
Moi je te parle d'un try..finally qui permettra de réactiver le bouton quelle que soit la manière dont la routine s'achèvera. N'oublies pas que là encore tu t'addresses à des débutants. Si quelqu'un utilises ton code et rajoutes un exit en plein milieu de ta procédure, que se passe t-il si tu ne mets pas de try..finally ? Un beau bouton inactif... :)

Cordialement.

signaler à un administrateur
Commentaire de WhiteHippo le 03/04/2005 00:18:38

Oups j'ai oublié des retours à la ligne devant les ">"
Désolé :oP

Cordialement.

signaler à un administrateur
Commentaire de Theos le 03/04/2005 01:17:29

Non, je suis a 600 km de marseille ;-)

A++
Theos

signaler à un administrateur
Commentaire de Forman le 03/04/2005 12:46:21

Désolé, je viens un peu foutre ma merde...

Est-ce que quelqu'un a une idée pour le problème suivant:
pour simplifier, on suppose que f est une fonction de [0,1] à valeurs positives, telle que son intégrale sur [0,1] vaut 1 (en fait, f est une densité de probabilité). Quelqu'un connaitrait-il un moyen simple de donner une nouvelle fonction Randomf qui serait une variable aléatoire de loi f? C'est à dire, que la probabilité que a<Randomf<b est égale à l'intégrale de f sur [a,b]? Par exemple, la fonction Random de base de Delphi est la réponse au problème dans le cas où f est constante et vaut 1.

Par exemple, f pourrait être une loi gaussienne...

J'ai une méthode pour faire un calcul approché de f par discrétisation d'histogramme qui est la suivante:

var
  DensityValues:array[0..999] of Single;

type
  TDensityFunc=function(x:Single):Single;

procedure Initialize(f:TDensityFunc);
var
  a,b:Integer;
  T:array[-1..999] of Single;
  s:Single;
begin
  s:=0;
  T[-1]:=0;
  for a:=0 to 999 do begin
    T[a]:=s+f(a/999);
    s:=T[a];
  end;
  s:=1000/s;
  for a:=0 to 999 do begin
    for b:=Trunc(T[a-1]*s) to Trunc(T[a]*s)-1 do
      DensityValues[b]:=a/999;
  end;
end;

function Randomf:Single;
begin
  Result:=DensityValues[Random(1000)];
end;

On commence à initialiser avec une densité de probabilité f:
Initialize(f);

Ensuite, la fonction Randomf donne des valeurs sur un échantillon de 1000 valeurs différentes dans l'intervalle [0,1]. Le problème, c'est que 1000 valeurs différentes ce n'est pas forcément assez, et que si l'on veut par exemple 1000000000 valeurs différentes possibles, il faut un tableau de Single de cette taille-là, ce qui peut prendre beaucoup de place en mémoire... Quelqu'un aurait-il un moyen de faire ça en utilisant moins (ou carrément pas du tout) de mémoire?

signaler à un administrateur
Commentaire de Theos le 03/04/2005 14:18:50

Désolé j'arrive tout juste à comprendre ta question, je suis trop nul en math pour donner une solution à ton problème ;-)

Je rentre juste en fac de math moi ;-)

A++
Theos

signaler à un administrateur
Commentaire de WhiteHippo le 03/04/2005 14:42:00

Ceci ferait-il ton bonheur ?
  http://www.esbconsult.com/amrandom.zip

Cordialement.

signaler à un administrateur
Commentaire de Forman le 03/04/2005 17:15:26

Cool, c'est exactement ça que je cherchais!
Apparemment, c'est le même algo que moi, avec des histogrammes pour les valeurs, mais optimisé avec une méthode arborescente de découpage d'intervalles et des interpolations...
En plus, ça a l'air d'être rapide!

Merci

signaler à un administrateur
Commentaire de jihelb le 04/04/2005 14:36:23

Que de complications inutiles pour une chose si simple !
function RandomProba(Proba:real):boolean;
begin
   if Proba <= 0 then Result:= false
  else if Proba >=1 then Result:= true
  else Result:= (Random < Proba)
end;
De plus il serait bon d'écouter les conseils de ceux qui nous veulent du bien; je suis parfaitement d'accord avec WhiteHippo. Un "progragramme pour débutant" ne doit pas être une excuse pour ne pas réfléchir et programmer correctement, AU CONTRAIRE.
Bonne Prog.
    

signaler à un administrateur
Commentaire de Forman le 04/04/2005 14:46:59

D'accord, tu as raison, simplifions au maximum:

function RandomProba(Proba:real):boolean;
begin
  Result:=Random<Proba
end;

Je crois que ça marche aussi...
<8=D

signaler à un administrateur
Commentaire de jihelb le 04/04/2005 16:53:05

Oui Forman, sauf si Proba est négatif (sait-on jamais ???) donc on gagne encore un test  !
Merci.

signaler à un administrateur
Commentaire de Theos le 04/04/2005 17:04:03

jihelb : Je suis d'accord, j'ai reconnu que j'avais utilisé des variables en trop dans MultiEssai alors voila, c'est bon, on va pas psycoter pendant dessus 6 mois :-))
(Lorsque j'ai répondu à WhiteHippo, on pouvait lire :
"effectivement, tu as raison, on peut économiser une variable dans MultiEssaisClick".)

Pour ce qui est du try, je n'ai pas changé d'avis, il ne sert pas à grand chose ici voir même à rien car les paramètres sont traités et les seules exceptions qui penvent arrivés sont des cas extremes qu'il ne sert à rien de traiter dans des applications d'exemples...

Et pour ce qui est de "programmer correctement", tu m'excuseras mais je crois que ton message est une plaisanterie car je ne trouve vraiment pas que

if Proba <= 0 then Result:= false
  else if Proba >=1 then Result:= true
  else Result:= (Random < Proba)

soit plus lisible que mon code...  Je suis même d'un avis contraire mais bon, la lisibilité c'est un avis personnel...
Tu devrais mettre tout sur la même ligne pendant que tu y es ;-) car les "else if" qui se suivent c'est le petit truc qui saute super à l'oeil quand on lit un code...
Non mais sérieux, il suffit que tu soit un peu fatigué, qu'il y ai un beug dans ton ton prog...
Avec ce genre de truc, tu passes facilement 20 minutes de plus à localiser le beug car les if juste derrière les else, ca se voient carrement pas...
Si il y a qu'un if imbirqué, ca va, on peut se permettre de tout mettre sur une ligne mais là, ton "amélioration" :-)), en met 3 qui se suivent les uns dans les autres alors ca va pas...
Enfin, je m'en fou, chacun fait comme il veux... Certains trouvent que 0.0 est plus lisible que  0, d'autres non, d'autres trouvent que c'est la même chose (c'est mon cas) et puis c'est tout...
Ma grand mêre aurait dit "Si tu veux améliorer la lisibilités des codes sources, commence par les tiens ;-)"
Non, je déconne, j'accepte les critiques mais quand elles sont justifiés...
Là vous êtes en train de tomber dans l'abus et de partir completement en vrie.

Pour ce qui est de la simplification de Fortman, ce n'est pas vraiment une simplification car les 2 codes ne font pas les mêmes choses...
Le code de fortman a lui (contrairement au mien) besoin d'un try car si on passe comme probablilité -0.25, il y aura un range négatif dans le random et je sais pas si ca va passer...
Soit il y a une exception, soit la fonction retourne carement n'importe quoi.
De plus, le code de fortman autorise n'importe quel nombre pour parametre alors que le reste de mon code ne fonctionne seulement dans certains cas...
(Exemple simple, avec 9999 pour parametre, je suis certains que certaines variables seront sous dimentionnées et seront en dépassement de capacité).
D'ailleur mon code est prévu pour fonctionner avec des probabilités comprises entre [0 et 1].
proba=0 signifie 0% des cas, proba=1 signifie 100% donc on parlait plus haut de mettre comme probabilité des nombres suppérieurs à 1...
C'est possible mais suppérieur à 100% des cas, ça revient à 100% des cas et voila..

Bref, en conclusion, ne délirez pas trop avec vos critiques à 2 balles ;-))

PS : Je remercie WhiteHippo car sa critique était effectivement intéressante. :-)
J'ai utilisé trop de variables et ca sert rien qu'a bouffer de la mémoire inutilement.

A++
Theos

signaler à un administrateur
Commentaire de Forman le 04/04/2005 18:05:17

Je persiste et je signe jihelb:

function RandomProba(Proba:real):boolean;
begin
  Result:=Random<Proba
end;

fonctionnera dans tous les cas, même si on met une Proba négative. En effet, la fonction random étant toujours positive, elle ne pourra jamais être plus petite qu'un nombre négatif. Donc ma version marche même si Proba est négatif, puisque dans ce cas le résultat est toujours "False".

De plus, Theos, les dépassements de capacités ne devraient pas être un problème dans ma version, toutefois il ne faudra pas dépasser les capacités d'un real, à savoir, comme décrit dans l'aide de Delphi:
5.0 x 10^-324 .. 1.7 x 10^308
en valeur absolue.
Mais bon, là encore, des nombres avec plus de 300 chiffres avant la virgule, ça me parait quand même assez correct comme intervalle de validité... Et si tu regardes bien ma fonction, j'ai utilisé la version sans paramètre de la fonction Random, donc il n'y a pas de problème de "range" ou de dépassement de capacité. Si tu veux vérifier que c'est vrai, compile ton projet en activant l'option "range checking" dans les options du projet, et essaie d'appeler la fonction avec un nombre très grand ou très petit, et tu verras qu'il n'y a pas d'exception déclenchée.

Au fait, ne voyez aucune aggressivité dans mes propos, j'expose simplement mon point de vue sur la façon la plus simple d'implémenter cette fonction!

signaler à un administrateur
Commentaire de Forman le 04/04/2005 18:18:40

Au fait, juste une remarque pour ceux qui ne le savaient pas:

Il existe 2 versions "overload" (C'est à dire 2 fonctions de types différents mais qui portent le mêm nom) de la fonction Random (déclarées je suppose dans l'unité virtuelle System.pas) qui sont respectivement déclarées comme ceci:

function Random(N:Integer):Integer;
function Random:Real;

La première donne un nombre ENTIER compris entre 0 et N-1 (au sens large), et la deuxième un nombre REAL compris strictement entre 0 et 1.

Et une dernière chose Theos, je t'assure que ta fonction initiale et la mienne font la même chose aux approximations près que tu fais en utilisant la première version de Random et moi la 2ème. Si tu veux le vérifier, c'est facile:

fais un programme ainsi:

procedure Test;
var
  a:Integer;
begin
  for a:=0 to 9 do
    if RandomProba(0.3) then
      showmessage('True')
    else
      showmessage('False');
end;

Met un bouton sur la fiche, et dans OnClick, lance la fonction Test.

Lance une fois le programme avec ta fonction, note sur un papier les 10 cas qui vont s'afficher, puis remplace ta fonction par la mienne, refais la même chose, et normallement tu devrais obtenir la même chose, si comme je le pense les 2 versions de la fonction Random sont définies l'une à partir de l'autre par Delphi.

signaler à un administrateur
Commentaire de Theos le 04/04/2005 18:41:33

Ah ok, désolé, je connaissais pas la fonction surchargée de random...
Bah merde alors, du coups ma fonction ne sert plus à rien...

Je te disais que ta fct allait pas marcher car je pensais que tu parlais de la fonction random que j'utilisais et que tu avais pas réécris toute la fin de mon code pour des raisons de flèmite ;-))

Effectivement maintenant que tu le dis, ca me parrait logique car en c++ j'utilise la fonction random de base (qui d'ailleurs s'appelle rand, je crois) et cette fonction retourne un nombre entre 0 et 1...

Je suis deg que mon code ne servent à rien mais bon ;-))
Pourtant j'avais bien cherché si il y avait pas une fonction qui existait déja et j'avais rien trouvé... j'avais mal cherché... grr..

Bon ben merci à vous pour m'avoir appris l'existence cette putain de surchage....

Je pense que je vais adopter ta fonction Forman (effectivement vu la signature de la surchage, elle doit marcher Nickel) et sera plus rapide que la mienne...

A++
Theos

signaler à un administrateur
Commentaire de Theos le 04/04/2005 18:48:34

En tout cas, je sais pas ou vous avez trouvé cette surcharge mais dans l'aide US de Delphi 7, elle est apparement pas indiquée au chapitre "Random function". Pourtant, je suis certain qu'elle existe depuis les premières version de delphi...

A++
Theos

signaler à un administrateur
Commentaire de jihelb le 05/04/2005 13:04:18

Effectivement Forman, aucun test n'est nécessaire. Jai répondu trop vite sans vérifier (j'étais à mon boulot, pas chez moi). Toutes mes excuses.
Dans ma proposition, je ne m'étais pas attardé sur mon utilisation de RANDOM à la place de RANDOM() croyant que celà allait de soi pour tous. Erreur. Tu as bien fait de préciser.
Décidemment Theos n'aime pas les conseils (pardon "...critiques à 2 balles " ???)
Dommage pour lui, mais ils sont utiles pour nous tous, sinon à quoi sert cette rubrique ?
Bonne Prog à tous.

Ajouter un commentaire



Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,250 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.