2

I am using the following code to generate a random number:

function getRandomInt (min, max) {
    return Math.floor((Math.random() * (max - min + 1)) + min;
}

What I want to do is add a weighting that favours the numbers at the lower end of the range.

I thought about maybe trying to multiply the numbers by 1/cosine.

Would this work and does anyone know how I might go about it?

Many thanks!

Amit Verma
  • 40,709
  • 21
  • 93
  • 115
user3102815
  • 71
  • 1
  • 5
  • possible duplicate of [Generate A Weighted Random Number](http://stackoverflow.com/questions/8435183/generate-a-weighted-random-number) – Felix Kling Dec 14 '13 at 18:16
  • if you want a cosine distribution you have to apply the inverse cosine, that means arccos(x) with x being your uniform random sample – Marian Theisen Dec 14 '13 at 18:16
  • 1
    what distribution do you want? – Stephen Thomas Dec 14 '13 at 19:01
  • I am not sure how best to explain this. Imagine a logarithmic curve that goes from 0-1. If the RNG returns a value of 0.5 I want to apply a weighting to being it down to say, 0.2. If 1 is returned, I would like to keep the number up at around 1, and similarly 0 with 0. – user3102815 Dec 14 '13 at 19:24
  • Ask a new question. Your "edit" has completely changed the question. And ask ot on math exchange. – chiliNUT Dec 14 '13 at 21:04

2 Answers2

12

First Solution

You need a function which contains the points (0, 0) and (1, 1). For instance: x^n when n > 0

Math.pow(1, n) === 1

And

Math.pow(0, n) === 0

Therefore, you would just change n depending on how you want the weighting to work.

  • When n = 1 : y === x
  • When n > 1 : y <= x
  • When 0 < n < 1 : y >= x

So, if you want lower values to be favored over higher values, simply use n > 1.

var weighted = Math.pow(Math.random(), 2);

Then you can scale the result as usual.

var scaled = Math.floor(weighted * (max - min + 1)) + min;

y = x^2

Other Functions

Likewise, you could use any continuous function which contains the points (0, 0), (1, 1), and has range and domain of [0, 1].

Sine

y = sin(xπ/2)

Cosine

y = 1 - cos(xπ/2)
cwharris
  • 17,835
  • 4
  • 44
  • 64
2

EDIT: there was a type in the final formula, log(2+log(x)) is incorrect it should have been log(1+log(x))+1, its fixed now.

If you are using logarithmic weighting, using something like

var x = Math.random();
var weighted = x * Math.log(1+x);

would make 0.5 weigh in at around 0.2, but 1 would only weigh in at around 0.69.

Using this

var x = Math.random();
var weighted = x * Math.log(2 + Math.log(x));

would allow 1 to weigh in at 1. So combine them, and this

var x = Math.random();
var weighted = (x <= 0.5) ? x * Math.log(1 + x) : x * Math.log(1 + Math.log(x))+1;

should do the trick

chiliNUT
  • 18,989
  • 14
  • 66
  • 106
  • Although it wasn't explicitly required, I believe it's implied that the weighting function should be smooth. However, your solution is not continuous. f(0.5) != f'(0.5). Example output: `f(0.4999)= 0.20265867976566646` `f(0.5000) = 0.2027325540540822` `f(0.5001) = 0.409514145930273` `f(0.5002) = 0.4097216758223955` – cwharris Dec 14 '13 at 20:22
  • Did you mean to lerp? – cwharris Dec 14 '13 at 20:25
  • Its not smooth. It just meets the basic criteria. Seemsllike this question belongs on math exchange. A basic log weighting shouldnt require a designer function though, I'd say not enough info on the question, which I believe has already changed since this answer. – chiliNUT Dec 14 '13 at 21:02
  • And I don't think I should get a downvote for not meeting a criteria which is not explicitly required or "implied" – chiliNUT Dec 14 '13 at 21:03
  • 1
    Thank you both for your solutions, I will look at them in detail. And no, smoothness was not asked for, nor required. Also, the question has not changed - someone tried to edit and *helpfully* correct my grammar, where their's was no better than my own. So I reversed the changes. – user3102815 Dec 14 '13 at 22:33
  • @chiliNUT If you edit your answer, I will be able to remove my down-vote, and gladly. – cwharris Dec 17 '13 at 06:01
  • No I mean just literally, I would be glad to remove the down-vote if you made any edit what-so-ever. I just literally cannot remove it until you do. – cwharris Dec 19 '13 at 01:10