查找最接近特定数字的数字总和

时间:2017-07-18 12:31:17

标签: r

我在r

中有以下数字向量
bay_no <- c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
bay_cont <- c(45,25,25,0,19,61,2,134,5,27,0,54,102,97,5,6,65,47,85,0)
count <- 3
bay_to_serve <- sum(bay_cont)/count

在上面的bay_cont向量中,我想在上面的bay_to_serve

中找到接近bay_to_serve = 268的总和

现在,从(45 till 2) sum is 177 and (45 till 134) sum is 311开始311 is closest to 268,它应该返回i.e 8 from bay_no的索引

我们将从bay_no = 1-8

获取一个向量

再次从bay_cont from 5 till the sum close to 268

开始

所需的输出

bay_no 1-8,9-14 and then remaining bay_nos

我们怎么能在r?

4 个答案:

答案 0 :(得分:2)

Dunno,如果有一个聪明的方法,但我会想到嵌套循环。 你的内循环可能看起来像这样(请注意我现在无法访问R,所以我无法测试它。):

old_sum = bay_count[1]
for(i in 2:length(by_cont)) {
  new_sum <- sum (bay_count[1:i])
  if (abs(bay_to_serve - new_sum) < abs(bay_to_serve - old_sum)) {
    output <- paste("bay_no", paste(1,i, sep="-"), sep=" ") break
  }else{
    old_sum <- new_sum
  }
}

这样,只要前X个条目的总和小于前一个和,就会打破循环并创建输出字符串。只需在第一个循环周围添加另一个循环,从j:length(by_cont)运行一个或多个if语句,其中j首先设置为1,并在内循环中设置为i + 1。

答案 1 :(得分:2)

您可以尝试:

res <- NULL
i = 1
while(i < length(bay_cont)){
 tmp <-  which.min(abs(cumsum(bay_cont[i:length(bay_cont)]) - bay_to_serve))
 res <- append(res,tmp)
 i = tmp + i
}
cumsum(res)
[1]  8 14 19

如果您想特别断绝关系,可以将rankwhich.min一起使用,如下所示:

which.min(rank(abs(cumsum(bay_cont[i:length(bay_cont)]) - bay_to_serve), ties.method = "last"))

然后我会创建一个矩阵而不是将它粘贴在一起:

cbind(c(1, cumsum(res)[-length(cumsum(res))]+1), cumsum(res))
     [,1] [,2]
[1,]    1    8
[2,]    9   14
[3,]   15   19

当然你也可以将它们粘贴在一起:

apply(cbind(c(1, cumsum(res)[-length(cumsum(res))]+1), cumsum(res)), 1, paste, collapse="-")
[1] "1-8"   "9-14"  "15-19"

答案 2 :(得分:1)

我的解决方案使用脏for循环但产生所需的indizes ... 希望这适合你?

  bay_no <- c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
    bay_cont <- c(45,25,25,0,19,61,2,134,5,27,0,54,102,97,5,6,65,47,85,0)
    count <- 3
    bay_to_serve <- sum(bay_cont)/count


    temp_sum=0
    for (i in 1:(length(bay_cont)-1)) {
      temp_sum=temp_sum+bay_cont[i]
      if ( abs(bay_to_serve-temp_sum)<abs(bay_to_serve-(temp_sum +bay_cont[i+1]))) {
        print(i)
        temp_sum=0
      }

    }

答案 3 :(得分:0)

我可能误解了这个问题,但这样做似乎更容易:

bay_no[ which.min(abs(cumsum(bay_cont) - bay_to_serve)) ]

从5开始,省略元素1:4并将4添加到which.min索引

bay_no[ which.min(abs(cumsum(bay_cont[-(1:4)]) - bay_to_serve))+4 ]