0

Let say I have sorted array :

 ary = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

the goal is to randomly pick a number with HIGHER probability of selecting lower numbers. One way to do that is the following :

 ary[ int( rand() * rand() * 10) ]

or even :

 ary[ int( rand() * rand() * 11) ]

multiplying random numbers 0 < x < 1, on average will produce smaller numbers.

I was wondering if you know better more robust way to that ? Perfectly the "probability slope" of the chance of selecting number should approximate something like 1/x function or something like that.

1/x

hist( [ int(rand() * rand() * 11.) for _ in range(1000) ])

=== why duplicate ???? this is not weighted but distribution like, also not discrete distribution ??


hist(np.random.exponential(size=1000) )

Looks like an option, but how to bound it to 0 .. 10 i.e. pick ary-idx from 0 .. 10

sten
  • 7,028
  • 9
  • 41
  • 63
  • 3
    You might be interested in [`np.random.exponential`](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.random.exponential.html) or [`random.expovariate`](https://docs.python.org/3/library/random.html#random.expovariate) – cs95 Nov 17 '17 at 18:09
  • 1
    You can use https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_discrete.html to custom make a discrete distribution over any finite set of possibilities. – Bill Bell Nov 17 '17 at 18:09
  • What are you using for a domain with 1/x? I don't think you can do 0 to inf, the integral (to get the CDF) won't converge. – Nick T Nov 17 '17 at 18:13
  • I meant like 1/x, you can pick from 1.2 if you want .. i was more concerned with the slope rather than the domain of the values – sten Nov 17 '17 at 18:21
  • By domain, he means what does x represent? Since the list is sorted, x could be either the index or the value. – luther Nov 17 '17 at 18:35
  • 2
    As I see it, this *is* a weighted distribution, but it's weighted by a function rather than by a hard-coded table. – luther Nov 17 '17 at 18:38
  • with higher probability generate lower index for the array, so that lower value is chosen. i.e. the requirement is to generate index in a specified range , in this case 0 .. 10 – sten Nov 17 '17 at 18:39
  • 1
    In case it's not re-opened: `from scipy.stats import rv_discrete; ary = list(range(1,11)); probs = [1/_ for _ in ary]; probs = [_/sum(probs) for _ in probs]; custom = rv_discrete(values=(ary, probs)); custom.rvs(size=10)`. Try it. I have and it works, I promise you. – Bill Bell Nov 17 '17 at 18:43
  • If it misses the mark open another question and ask about it. – Bill Bell Nov 17 '17 at 18:44
  • If you're looking into behavior similar to exponential, there is a perfect match in the discrete world - geometric distribution. Select parameter `p` which fits your problem, reject any index beyond 10, code example is at https://stackoverflow.com/questions/46916789/randomly-generate-integers-with-a-distribution-that-prefers-low-ones/ – Severin Pappadeux Nov 17 '17 at 19:14

0 Answers0