Fonction aléatoire sur un intervalle

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Golfy
Messages : 423
Inscription : mer. 25/août/2004 15:14
Localisation : Grenoble
Contact :

Fonction aléatoire sur un intervalle

Message 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 :lol:

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
Purebasic 5.30 full sous Windows XP (x86) et Win7 (64 bits), Linux Debian. Orientation réseaux, domotique
http://golfy.olympe.in/Teo-Tea/
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Fonction aléatoire sur un intervalle

Message 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" :mrgreen:
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Fonction aléatoire sur un intervalle

Message 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
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Fonction aléatoire sur un intervalle

Message 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 :)
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Fonction aléatoire sur un intervalle

Message 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.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Fonction aléatoire sur un intervalle

Message par Backup »

c'est clair :)
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Fonction aléatoire sur un intervalle

Message par falsam »

Réponse de ..... moi :mrgreen: 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
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Fonction aléatoire sur un intervalle

Message 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.
Dernière modification par Ar-S le jeu. 13/sept./2012 16:13, modifié 1 fois.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Fred
Site Admin
Messages : 2808
Inscription : mer. 21/janv./2004 11:03

Re: Fonction aléatoire sur un intervalle

Message par Fred »

Si min = max, tu devrais renvoyer 'min', pas 0 :)
Golfy
Messages : 423
Inscription : mer. 25/août/2004 15:14
Localisation : Grenoble
Contact :

Re: Fonction aléatoire sur un intervalle

Message 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...") :oops:
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) :)
Dernière modification par Golfy le jeu. 13/sept./2012 12:32, modifié 1 fois.
Purebasic 5.30 full sous Windows XP (x86) et Win7 (64 bits), Linux Debian. Orientation réseaux, domotique
http://golfy.olympe.in/Teo-Tea/
Golfy
Messages : 423
Inscription : mer. 25/août/2004 15:14
Localisation : Grenoble
Contact :

Re: Fonction aléatoire sur un intervalle

Message 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 :oops:
Purebasic 5.30 full sous Windows XP (x86) et Win7 (64 bits), Linux Debian. Orientation réseaux, domotique
http://golfy.olympe.in/Teo-Tea/
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Fonction aléatoire sur un intervalle

Message 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
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Fonction aléatoire sur un intervalle

Message 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.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Golfy
Messages : 423
Inscription : mer. 25/août/2004 15:14
Localisation : Grenoble
Contact :

Re: Fonction aléatoire sur un intervalle

Message 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 :)
Purebasic 5.30 full sous Windows XP (x86) et Win7 (64 bits), Linux Debian. Orientation réseaux, domotique
http://golfy.olympe.in/Teo-Tea/
Répondre