3

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 

たぶん、値を昇順でソートすることが可能であり、それからそれをdoubleforループで使用することができます。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ループをどのように組み合わせることができるか、そしてこれが全体として適切な解決策であるかどうかはわかりません。あなたのアイデアを聞いてうれしいです。ありがとう!

4

2 に答える 2

2

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)
}

この 2 番目のバージョンは少しわかりにくいですが、より洗練されているように感じます。

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)
}
于 2012-06-29T00:54:31.040 に答える
1

別のオプションは次のとおりです。

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]
}
于 2012-06-29T02:31:03.883 に答える