1

How would you implement a function that is returning a random number from interval 1..1000 in the case there is a number N determining the chance of reaching higher numbers or lower numbers?

It should behave as follows: e.g.

  • if N = 0 and we will generate many times the random number we will get a certain equilibrium (every number from interval 1..1000 has equal chance).
  • if N = 2321 (I call it positive factor) it will be very hard to achieve small number (often will be generated numbers > 900, sometimes numbers near 500 and rarely numbers < 100). The highest the positive factor the highest probability for high numbers
  • if N = -2321 (negative factor) this will be the opposite of positive factor

It's clear that the generated numbers will create for given N certain characteristic curve. Could you advise me how to achieve this goal and what curves can I create? What possibilities do I have here? How would you limit positive and negative factors etc.

thank you for help

xralf
  • 3,312
  • 45
  • 129
  • 200
  • and you have tried what exactly? – Woot4Moo Feb 21 '12 at 20:45
  • @Woot4Moo This is theory (knowledge question), the programming language is not so important here. – xralf Feb 21 '12 at 20:47
  • I understand theory quite well, my question still stands. – Woot4Moo Feb 21 '12 at 20:48
  • @Woot4Moo I don't orient in random functions so well, so I'm asking here. I tried to search first. – xralf Feb 21 '12 at 20:52
  • I see, i have a short explanation below, if anything isn't clear let me know and I will update. – Woot4Moo Feb 21 '12 at 20:54
  • @Woot4Moo OK, there are many things not clear, but I was leaving my room already, so after I'll return. – xralf Feb 21 '12 at 20:58
  • If you could provide a list of weights from the number `N`, then the [accepted answer to "Weighted random numbers"](http://stackoverflow.com/a/1761646/237483) would be a solution. – Christian Ammer Feb 21 '12 at 21:28
  • @ChristianAmmer it appears OP would want uniform distribution with no weights. – Woot4Moo Feb 21 '12 at 21:29
  • @Woot4Moo: I think with weights you can make any distribution, even a uniform (weights = {1, 1, 1, 1, ...}). You only need a function F(N) which produces the weights. – Christian Ammer Feb 21 '12 at 21:34
  • [A good explanation for picking random elements based on probabilities](http://stackoverflow.com/a/2772934/237483). – Christian Ammer Feb 21 '12 at 22:08
  • It would be useful (by which I mean, it would make it possible to solve this problem and/or offer useful advice) if you had some concrete probability distributions in mind. As opposed to "hard to achieve," "sometimes," "often," "rarely," etc. – Novak Feb 21 '12 at 22:36

3 Answers3

5

If you generate a uniform random number, and then raise it to a power > 1, it will get smaller, but stay in the range [0, 1]. If you raise it to a power greater than 0 but less than 1, it will get larger, but stay in the range [0, 1].

So you can use the exponent to pick a power when generating your random numbers.

def biased_random(scale, bias):
  return random.random() ** bias * scale

sum(biased_random(1000, 2.5) for x in range(100)) / 100
  291.59652962214676  # average less than 500

max(biased_random(1000, 2.5) for x in range(100))
  963.81166161355998  # but still occasionally generates large numbers

sum(biased_random(1000, .3) for x in range(100)) / 100
  813.90199860117821   # average > 500

min(biased_random(1000, .3) for x in range(100))
  265.25040459294883   # but still occasionally generates small numbers
Rob Neuhaus
  • 9,190
  • 3
  • 28
  • 37
  • No that is not correct. It appears you are looking at this definition of random from wikipedia: Most computer programming languages include functions or library routines that purport to be random number generators. They are often designed to provide a random byte or word, or a floating point number uniformly distributed between 0 and 1. The problem above can be solved using a human and therefore it is inappropriate to tie this to a computer. Further even more incorrect to state that it will be in the range of [0,1], with the caveat being that it is not done via a computer. – Woot4Moo Feb 21 '12 at 21:26
  • I have no idea what your objection is. He asked for an algorithm that generates a distribution with a particular distribution, and I showed him how to turn a uniform RNG into an RNG with a distribution that matches the specification. – Rob Neuhaus Feb 22 '12 at 02:25
  • my objection was you bound it to a computer rng, not a theoretical one. That is the only gripe I have, which stems from a comment OP left to me on his initial post about it not being a programming solution. – Woot4Moo Feb 22 '12 at 03:44
  • @Woot: The OP said it's not language specific, but it's safe to assume he'll be doing it in code. (And whatever language he's using, it's pretty safe to assume it comes with a uniform RNG... I don't think I've ever seen one which doesn't.) – Nick Barnes Feb 22 '12 at 06:10
  • @rrenaud This is exactly the kind of answer I was looking for. Showing some approach to generate these numbers and that's it's used in Python is even better. I have to experiment and see which curves are drawed. thanks a lot – xralf Feb 22 '12 at 11:47
2

This problem is severely underspecified. There are a million ways to solve it as it is mentioned.

Instead of arbitrary positive and negative values, try to think what is the meaning behind them. IMHO, beta distribution is the one you should consider. By selecting the parameters \alpha and \beta you should be appropriately modulate the behavior of your distribution.

See what shapes you can get with certain \alpha and \beta http://en.wikipedia.org/wiki/Beta_distribution#Shapes

http://en.wikipedia.org/wiki/File:Beta_distribution_pdf.svg

ElKamina
  • 7,747
  • 28
  • 43
1

Lets for beginning decide that we will pick numbers from [0,1] because it makes stuff simpler.
n is number that represents distribution (0,2321 or -2321) as in example
We need solution only for n > 0, because if n < 0. You can take positive version of n and subtract from 1.

One simple idea for PDF in interval [0,1] is x^n. (or at least this kind of shape)
Calculating CDF is then integrating x^n and is x^(n+1)/(n+1)
Because CDF must be 1 at the end (in our case at 1) our final CDF is than x^(n+1) and is properly weighted In order to generate this kind distribution from this, we must calaculate quantile function

Quantile function is just inverse of CDF and is in our case. x^(1/(n+1))

And that is it. Your QF is x^(1/(n+1))

To generate numbers from [0,1] you have to pick uniformly distributetd random from [0,1] (most common random function in programming languages)
and than power this whit (1/(n+1))

Only problem I see is that it can be problem to calculate 1-x^(1/(-n+1)) correctly, where n < 0 but i think that you can use log1p, so it becomes exp(log1p(-x^(1/(-n+1))) if n<0

conclusion whit normalizations

  if n>=0:  (x^(1/(n/1000+1)))*1000
  if n<0:   exp(log1p(-(x^(1/(-(n/1000)+1)))))*1000   
  where x is uniformly distributed random value in interval  [0,1]    
Luka Rahne
  • 10,336
  • 3
  • 34
  • 56