我想在x
和a
之间生成b
随机数。这个x
随机数中的每一个都不应该与y
的其他随机数更接近:
如果y = 100
那么我不应该生成500和555但500和601就可以了。
更多背景信息:
我希望生成x
圈d3.js
,但不要相互接触(因此y
将是较大圈子的半径)。我可以使用类似this的内容,但我更喜欢不使用force()
的内容。
答案 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树,并随着时间的推移跟踪节点。这应该非常快速和可靠。
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;
这将提供由MAXCOUNT
分隔的最多BUFFER
个值。如果在给定大缓冲区的范围内没有空间,则可能返回少于MAXCOUNT
。由于b树的性质,它将根据需要填补空白。
编辑:
由于我们实际上并没有使用树形结构(在其他情况下可能会有用),因此可以重写它以使用原始数字。这会将其更改为单个函数调用,以使重用更容易:
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;
答案 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));