Page 1 sur 1
Fonction aléatoire sur un intervalle
Publié : mer. 12/sept./2012 13:01
par Golfy
J'ai lu (dans un post "houleux") qu'un programmeur avait besoin d'une fonction random plus pratique que la fonction de base.
Son besoin était :
1) pouvoir choisir des nombres négatifs (random(max) propose entre 0 et max)
2) pouvoir conserver ou non la valeur zéro sans devoir ajouter 1 (qui nécessite alors de soutraire 1 à max).
L'exercice était simple mais outre les réponses inutiles, une réponse possible de procédure était manquante (et le post est désormais verrouillé). Voici la plus courte des procédures je crois
Code : Tout sélectionner
; procedure de génération de nombre aléatoire dans un intervalle (bornes incluses)
; by Golfy (2012-09)
;
Procedure.i rnd(min.i, max.i)
ProcedureReturn Random(max.i-min.i)+min.i
EndProcedure
For t=1 To 50
Debug Str(rnd(0,8))+" "+ Str(rnd(-10,10))+" "+ Str(rnd(-20,10))
Next t
Ce code permet de choisir son intervalle, seule contrainte : saisir les nombres dans l'ordre (les bornes sont incluses dans le résultat renvoyé).
1) rnd(-10,10) renvoie des nombres entre -10 (donc négatifs) et 10
2) rnd(1,5) renvoie des nombres entre 1 et 5
Re: Fonction aléatoire sur un intervalle
Publié : jeu. 13/sept./2012 0:46
par G-Rom
Merci Golfy , toujours pratique d'avoir ce genre de fonction sous la main.
c'est du "tout prêt sans réfléchir"

Re: Fonction aléatoire sur un intervalle
Publié : jeu. 13/sept./2012 9:22
par Le Soldat Inconnu
juste pour vérifier le que le random répartit bien le retour entre le min et le max
Code : Tout sélectionner
; procedure de génération de nombre aléatoire dans un intervalle (bornes incluses)
; by Golfy (2012-09)
;
Procedure.i rnd(min.i, max.i)
ProcedureReturn Random(max.i-min.i)+min.i
EndProcedure
Dim Cpt(9)
For x = 1 To 10000000
Aleatoire = rnd(0, 9)
Cpt(Aleatoire) = Cpt(Aleatoire) + 1
Next
For x = 0 To 9
Debug Str(x) + " = " + Str(Cpt(x))
Next
Re: Fonction aléatoire sur un intervalle
Publié : jeu. 13/sept./2012 10:02
par Backup
L'exercice était simple mais outre les réponses inutiles, une réponse possible de procédure était manquante
il s'agit de ce post :
http://www.purebasic.fr/french/viewtopi ... om&start=0
et nous sommes quand meme plusieurs a avoir apporter une solution (y compris en procedure

)
a te lire , on pourrai croire qu'aucune reponses UTILE n'a été apporté , ....
Reponse de Ar-s
Code : Tout sélectionner
For i = 1 To 5
EssayeEncore:
R = Random(i)
If R = 0
Goto EssayeEncore
EndIf
neg = Random(1)
If neg = 0
R - (2*R)
EndIf
Debug R
Next
Reponse de Comtois :
Code : Tout sélectionner
Pour un nombre négatif compris entre -20 et -1
R = -1 - Random(19)
Reponse de TazNormand :
Code : Tout sélectionner
For i = 1 To 20
R = Random(20)+1
neg = -R
Debug R
Debug neg
Next
Reponse de Dobro ( en procedure )
voici une fonction qui permet de choisir un chiffre aleatoire
parmis une liste de chiffre positif ou negatif
cette liste partira du parametre "a" jusqu'au parametre "b"
pour l'exemple de -10 a 10
Code : Tout sélectionner
Declare rando(a,b)
debug rando(-10,10) ; ici on va choisir parmis une liste qui va de -10 a 10 ;o)
procedure rando(a,b)
; By Dobro
; info : la valeur du parametre "a" doit etre inferieur a "b"
; ****
; prepare la liste de numéros voulue
for x=a to b
liste.s=liste.s+str(x)+","
next x
calldebugger
; maintenant on choisi une valeur de cette liste au hasard
pos=random(CountString(liste.s,","))-1 ; on recup le nombre de virgules (donc le nombre de chiffre de la chaine-1...la virgule de fin)..et on tire un element au hasard
valeur.s=stringfield(liste.s,pos,",") ; on extrait de la chaine la valeur tiré au hasard
ProcedureReturn val(valeur)
endprocedure
; EPB
Autre reponse de Dobro
autre fonction , qui retourne un chiffre au hasard ,(positif ou negatif) mais sans plage
Code : Tout sélectionner
Declare rando2(a)
for i=1 to 10 ; on va tirer 10 chiffre au hasard
debug rando2(10) ;
next i
procedure rando2(a)
; By Dobro
; retourne un chiffre aleatoire positif ou negatif
x=random(a) ; le chiffre qu'on tire au hasard
de=random(1) ; le dé qui sert a choisir aleatoirement si ça va etre positif ou négatif
if de=0 ; le chiffre sera négatif
x=-x
endif
ProcedureReturn x
endprocedure
;
; EPB
voila voila

Re: Fonction aléatoire sur un intervalle
Publié : jeu. 13/sept./2012 10:06
par Ar-S
Un des charmes majeur de la prog en ce qui me concerne, trouver moult solutions pour arriver au même résultats.
Re: Fonction aléatoire sur un intervalle
Publié : jeu. 13/sept./2012 10:07
par Backup
c'est clair

Re: Fonction aléatoire sur un intervalle
Publié : jeu. 13/sept./2012 10:10
par falsam
Réponse de ..... moi

j'ai une préférence pour la solution de Golfy beaucoup plus sexy dans sa présentation et tellement plus courte.
Code : Tout sélectionner
Procedure.i rnd(min.i, max.i)
ProcedureReturn Random(max.i-min.i)+min.i
EndProcedure
Re: Fonction aléatoire sur un intervalle
Publié : jeu. 13/sept./2012 11:01
par Ar-S
Golfy a écrit :
Ce code permet de choisir son intervalle, seule contrainte : saisir les nombres dans l'ordre (les bornes sont incluses dans le résultat renvoyé).
Avec un petite vérif on annule cette contrainte. ne jamais lésiner sur les vérifications dans les procédures !
Code : Tout sélectionner
Procedure.i rnd(min.i, max.i)
if min = max
procedurereturn min
endif
If min > max
ProcedureReturn Random(mix.i-max.i)+max.i
Else
ProcedureReturn Random(max.i-min.i)+min.i
EndIf
EndProcedure
Ainsi peut donner comme consigne pour sa proce
rnd(valeur1, valeur2) sans se soucier de l'ordre.
Re: Fonction aléatoire sur un intervalle
Publié : jeu. 13/sept./2012 12:08
par Fred
Si min = max, tu devrais renvoyer 'min', pas 0

Re: Fonction aléatoire sur un intervalle
Publié : jeu. 13/sept./2012 12:20
par Golfy
Dobro a écrit :L'exercice était simple mais outre les réponses inutiles, une réponse possible de procédure était manquante
et nous sommes quand meme plusieurs a avoir apporter une solution (y compris en procedure

)
a te lire , on pourrai croire qu'aucune reponses UTILE n'a été apporté , ....
voila voila

Mes excuses si ma phrase te fait penser cela (probablement la redondance du mot réponse, j'aurais écrire :"
outre les réponses hors-sujets, une solution possible...")
En effet, c'est ce qui m'a le plus choqué sur le post correspondant (les réponses hors-sujets). Le forum anglais semble plus sain...
Donc loin de moi l'idée que des solutions n'avaient pas été astucieusement proposées mais juste l'envie de contribuer à la diversité des solutions
J'ai deux leit-motiv dans la vie :
ce qui ce conçoit bien, s'énonce clairement (grâce à ça, j'ai pu par exemple améliorer mon code pour PB_Velbus-server d'une version à l'autre : en simplifiant... je remecie tout les jours mon prof d'électronique qui nous répétait cette phrase tout les jours

)
Collaborative spirit : mettre de l'énergie à résoudre les défis de la vie plutôt qu'à gérer des problèmes d'ego (y compris les siens)

Re: Fonction aléatoire sur un intervalle
Publié : jeu. 13/sept./2012 12:28
par Golfy
Le Soldat Inconnu a écrit :juste pour vérifier le que le random répartit bien le retour entre le min et le max
Code : Tout sélectionner
; procedure de génération de nombre aléatoire dans un intervalle (bornes incluses)
; by Golfy (2012-09)
;
Procedure.i rnd(min.i, max.i)
ProcedureReturn Random(max.i-min.i)+min.i
EndProcedure
Dim Cpt(9)
For x = 1 To 10000000
Aleatoire = rnd(0, 9)
Cpt(Aleatoire) = Cpt(Aleatoire) + 1
Next
For x = 0 To 9
Debug Str(x) + " = " + Str(Cpt(x))
Next
Excellent cet algo de répartition : je n'avais pas cherché dans la bonne direction... ça devrait me servir pour de la supervision de trames ! merci
[Edit] à condition de n'avoir que des nombres positifs

Re: Fonction aléatoire sur un intervalle
Publié : jeu. 13/sept./2012 13:29
par Le Soldat Inconnu
pour des nombres négatif, tu peux partir sur une MAP
Code : Tout sélectionner
; procedure de génération de nombre aléatoire dans un intervalle (bornes incluses)
; by Golfy (2012-09)
;
Procedure.i rnd(min.i, max.i)
ProcedureReturn Random(max.i-min.i)+min.i
EndProcedure
NewMap Cpt()
For x = 1 To 1000000
Aleatoire.s = Str(rnd(-10, 10))
Cpt(Aleatoire) = Cpt(Aleatoire) + 1
Next
For x = -10 To 10
Debug Str(x) + " = " + Str(Cpt(Str(x)))
Next
ou sinon, avec un offset
Code : Tout sélectionner
; procedure de génération de nombre aléatoire dans un intervalle (bornes incluses)
; by Golfy (2012-09)
;
Procedure.i rnd(min.i, max.i)
ProcedureReturn Random(max.i-min.i)+min.i
EndProcedure
Dim Cpt(20)
For x = 1 To 1000000
Aleatoire = rnd(-10, 10)
Cpt(Aleatoire + 10) = Cpt(Aleatoire + 10) + 1
Next
For x = -10 To 10
Debug Str(x) + " = " + Str(Cpt(x + 10))
Next
Re: Fonction aléatoire sur un intervalle
Publié : jeu. 13/sept./2012 16:11
par Ar-S
Quitte à simplifier la syntaxe :
Changer
Cpt(Aleatoire + 10) = Cpt(Aleatoire + 10) + 1
devient
Cpt(Aleatoire + 10) + 1 suffit
Petit rappel :
N'oubliez pas que pure basic permet ce genre d'incrémentation directe.
a$ = "toto"
pour ajouter "titi" à a$ ce n'est pas utile de ré-écrire
a$ = a$ + "titi"
Vous pouvez simplement mettre
a$ + titi$
On fait bien comme on veut (ou comme on a l'habitude) mais
c'est bien de le savoir.
fred a écrit :Si min = max, tu devrais renvoyer 'min', pas 0

C'est pas faux. Le 0 est plus là pour dire "Hum y'a une couille dans l'gigot"

Mais c'est vrai que renvoyer une des 2 valeurs est plus juste.
Re: Fonction aléatoire sur un intervalle
Publié : ven. 14/sept./2012 8:19
par Golfy
Merci LSI : je ne connaissais pas les MAP (je pensais que c'était lié aux fonctions 3D)
C'est vraiment génial et simple... comme beaucoup de choses en PureBasic
