3

Seems simple, but I'd like a formula (.net preferably) which:

For a given number- say, 1.5 - the formula will output a random number which taken over a series will average around 1.5... so it could be 0.1, 1.2, 7.1, 2.5, .2, etc, but the average value will be close to 1.5.

clarification: I would like the numbers to be positive.

Brady Moritz
  • 8,624
  • 8
  • 66
  • 100
  • Why not specify a range for your random number. You could even divide the result by 100 to get the float. – Botonomous Jul 09 '13 at 21:12
  • There are a lot of moving pieces there. Do you need to guarantee that it will be around 1.5 after N items, or just "probably"? How big a range will you allow? – Joe Enos Jul 09 '13 at 21:13
  • 2
    if 1.5 is your average, would you expect -1000 and 1003 to be valid values? What are your extrema? – Reacher Gilt Jul 09 '13 at 21:14
  • any range with 1.5 as the middle will tend to average 1.5 – Keith Nicholas Jul 09 '13 at 21:15
  • Do you want a uniform distribution? That's normally the case with random numbers but it changes the answer if you don't. – Mark Ransom Jul 09 '13 at 21:24
  • Do you want the range (support of the random variable) to be all of the positive "real" numbers? There are many ways you could obtain that. (I noticed `7.1` was a lot larger than the average `1.5`.) – Jeppe Stig Nielsen Jul 09 '13 at 21:36
  • yeah that's the part I wasn't sure about - do I need to define a range? or is there a simple algo that can pick any number, but the probability of a really big one is very low... my brain hurts... – Brady Moritz Jul 09 '13 at 21:37
  • added detail - yes, id like the values to real ie positive values. – Brady Moritz Jul 09 '13 at 21:39
  • 1
    so you want lopsided random numbers? ie, a range 0.0 -> 20.0 but averaging 1.5? – Keith Nicholas Jul 09 '13 at 21:41
  • Always returning 1.5 fits the original problem. This isn't well posed with a specification of the distribution you are drawing from. – Nick Cox Jul 09 '13 at 21:42
  • Perhaps you want a χ²-distribution (chi squared)? You might want to do some research into what type of statistical distribution you want before figuring out how to code it. – Kirk Broadhurst Jul 09 '13 at 21:44

2 Answers2

2
public class RandomAroundAverage
    {
        Random r = new Random();
        public double Random(double middle, double scale)
        {
            return r.NextDouble() * scale - (scale / 2) + middle;
        }
    }

then

var v = r.Random(1.5, 20);

and it will generate random numbers -8.5 -> 11.5

and to see it in action...

 

   var r = new RandomAroundAverage();
    var sum = 0.0;
    for (int i = 0; i < 10000; i++)
    {
        var v = r.Random(1.5, 20);
        sum += v;
        Console.WriteLine(string.Format("Value: {0} Average: {1}", v, sum/i)); 
    }
Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
  • +1 for a simple, clear solution. You can simplify it even more, and eliminate the division, by returning `(r.NextDouble() - 0.5) * scale + middle` – Adam Liss Jul 10 '13 at 01:26
  • Note that if you want positive numbers only, `scale` must be less than or equal to `2*middle`. – Mark Ransom Jul 11 '13 at 03:26
1

There are lots of possible ways to do it. One of these, which is always positive, is to generate exponentially distributed values. An algorithm to generate exponential random variates with a specified mean is:

public static double ExpRV(double mean, Random rnd) {
   return -mean * Math.Log(rnd.NextDouble());
}

[Editor's note: Converted to C#.]

When you crank out a bunch of those, the average should be fairly close to mean.

If you need a bounded range for the individual values you'll need a different distribution, but since you didn't specify that as a constraint this should do it for you.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
pjs
  • 18,696
  • 4
  • 27
  • 56