javascript - 生成等于 100 但两个数字之间的差必须大于 4 的 m 个数字

标签 javascript oop random numbers

我正在尝试生成等于 100(%) 的数字,但所有数字之间必须至少有 4 个数字。因此,如果我生成 4 个数字,它们必须像这样,例如 [22,28,15,35] 而不能像这样 [22,28,20,30] 因为 28-30 和 22-20 之间的差异小于 4。

我能够将生成数字的方法放在一起,看起来像这样。

generate (max, many) {
    this.numbers_array = []
    this.normalized_numbers_array = []
    this.sum = 0 
    for (let i = 0; i < many; i++) {
      this.numbers_array.push(Math.random())
      this.sum += this.numbers_array[i]  
    }
    this.remaining = max
    for (let i = 0; i < this.numbers_array.length; i++) {
      this.outcome= (this.numbers_array[i] / this.sum) * max
      this.normalized_numbers_array[i] = Math.floor(this.outcome)
      this.remaining -= this.normalized_numbers_array[i]
      if (i + 1 == this.numbers_array.length) {
        while (this.remaining > 0) {
          this.normalized_numbers_array[i]++
          this.remaining--
        }
      }
    }
  }  

并且工作正常。我的下一个方法是尝试通过两个 for 循环和 if 语句将规范化数字相互比较。然后根据彼此之间的数字差异,我希望对正在比较的两个数字将 2% 添加到一个并从另一个减去 2%。然后我将它们放入我想再次归一化的新数组中。

   for (let i = 0; i < this.normalized_numbers_array.length; i++) {

  for (let j = i + 1; j < this.normalized_numbers_array.length; j++) {

    if (Math.abs(this.normalized_numbers_array[i] - this.normalized_numbers_array[j]) < 5) {
        //do something
      if (this.normalized_numbers_array[i] > this.normalized_numbers_array[j]) {
        //do something
      } else if (this.normalized_numbers_array[i] <= this.normalized_numbers_array[j]) {
    //do something  
      }
    }
}

不过,这种方法是有缺陷的。通过添加或子结构,我可以创建小于 4 的新差异。例如 [35,18,26,21]->[35,16,26,23] 26 和 23 之间的差异更改后为3。

我的想法是创建另一个循环,只要存在差异就会继续下去。但我不确定这是否有效。所以我想知道是否有更好的解决方案来解决这个问题——也许能够从一开始就生成大小不同的数字,而不必在之后更改它们。

最佳答案

  • 从同一范围内生成四个统一的随机数
  • 缩放它们,使它们加起来达到 76(100 - 分隔符,见下文);根据需要随机调整以解决剩余问题
  • 插入分隔符:排序,然后第一个加 4,第二个加 8,最后一个加 12(第 0 个不调整)。

例子

  • 生成 [102, 387, 386, 284]
  • 比例:[102, 387, 386, 284] * 76/(102 + 387 + 386 + 284) 计算结果为 [6, 25, 25, 18]
  • 调整:那就只有74了,所以随机给两个元素加上1:[6, 25, 26, 19]
  • 排序:[6, 19, 25, 26]
  • 插入分隔符:[6, 23, 33, 38]

加起来为 100,保证至少相隔 4,[编辑] 很少的循环(以确保不被零除),并且对分布的任意干扰尽可能少。出于好奇,这是它的样子:

function f() {
  let q, s;
  while (!s) {
    q = Array.from({length: 4}, () => Math.random()); 
    s = q.reduce((a, e) => a + e);
  }
  q.forEach((e, i, q) => q[i] = (e * 76 / s)|0);
  s = q.reduce((a, e) => a + e);
  while (s < 76) {
    q[(Math.random() * 4)|0]++; s++;
  }
  q.sort((a, b) => a - b);
  q.forEach((e, i, q) => q[i] += i * 4);
  return q;
}


const N = 100000;
function draw() {
  const labels = ["#0", "#1", "#2", "#3", "Any"];
  const colours = ["red", "orange", "green", "blue", "black"];
  const data = Array.from({length:5}, (e, i) => ({
    label: labels[i],
    borderColor: colours[i],
    backgroundColor: i == 4 ? "rgba(0, 0, 0, 0.1)" : "rgba(0, 0, 0, 0)",
    pointRadius: 0,
    data: Array.from({length:100}, (e, i) => ({ x: i, y: 0 }))
  }));
  for (let s = 0; s < N; s++) {
    const q = f();
    q.forEach((e, i) => {
      data[i].data[e].y++;
      data[4].data[e].y++;
    });
  }

  const ctx = document.querySelector('canvas').getContext('2d');
  const myChart = new Chart(ctx, {
    type: 'line',
    data: {
        datasets: data
    },
    options: {
      maintainAspectRatio: false,
      animation: false,
      legend: {
        position: 'right'
      },
      scales: {
        yAxes: [{
          ticks: {
            beginAtZero: true
          }
        }],
        xAxes: [{
          type: 'linear',
          ticks: {
            beginAtZero: true,
            max: 100
          }
        }]
      }
    }
  });
};

draw();
document.querySelector('canvas').addEventListener('dblclick', draw);
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0/dist/Chart.min.js"></script>
<canvas width="400" height="180"/>

关于javascript - 生成等于 100 但两个数字之间的差必须大于 4 的 m 个数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56850470/

相关文章:

javascript - 从 PHP 中的 UTF-8 字符串中删除控制字符

javascript - 一般 float 学查询

python - 如何在 Python 中进行随机但部分随机播放?

random - VHDL案例陈述错误

JavaScript 根据第一个事件创建第二个事件

javascript - 排除站点 anchor 链接 JavaScript

php - 显示另一个表中的畅销商品和关联图像

PHP OOP DateTime ModifyDate 小数位错误

c# - 从共享某些部分的 2 个接口(interface)实现一个类

javascript - JS - 如何在特定时间段内随机时间重复触发函数