代码之家  ›  专栏  ›  技术社区  ›  Kieran E

如何创建一个整数数组,大致平均到给定的数字?

  •  0
  • Kieran E  · 技术社区  · 3 年前

    我并不是想找到一个数组的平均值,而是想创建一个大致平均到所需数字的数组。

    我的用例是,我有2个步进电机,每个电机都需要执行一个 光滑的 在大致相同的时间内移动。步进器以离散的步骤移动,这些步骤之间有整数毫秒的延迟。我需要能够控制“较快”电机的速度(即:需要采取更多总步骤,步骤之间有更小、恒定延迟的电机),“较慢”电机的转速应根据需要进行调整。

    考虑电机A需要走100步,电机B需要走150步的情况。电机B的步之间的延迟必须为1ms,因此电机A的步之间延迟为1.5ms。这不起作用,因为步长延迟必须是整数。

    为此,我相信你可以通过生成一个长度等于总步数的数组来解决这个问题,其中每个元素都是一个整数,总的来说,平均延迟为1.5ms。这个例子很简单:

    motor_a_step_delays = [1, 2, 1, 2, 1, 2 ... 100 elements total ...]
    

    我的问题是,我似乎找不到创建这个数组的好方法。整数元素应该是“close”(因为没有更好的单词)。类似的东西 [51, 1, 1, ... 97 more 1's...] 这是正确的,但不会导致平稳、均匀的运动。

    这个问题似乎已经解决了,但我甚至不知道如何开始寻找它。这似乎在数控、机器人或游戏设计应用中有用。

    0 回复  |  直到 3 年前
        1
  •  1
  •   Kieran E    3 年前

    像往常一样,输入我的问题的行为让我停下来思考实际发生了什么。

    从根本上说,数组只包含所需平均延迟的下限和上限。如果期望的平均值为2.25,则最终的数组将是2和3的某种组合,但绝不是1或4。一旦我意识到这一点,它似乎很简单,天花板和地板的数量与所需的延迟距离天花板/地板的距离成正比。换句话说,2.25需要一个75%2和25%3的数组。简单!

    以下是我最终得到的(Elixir):

      def generate_step_delays(steps, desired_delay) do
        desired_delay_ceil = ceil(desired_delay)
        desired_delay_floor = floor(desired_delay)
        # The ratio of ceils to floors needed
        ratio = desired_delay - desired_delay_floor
    
        ceil_list = List.duplicate(desired_delay_ceil, round(steps * ratio))
        floor_list = List.duplicate(desired_delay_floor, steps - length(ceil_list))
    
        ceil_list
        |> Enum.concat(floor_list)
        |> Enum.shuffle()
      end
    

    此实现将最终数组随机化,因为这对我的情况最有效。然而,换掉它很容易 Enum.shuffle 如果需要,可以均匀地分配数字。