我们必须有一定量的如300个单位。 这个量应尽可能均匀地分布在40“时隙”。 这将是容易的,如果每个插槽将是相同的 - 所以这将是7,5在每个插槽。 然而,槽大小不同,我们不能“填写”有超过它的“大小”允许例如,如果它的唯一5.什么是不能“填写”我们必须比其他的分配更多的。
我有一些基本思想,但我远离作为一名专家,并希望有一个简单的方法来解决这个问题。 作为一个例子这是怎么样子。 在阵列的“a”的值代表最大值槽可以采取。 一个[i]为最大的第i个时隙的。 “B”就是我们要分发的整体例如300。
# developing slots and their "size"
a <- rnorm(40,10,4)
sum(a)
# overall sum to distribute
b <- 300
也许是可能以递增的顺序值进行排序,然后一个可以被用于循环的双重使用它。 一个[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循环在一起,如果这是总体适当的解决方案。 很高兴听到你的想法。 谢谢!
第一个版本,使用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)
}
这里的另一种选择:
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]
}