【问题标题】:Fill an array with distanced random integers用有距离的随机整数填充数组
【发布时间】:2020-05-29 10:17:35
【问题描述】:

我需要一个用随机整数填充的数组 这些整数应该彼此非常不同,即每个项目之间必须至少有 20 个分隔单位

这是我迄今为止尝试过的:

var all = [];
var i = 0;

randomDiff();

function randomDiff() {
    var num1 = randomNumber(10, 290); //chose a first random num in the range...
    all[0] = num1; //...put it in first index of array
    do // until you have 12 items...
    {
        var temp = randomNumber(10, 290); //...you pick a temporary num              
        var j;
        for (j = 0; j < all.length; j++) // for each item already in the array
        {
            if ((temp < all[i] - 10) || (temp > all[i] + 10)) // if the temporary num is different enough                                                            from others members...
            {
                all.push(temp); //then you can store it
                i++; //increment until....
                console.log(all[i]);
            }
        }
    }
    while (i < 11) // ...it is filled with 12 items in array    
}
////////////Radom in int range function///////////////////////////////////////
function randomNumber(min, max) {
    return Math.floor(Math.random() * (max - min) + min);
}

但总是不成功,包括无限循环……

【问题讨论】:

  • 您能否详细说明“必须至少有 20 个分隔单位”是什么意思?您需要列表中每个给定的数字对 x, y 为 |x - y| >= 20 ?
  • @antoniom ,数组中的所有项目都不能有一个更接近 10 个点的下邻居,也不能有一个最接近 10 个单位的上邻居,因为我对数学不满意这里是一个绘图 [链接]。@ 987654321@

标签: javascript arrays random


【解决方案1】:

看看这样的东西:

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

const LIST_SIZE = 20;
const DISTANCE = 10;

const STOP_AFTER_ATTEMPT = 2000;
const randomList = [];

let attempt = 0;
while(randomList.length < LIST_SIZE && attempt < STOP_AFTER_ATTEMPT) {

  const num = randomNumber(10, 290);

  const numberExistsWithSmallerDistance = randomList.some(r => Math.abs(r - num) < DISTANCE)

  if (!numberExistsWithSmallerDistance) {
    randomList.push(num);
  }

  attempt++;
}
if (randomList.length === LIST_SIZE) {
    console.log(randomList);
} else {
    console.log("Failed to create array with distnct values after ", attempt, " tries");
}

【讨论】:

    【解决方案2】:

    这是一个始终有效的解决方案,只要您在选择的范围/分隔/计数中留出足够的空间。而且它比while循环更有效。它不会一直尝试直到正确为止,它实际上会进行数学运算以确保第一次正确。

    这是以倾向于比其他数字更倾向于某些数字为代价的(例如from + (i * separation)),因此请注意这一点。

    function getSeparatedRadomInts(from, through, separation, count) {
      if(through < from) return getSeparatedRadomInts(through, from, separation, count);
      if(count == 0) return [];
      if(separation == 0) return !!console.log("Please allow enough room in the range/separation/count you choose.");
      
      //pick values from pool of numbers evenly stepped apart by units of separation... adding 1 to from and through if from is 0 so we can divide properly
      var smallFrom = Math.ceil((from || 1) / separation);
      var smallThrough = Math.floor((through + (from == 0)) / separation);
      var picks = randoSequence(smallFrom, smallThrough).slice(-count).sort((a, b) => a - b);
      if(picks.length < count) return !!console.log("Please allow enough room in the range/separation/count you choose.");
      for (var i = 0; i < picks.length; i++) picks[i] *= separation;
    
      //go through each pick and randomize with any wiggle room between the numbers above/below it... adding 1 to from and through if from is 0
      for (var i = 0; i < picks.length; i++) {
        var lowerBound = picks[i - 1] + separation || from || 1;
        var upperBound = picks[i + 1] - separation || (through + (from == 0));
        picks[i] = rando(lowerBound, upperBound);
      }
      
      //subtract 1 from all picks in cases where from is 0 to compensate for adding 1 earlier
      for (var i = 0; i < picks.length; i++) if(from == 0) picks[i] = picks[i] - 1;
      
      return picks;
    }
    
    console.log(getSeparatedRadomInts(10, 290, 20, 12));
    &lt;script src="https://randojs.com/1.0.0.js"&gt;&lt;/script&gt;

    要清楚,from 是最小范围值,through 是最大范围值,separation 是每个数字必须彼此分开的最小值(20 的分隔可能会导致 @例如 987654329@),count 是您要选择的值的数量。

    我在这段代码中使用了randojs 来简化随机性并使其更易于阅读,所以如果你想使用这段代码,请记住将其粘贴到 HTML 文档的头部:

    <script src="https://randojs.com/1.0.0.js"></script>
    

    【讨论】:

    • 乐于助人 :) 感谢您发布这个有趣的小问题
    猜你喜欢
    • 2013-09-16
    • 1970-01-01
    • 1970-01-01
    • 2014-05-10
    • 1970-01-01
    • 2011-01-23
    • 2017-06-04
    相关资源
    最近更新 更多