Understanding “randomness”

前端 未结 28 2044
轻奢々
轻奢々 2020-11-22 15:28

I can\'t get my head around this, which is more random?

rand()

OR:

rand() * rand()

I´m f

相关标签:
28条回答
  • 2020-11-22 16:01

    Some things about "randomness" are counter-intuitive.

    Assuming flat distribution of rand(), the following will get you non-flat distributions:

    • high bias: sqrt(rand(range^2))
    • bias peaking in the middle: (rand(range) + rand(range))/2
    • low:bias: range - sqrt(rand(range^2))

    There are lots of other ways to create specific bias curves. I did a quick test of rand() * rand() and it gets you a very non-linear distribution.

    0 讨论(0)
  • 2020-11-22 16:01

    Floating randoms are based, in general, on an algorithm that produces an integer between zero and a certain range. As such, by using rand()*rand(), you are essentially saying int_rand()*int_rand()/rand_max^2 - meaning you are excluding any prime number / rand_max^2.

    That changes the randomized distribution significantly.

    rand() is uniformly distributed on most systems, and difficult to predict if properly seeded. Use that unless you have a particular reason to do math on it (i.e., shaping the distribution to a needed curve).

    0 讨论(0)
  • 2020-11-22 16:01

    Actually, when you think about it rand() * rand() is less random than rand(). Here's why.

    Essentially, there are the same number of odd numbers as even numbers. And saying that 0.04325 is odd, and like 0.388 is even, and 0.4 is even, and 0.15 is odd,

    That means that rand() has a equal chance of being an even or odd decimal.

    On the other hand, rand() * rand() has it's odds stacked a bit differently. Lets say:

    double a = rand();
    double b = rand();
    double c = a * b;
    

    a and b both have a 50% precent chance of being even or odd. Knowing that

    • even * even = even
    • even * odd = even
    • odd * odd = odd
    • odd * even = even

    means that there a 75% chance that c is even, while only a 25% chance it's odd, making the value of rand() * rand() more predictable than rand(), therefore less random.

    0 讨论(0)
  • 2020-11-22 16:01

    Assuming that rand() returns a number between [0, 1) it is obvious that rand() * rand() will be biased toward 0. This is because multiplying x by a number between [0, 1) will result in a number smaller than x. Here is the distribution of 10000 more random numbers:

    google.charts.load("current", { packages: ["corechart"] });
    google.charts.setOnLoadCallback(drawChart);
    
    function drawChart() {
      var i;
      var randomNumbers = [];
      for (i = 0; i < 10000; i++) {
        randomNumbers.push(Math.random() * Math.random());
      }
      var chart = new google.visualization.Histogram(document.getElementById("chart-1"));
      var data = new google.visualization.DataTable();
      data.addColumn("number", "Value");
      randomNumbers.forEach(function(randomNumber) {
        data.addRow([randomNumber]);
      });
      chart.draw(data, {
        title: randomNumbers.length + " rand() * rand() values between [0, 1)",
        legend: { position: "none" }
      });
    }
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    
    <div id="chart-1" style="height: 500px">Generating chart...</div>

    If rand() returns an integer between [x, y] then you have the following distribution. Notice the number of odd vs even values:

    google.charts.load("current", { packages: ["corechart"] });
    google.charts.setOnLoadCallback(drawChart);
    document.querySelector("#draw-chart").addEventListener("click", drawChart);
    
    function randomInt(min, max) {
      return Math.floor(Math.random() * (max - min + 1)) + min;
    }
    
    function drawChart() {
      var min = Number(document.querySelector("#rand-min").value);
      var max = Number(document.querySelector("#rand-max").value);
      if (min >= max) {
        return;
      }
      var i;
      var randomNumbers = [];
      for (i = 0; i < 10000; i++) {
        randomNumbers.push(randomInt(min, max) * randomInt(min, max));
      }
      var chart = new google.visualization.Histogram(document.getElementById("chart-1"));
      var data = new google.visualization.DataTable();
      data.addColumn("number", "Value");
      randomNumbers.forEach(function(randomNumber) {
        data.addRow([randomNumber]);
      });
      chart.draw(data, {
        title: randomNumbers.length + " rand() * rand() values between [" + min + ", " + max + "]",
        legend: { position: "none" },
        histogram: { bucketSize: 1 }
      });
    }
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    
    <input type="number" id="rand-min" value="0" min="0" max="10">
    <input type="number" id="rand-max" value="9" min="0" max="10">
    <input type="button" id="draw-chart" value="Apply">
    
    <div id="chart-1" style="height: 500px">Generating chart...</div>

    0 讨论(0)
  • 2020-11-22 16:01

    The answer would be it depends, hopefully the rand()*rand() would be more random than rand(), but as:

    • both answers depends on the bit size of your value
    • that in most of the cases you generate depending on a pseudo-random algorithm (which is mostly a number generator that depends on your computer clock, and not that much random).
    • make your code more readable (and not invoke some random voodoo god of random with this kind of mantra).

    Well, if you check any of these above I suggest you go for the simple "rand()". Because your code would be more readable (wouldn't ask yourself why you did write this, for ...well... more than 2 sec), easy to maintain (if you want to replace you rand function with a super_rand).

    If you want a better random, I would recommend you to stream it from any source that provide enough noise (radio static), and then a simple rand() should be enough.

    0 讨论(0)
  • 2020-11-22 16:02

    "random" vs. "more random" is a little bit like asking which Zero is more zero'y.

    In this case, rand is a PRNG, so not totally random. (in fact, quite predictable if the seed is known). Multiplying it by another value makes it no more or less random.

    A true crypto-type RNG will actually be random. And running values through any sort of function cannot add more entropy to it, and may very likely remove entropy, making it no more random.

    0 讨论(0)
提交回复
热议问题