Download MetaTrader 5

get random from a list of value

To add comments, please log in or register
DavidHuynh
33
DavidHuynh  

Dear fellow trader,

Let's say I have a list of value {1,4,9,6}. How to get a random value from this list?

Thank you very much!

whroeder1
17122
whroeder1  
DavidHuynh: Let's say I have a list of value {1,4,9,6}. How to get a random value from this list?
Choose a number from zero to three and get that element.
// MathRand() / 32768. is [0..1) * (max-min) + min is [min..max)
int Random(int max, int min=0){ return int( MathRand() / 32768. * (max-min) + min); }
int list[] = {1, 4, 9, 6};
int index = Random(ArraySize(list));
int value = list[index];
Alain Verleyen
Moderator
29870
Alain Verleyen  
whroeder1:
Choose a number from zero to three and get that element.
You have a typo in your formula.
whroeder1
17122
whroeder1  
You're right. Must be times (max-min)
Carl Schreiber
Moderator
7962
Carl Schreiber  

Wouldn't it do a simple:

int randCell = list[ rand()%ArraySize(list)  ];
The probability is not in all cases absolutely equal (if 32767 cannot be divided by the size) - but may be negligible?
nicholishen
1546
nicholishen  
whroeder1:
No I don't. An array of length 4 has elements [0..3] Random(4) returns [0..4) == [0..3] with equal probability.

Alain is right, check it again.

@Carl Schreiber

Your solution is the best. The distribution will be as equal as can be. 

void OnStart()
{
   long cnt = 1000000;
   long a=0,b=0,c=0,d=0;
   srand(GetTickCount());
   for(long i=0;i<cnt;i++)
   {
      int res = rand()%4;
      if(res==0)     a++;
      else if(res==1)b++;
      else if(res==2)c++;
      else if(res==3)d++;
   }
   Print("a = ",a," - ",DoubleToString((double)a/(double)cnt*100,4)+"%");
   Print("b = ",b," - ",DoubleToString((double)b/(double)cnt*100,4)+"%");
   Print("c = ",c," - ",DoubleToString((double)c/(double)cnt*100,4)+"%");
   Print("d = ",d," - ",DoubleToString((double)d/(double)cnt*100,4)+"%");
}

result:

a = 250006 - 25.0006%

b = 249930 - 24.9930%

c = 249999 - 24.9999%

d = 250065 - 25.0065%

Carl Schreiber
Moderator
7962
Carl Schreiber  

@Carl Schreiber

Your solution is the best.

Thank you for your kindness, Sir - may I stay at home tomorrow?

whroeder1
17122
whroeder1  
nicholishen: Alain is right, check it again.

Your solution is the best. The distribution will be as equal as can be.

Corrected.
Carl's modulo is the best because 32768 is an exact multiple of four. Change it to five and the standard deviation goes up.
Random Modulo
19999043 20005727
19996800 19990510
20003446 20000756
20007574 20000035
19993137 20002972
5645.735750.31std dev
nicholishen
1546
nicholishen  
whroeder1:
Corrected.
Carl's modulo is the best because 32768 is an exact multiple of four. Change it to five and the standard deviation goes up.
Random Modulo
19999043 20005727
19996800 19990510
20003446 20000756
20007574 20000035
19993137 20002972
5645.735750.31std dev

The distribution is still equal... I've run this test several times with many different numbers and never get more that 1/100th of a percent deviation of the distribution. 

void OnStart()
{
   #define  N  5
   long cnt = 100000000;  
   long count[N]={0};
   srand(GetTickCount());
   for(long i=0;i<cnt;i++)
      count[rand()%N]+=1;
      
   for(int i=0;i<ArraySize(count);i++)
      Print("index[",i,"] = ",count[i]," | ",NormalizeDouble((double)count[i]/(double)cnt*100,2),"%");
}
Carl Schreiber
Moderator
7962
Carl Schreiber  

You can get equal probabilities if you reject any random number above a limit.

This limit is the greatest number with rand()%ArrSize == ArrSize - 1;

To add comments, please log in or register