javascript:生成由特定"边距分隔的随机数"

时间:2018-01-06 20:17:25

标签: javascript d3.js random

我想在xa之间生成b随机数。这个x随机数中的每一个都不应该与y的其他随机数更接近:

如果y = 100那么我不应该生成500和555但500和601就可以了。

更多背景信息: 我希望生成xd3.js,但不要相互接触(因此y将是较大圈子的半径)。我可以使用类似this的内容,但我更喜欢不使用force()的内容。

3 个答案:

答案 0 :(得分:3)

最简单的方法是在Math.random()上循环,直到你得到一个不在禁飞区的答案。缺点是对Math.random的一些不必要的调用,但如果禁飞空间与范围相比较小,那么它就不会很重要。

更新:避免结果的历史记录。乐趣。

let history = [];
function myRand(range, margin) {
    while(true) {
        let result = Math.trunc(Math.random() * range);
        if (history.every(last => {
            return Math.abs(result - last) > margin;
        })) {
            history.push(result);
            return result;
        }
    }
}

for (let i = 0; i < 5; i++)
    console.log(myRand(100, 10));

答案 1 :(得分:2)

我会制作一个简单的b树,并随着时间的推移跟踪节点。这应该非常快速和可靠。

&#13;
&#13;
let MAX = 100
let MIN = 0
let BUFFER = 10
let MAXCOUNT = 6

function randomBetween(min, max) {
  return {
    val: Math.floor(Math.random() * (max - min + 1) + min)
  }
}

function addLeaves(f, min = MIN - BUFFER, max = MAX + BUFFER, arr = []) {
  if (arr.length >= MAXCOUNT) return arr
  arr.push(f.val)
  f.left = (min + BUFFER < f.val - BUFFER) && addLeaves(randomBetween(min + BUFFER, f.val - BUFFER), min, f.val, arr)
  f.right = (f.val + BUFFER < max - BUFFER) && addLeaves(randomBetween(f.val + BUFFER, max - BUFFER), f.val, max, arr)
  return arr
}


let res = addLeaves(randomBetween(MIN, MAX))
console.log(res)
&#13;
&#13;
&#13;

这将提供由MAXCOUNT分隔的最多BUFFER个值。如果在给定大缓冲区的范围内没有空间,则可能返回少于MAXCOUNT。由于b树的性质,它将根据需要填补空白。

编辑:

由于我们实际上并没有使用树形结构(在其他情况下可能会有用),因此可以重写它以使用原始数字。这会将其更改为单个函数调用,以使重用更容易:

&#13;
&#13;
function getRandom(min, max, buffer, maxcount) {
  let randomBetween = (min, max) => Math.floor(Math.random() * (max - min + 1) + min)

  function addLeaves(f, min, max, arr = []) {
    if (arr.length < maxcount) {
      arr.push(f);
        if(min + buffer < f - buffer) addLeaves(randomBetween(min + buffer, f - buffer), min, f, arr);
        if(f + buffer < max - buffer) addLeaves(randomBetween(f + buffer, max - buffer), f, max, arr);
    }
    return arr
  }
  return addLeaves(randomBetween(min, max), min - buffer, max + buffer)
}
// now you can call with just: min, max, buffer, maxcount
let res = getRandom(0, 100, 10, 6)
console.log(res)
&#13;
&#13;
&#13;

答案 2 :(得分:1)

这是另一种方法,虽然对我来说感觉不那么随意。在狭窄空间的情况下,它不会冒无限循环的风险。

function randomWithMargin(start, stop, count, margin) {
    let spacing = Math.trunc((stop - start) / count);
    let left = start;
    let right = start + spacing;

    let results = [];
    while (count--) {
        let r = left + Math.trunc(Math.random() * (right - left));
        results.push(r);
        left = r + margin;    // ensure next number is at least margin from last
        right += spacing;    
    }
    return results;
}

console.log(randomWithMargin(10, 110, 10, 7));