如何保证循环中出现一定数量的随机事件



我有一个程序,可以模拟时钟指针的旋转,它会随机跳到正常旋转量的2倍。我需要保证在一个完整的旋转中,我至少有n次跳跃。我应该如何在确保至少n次跳跃的情况下随机化它?

我曾想过每x次迭代都有一个保证的跳跃,但这不是随机的。

这是我的旋转循环代码:

for (let i = 0; i < ticks; i++) {           
// Move the clockhand by a position, sometimes by a greater amount 
setTimeout(() => {
let d = Math.random();
jump = false;
// Randomize and keep track of jumps
if (d < (probabilty/100)) {
jump = true;
}
}
}

一种方法是设置每次完整旋转的MAX_JUMPSMAX_TICKS数量,然后跟踪每次迭代中执行的跳跃和节拍数量。如果跳跃和滴答仍然没有达到最大数量,那么在它们之间随机选择。如果其中一个达到最大值,那么只需选择另一个,直到旋转完成。

这里是一个工作示例,其中保证了5跳跃的精确性。注意,我将DISTANCE设置为仅30,因为代码段控制台没有显示很多行。此外,超时延迟被设置为0,只是为了快速显示完整的结果。

const DISTANCE = 30 // change to 60
const MAX_JUMPS = 5
const MAX_TICKS = DISTANCE - 2 * MAX_JUMPS
const PROBABILITY = 0.25
let currentDistance = 0
let normalTicks = 0
let jumps = 0
function oneTick() {
if (currentDistance === DISTANCE) {
// Completed full rotation
console.log('normalTicks = ', normalTicks, ', jumps = ', jumps)
return
}
setTimeout(() => {
if (normalTicks === MAX_TICKS) {
// If we are out of normal ticks then just jump
// to satisfy the MAX_JUMPS amount
jump()
} else if (jumps === MAX_JUMPS) {
// If we run out of jumps, do normal tick
normal()
} else {
// If both ticks and jumps are available then randomly choose one
if (Math.random() > PROBABILITY) {
normal()
} else {
jump()
}

}
console.log(currentDistance)
oneTick()
}, 0 /* change to 1000 */)
}
function normal() {
normalTicks += 1
currentDistance += 1
}
function jump() {
jumps += 1
currentDistance += 2
console.log('JUMPED! Jumps left: ', MAX_JUMPS - jumps)
}
oneTick()
.as-console-wrapper {
min-height: 200px;
top: 0;
}

编辑:要使其至少执行MAX_JUMPS,然后随机执行更多跳跃,只需删除if (jumps === MAX_JUMPS)块:

const DISTANCE = 30 // change to 60
const MAX_JUMPS = 5
const MAX_TICKS = DISTANCE - 2 * MAX_JUMPS
const PROBABILITY = 0.25
let currentDistance = 0
let normalTicks = 0
let jumps = 0
function oneTick() {
if (currentDistance >= DISTANCE) {
console.log('normalTicks = ', normalTicks, ', jumps = ', jumps)
return
}
setTimeout(() => {
if (normalTicks === MAX_TICKS) {
jump()
} else {
if (Math.random() > PROBABILITY) {
normal()
} else {
jump()
}
}
console.log(currentDistance)
oneTick()
}, 0 /* change to 1000 */ )
}
function normal() {
normalTicks += 1
currentDistance += 1
}
function jump() {
jumps += 1
currentDistance += 2
console.log('JUMPED! Jumps performed: ', jumps)
}
oneTick()
.as-console-wrapper {
min-height: 200px;
top: 0;
}

请注意,这可能会导致它在旋转的最后一个刻度处跳跃,因此您必须决定是将其算作一个刻度,还是将额外的刻度添加到下一个旋转中。

最新更新