【问题标题】:Javascript Math.random() returning very similar valuesJavascript Math.random() 返回非常相似的值
【发布时间】:2019-04-29 08:41:46
【问题描述】:

所以我有 position: absolute 的元素,然后我使用 Math.random() 设置它们的 left:#random 和 top:#random 位置。

然而,一件非常奇怪的事情正在发生。它应该是完全随机的,因此它们应该完全随机放置。然而,一次又一次,它们非常紧密地放在一起。而不是分散开来。

但是你可以清楚地看到,它们的位置确实是随机的:

这是我用来生成它们的代码:

const Clouds = function(props) {
    const clouds = []
    for (let i = 0; i < props.cloudNum; i++) {
        const style = {
            position: 'absolute',
            height: 50 * props.cloudSize + 'px',
            top: Math.random() * 100 + '%',
            left: Math.random() * 100 + '%',
        }
        clouds.push(<Cloud key={i} style={style} />)
    }
    return <div className={props.side}>{clouds}</div>
}

Math.random 是否有时间分量,因为它们是按顺序生成的,所以它们的随机数相似?

【问题讨论】:

  • 这种情况总是发生,还是偶尔发生?因为真正的随机数(不是Math.random() 生成的那些是真正随机的,但它们应该足以满足大多数目的)会比人们天真地期望“随机”数字更频繁地“聚集在一起”做。但是如果你说这些值总是在一个狭窄的范围内,比如总是 51.xxxx,而不是 0-100 之间的任何地方,那么这看起来确实很奇怪,我无法从给出的代码 sn-p 中解释它.
  • 随机并不意味着平均分布。真正随机的数据应该有一些点簇靠近在一起,因为每个点都应该有平等的机会被选中。这是每次都在特定范围内发生还是会发生变化?
  • cryptoObj.getRandomValues() 是 Math.random 的替代品,试试这个
  • 我明白了。要回答@RobinZigmond,不,他们并不总是在 51 岁左右。只是很多次。但是你们提出了一个很好的观点。我可能只是误解了随机意味着什么

标签: javascript reactjs math


【解决方案1】:

事实上,虽然它们看起来像相似的数字,但它们并不相似(请记住,您是乘以 100),这意味着您的随机数空间从 0 变为 100(因为图中的小数几乎没有价值,因为是你问的情况)。

请记住,如果您的空间是 100 朵云,仅生成 13 朵云,那么由于生日问题,两朵云占据相同位置的概率超过 50%。

https://en.wikipedia.org/wiki/Birthday_problem

【讨论】:

    【解决方案2】:

    您获得相似的价值是一个巧合。使用我的 sn-p 尝试多次,然后自己进行测试。

    请注意,我的对象比您的要小得多,没有元素重叠可以更好地理解随机性。恕我直言,如果您正在生成云(取决于目的),最好使用perlin noise

    const container = document.getElementById('container');
    
    const Clouds = function() {
       
        for (let i = 0; i <10; i++) {        
             let myCloud = document.createElement("div");
            myCloud.style.height = '15px';
                    myCloud.style.width = '15px';
            myCloud.style.position = 'absolute';
            myCloud.style.background =  '#fff';
            myCloud.style.border = '1px solid #ccc';
            myCloud.style.left = Math.random()*100+'%';
            myCloud.style.top = Math.random()*100+'%';
            container.appendChild(myCloud);
        }
       
    }
    
    function generate() {
     container.innerHTML = '';
     Clouds();
    }
    #container {
      position: absolute;
      top: 0;
      right: 0;
      left: 0;
      bottom: 0;
      background: red;
    }
    
    button {
    position: absolute;
    z-index: 999;
    }
    <div id="container"></div>
    <button onClick="generate()">Generate</button>

    【讨论】:

    • 很抱歉,我应该解释得更好。这种情况一次又一次地发生。我会尝试使用柏林噪声。谢谢! :)
    • 然而,即使使用您的 sn-p,将大多数对象放在“单”轴上也是很常见的。像这样:prntscr.com/niavcw
    • 这并不像您想象的那么常见,并且随着您增加容器大小而不太常见。这与上面的生日问题有关。如果您不想要相似的坐标,最好使用分布算法而不是随机生成器。
    【解决方案3】:

    没有时间组件 - 它只是由系统生成。 Here's 一个很好的解释它的线程。随机算法取决于 JavaScript 引擎(该线程中有一个 V8 答案),但该函数总是产生一个介于 0 和 1 之间的浮点数。您的代码产生了两个接近的数字,这是一个非常大的巧合。

    【讨论】:

    • 我应该说,这种情况一直在发生。这里是另一个例子:prntscr.com/niaw1v
    猜你喜欢
    • 1970-01-01
    • 2022-01-15
    • 2015-04-30
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    相关资源
    最近更新 更多