3

I need to generate random numbers with following properties.

  • Min must be 1
  • Max must be 9
  • Average (mean) is 6.00 (or something else)
  • Random number must be Integer (positive) only

I have tried several syntaxes but nothing works, for example

r=1+8.*rand(100,1);

This gives me a random number between 1-9 but it's not an integer (for example 5.607 or 4.391) and each time I calculate the mean it varies.

JJJ
  • 32,902
  • 20
  • 89
  • 102
Chanon
  • 41
  • 1
  • 4
  • 3
    What shape do you want for your distribution? – Jonas Mar 21 '12 at 15:48
  • For any RNG don't expect the mean will always be exactly as you specify, it will vary from run to run. With larger N it can be closer though. – yuk Mar 21 '12 at 17:44
  • type of distribution is not importance, just want mean is the same for each set of random numbers. – Chanon Mar 22 '12 at 02:02

6 Answers6

4

You may be able to define a function that satisfies your requirements based on Matlab's randi function. But be careful, it is easy to define functions of random number generators which do not produce random numbers.

Another approach might suit -- create a probability distribution to meet your requirements. In this case you need a vector of 9 floating-point numbers which sum to 1 and which, individually, express the probability of the i-th integer occurring. For example, a distribution might be described by the following vector:

[0.1 0.1 0.1 0.1 0.2 0.1 0.1 0.1 0.1]

These split the interval [0,1] into 9 parts. Then, take your favourite rng which generates floating-point numbers in the range [0,1) and generate a number, suppose it is 0.45. Read along the interval from 0 to 1 and you find that this is in the 5-th interval, so return the integer 5.

Obviously, I've been too lazy to give you a vector which gives 6 as the mean of the distribution, but that shouldn't be too hard for you to figure out.

High Performance Mark
  • 77,191
  • 7
  • 105
  • 161
2

You can use randi to get random integers

Ali
  • 18,665
  • 21
  • 103
  • 138
2

Here is an algorithm with a loop to reach a required mean xmean (with required precision xeps) by regenerating a random number from one half of a vector to another according to mean at current iteration. With my tests it reached the mean pretty quick.

n = 100;
xmean = 6;
xmin = 1;
xmax = 9;
xeps = 0.01;
x = randi([xmin xmax],n,1);
while abs(xmean - mean(x)) >= xeps
    if xmean > mean(x)
        x(find(x < xmean,1)) = randi([xmean xmax]);
    elseif xmean < mean(x)
        x(find(x > xmean,1)) = randi([xmin xmean]);
    end
end

x is the output you need.

yuk
  • 19,098
  • 13
  • 68
  • 99
  • this syntax give me --- ??? Undefined function or method 'randi' for input arguments of type 'double'.---- T-T help me pls. – Chanon Mar 22 '12 at 02:09
  • Function `randi` (to generate random integers) appeared first in MATLAB version 2008b. Probably yours is older. See this [SO answer](http://stackoverflow.com/questions/6415424/using-rand-in-matlab-to-produce-numbers-between-limits/6415698#6415698). – yuk Mar 22 '12 at 03:10
  • the algorithm that you gave to me just work fine on MATLAB2010b, thanks to you alot ^^ but sometime mean is not integer number such as 6.65 or 4.77 then this algorithm rejected to generate number for me T-T how can I use mean that is not integer ? – Chanon Mar 24 '12 at 11:34
  • You've never said the mean has to be integer what you need it for. Please explain. And what is T-T? – yuk Mar 24 '12 at 12:27
  • I'm so sorry about didn't told you clearly ^^" and want to say thanks to you a lot again, yuk. Your algorithm just save my life for a while. I have to say I'm new to MATLAB or statistic like this, never do this before in my life but still try to learn. So, it is possible to set mean in to not-integer value ? This set of random numbers I'll use to prove something that hard to explain with my broken english like this ^^" Just in case, sometimes mean is not integer value and this algorithm failed to generate ^^ so, it is possible ? – Chanon Mar 25 '12 at 09:44
  • I still son't understand. Do you need integer or non-integer mean. Yes, you can set `xmean` to non-integer value. If `xmean` in integer, you can try to set `xeps` to a very small number, like `xeps=eps(0);`, but I cannot guarantee how many iterations it will require. Function `mean` is always returns double, so `xeps=0` may not work due to nature of double values. – yuk Mar 26 '12 at 14:55
  • Another question is about the algorithm which fails. Is it in MATLAB? If not, is it in another language or just program? How do you pass the generated numbers? Do you have to provide the mean to that algorithm or it's calculated there itself? – yuk Mar 26 '12 at 14:56
  • For statistical questions I'd recommend you to ask at http://stats.stackexchange.com/ – yuk Mar 26 '12 at 14:57
1

You could use floor to truncate your random numbers to integer values only:

r = 1 + floor(9 * rand(100,1));

Obtaining a specified mean is a little trickier; it depends what kind of distribution you're after.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
1

Before you can design your random number generator you need to specify the distribution it should draw from. You've only partially done that: i.e., you specified it draws from integers in [1,9] and that it has a mean that you want to be able to specify. That still leaves an infinity of distributions to chose among. What other properties do you want your distribution to have?

Edit following comment: The mean of any finite sample from a probability distribution - the so-called sample mean - will only approximate the distribution's mean. There is no way around that.

That having been said, the simplest (in the maximum entropy sense) distribution over the integers in the domain [1,9] is the exponential distribution: i.e.,

p = @(n,x)(exp(-x*n)./sum(exp(-x*(1:9))));

The parameter x determines the distribution mean. The corresponding cumulative distribution is

c = cumsum(p(1:9,x));

To draw from the distribution p you can draw a random number from [0,1] and find what sub-interval of c it falls in: i.e.,

samp = arrayfun(@(y)find(y<c,1),rand(n,m));

will return an [n,m] array of integers drawn from p.

lsfinn
  • 446
  • 2
  • 4
  • any type of distribution is okay, type of distribution is not importance, just want mean is the same for each set of random numbers. thanks. – Chanon Mar 22 '12 at 02:04
1

If the distribution is not important and all you're interested in is the mean, then there's a particularly simple function that does that:

function x=myrand
 x=6;
end
yohai
  • 438
  • 5
  • 15