【问题标题】:Distributing an amount as evenly as possible尽可能平均分配金额
【发布时间】:2012-06-30 13:15:13
【问题描述】:

我们有一定数量,例如300个单位。这个数量应该尽可能均匀地分布在 40 个“插槽”上。如果每个插槽都相同,那将很容易-因此每个插槽将是 7,5。但是,插槽的大小各不相同,我们不能“填充”超过其“大小”允许的范围,例如如果只有 5 个。我们无法“填写”的内容,我们必须在其他内容上分配更多。

我有一些基本的想法,但我离成为专家还很遥远,希望有一种简单的方法来解决这个问题。 例如,这可能是什么样子。在数组“a”中,值代表插槽可以采用的最大值。 a[i] 是第 i 个时隙的最大值。 “b”是我们必须整体分配的,例如300.

 # developing slots and their "size"
 a <- rnorm(40,10,4)
 sum(a)

 # overall sum to distribute
 b <- 300 

也许可以按升序对值进行排序,然后可以通过双 for 循环使用它。 a[,2] 成为“填充”金额的列。

 for i in 1:40
 {a[i,2] <- a[1,2]*40
 b <- a [1,2]*40}

 for i in 2:40
 {a[i,2] <- a[1,2]*39
 b <- a[1,2]*39}

etc.

我不确定如何将两个 for 循环放在一起,以及这是否是一个足够的解决方案。 很高兴听到你的想法。谢谢!

【问题讨论】:

  • 我不关注。每个插槽可以占用的大小的信息在哪里?你有单独的信息吗?就像 40 个插槽中的每一个都可以占用一样。
  • 数组 a 表示每个插槽可以占用多少。 b

标签: r distribution minimum evenly


【解决方案1】:

第一个版本,使用 while 循环:

optimal.fill <- function(a, b) {
  stopifnot(sum(a) >= b)

  d <- rep(0, length(a))
  while(b > 0) {
    has.room  <- a > 0
    num.slots <- sum(has.room)
    min.size  <- min(a[has.room])
    add.size  <- min(b / num.slots, min.size)
    d[has.room] <- d[has.room] + add.size
    a[has.room] <- a[has.room] - add.size
    b <- b - num.slots * add.size
  }
  return(d)
}

第二个版本有点难理解,但我觉得更优雅:

optimal.fill <- function(a, b) {
  stopifnot(sum(a) >= b)

  slot.order   <- order(a)
  sorted.sizes <- a[slot.order]
  can.fill     <- sorted.sizes * rev(seq_along(a))
  full.slots   <- slot.order[which(cumsum(can.fill) <= b)]

  d <- rep(0, length(a))
  d[ full.slots] <- a[full.slots]
  d[!full.slots] <- (b - sum(a[full.slots])) /
                    (length(a) - length(full.slots))

  return(d)
}

【讨论】:

    【解决方案2】:

    这是另一个选择:

    optimal.fill2 <- function(a,b) {
      o <- rank(a)
      a <- sort(a)
      ca <- cumsum(a)
      foo <- (b-ca)/((length(a)-1):0)
      ok <- foo >= a
      a[!ok] <- foo[max(which(ok))]
      a[o]
    }
    

    【讨论】:

    • 感谢您的想法!让我们假设有另一个限制,即我们可以在插槽中填充多少,与插槽的大小无关。某事。就像一个受约束的一般文件。例如。最后一个位置有 30 个,我们还剩下 25 个,但我们最多可以填写 20 个。然后我们必须将剩余的 5 个放入一个单独的剩余槽中。如果“填充”超过最大值,我们可能必须使用条件,我们必须将其添加到剩余池中。但是我不确定如何创建它。
    • 早上又看了一遍,觉得这和@flodel的第二个回答是一样的想法。
    • @FabianStolz:最好修改问题或提出新问题,而不是在评论中提问。在这种情况下,我认为需要一个新问题,但请务必链接回这个问题。
    • 这里是新问题的链接:stackoverflow.com/questions/11288900/… 如果某人可以看看就好了。
    猜你喜欢
    • 1970-01-01
    • 2019-07-22
    • 1970-01-01
    • 2016-12-05
    • 2012-07-02
    • 2021-11-30
    • 2023-03-26
    • 1970-01-01
    • 2020-06-03
    相关资源
    最近更新 更多