这个R函数可以矢量化吗? bucketinex
这里有一个尝试(尚未到达这个R函数可以矢量化吗? bucketinex,r,vectorization,conditional-statements,R,Vectorization,Conditional Statements,这里有一个尝试(尚未到达bucketinex!): 你的 bucketIndex <- function(v, N){ o <- rep(0, length(v)) curSum <- 0 index <- 1 for(i in seq(length(v))){ o[i] <- index curSum <- curSum + v[i] if(curSum > N){ curSum <-
bucketinex
!):
- 你的
也就是说,只需在bucketIndex <- function(v, N){ o <- rep(0, length(v)) curSum <- 0 index <- 1 for(i in seq(length(v))){ o[i] <- index curSum <- curSum + v[i] if(curSum > N){ curSum <- 0 index <- index + 1 } } o } > bucketIndex(c(1, 1, 2, 1, 5, 1), 3) [1] 1 1 1 2 2 3
中交换两个连续条目,结果中的最大值就会不同v
- 另一点是,仅在导致总和为>
的元素之后进行计数。这意味着结果的开头应该有一个额外的1,最后一个元素应该被删除N
- 您可以将
重置为0,而不管它在curSum
上射出多少。因此,对于所有具有N
的元素,您需要减去该值,然后查找下一个cumsum(v)>N
,依此类推。这就减少了与cumsum(v)>N
循环相关的循环迭代次数,但这是否会给您带来本质上的改进取决于for
的条目和v
(或者,取决于N
:max(index)
比率)。如果这是你例子中的50%,我认为你不能获得实质性的收益。除非它们之间至少有一个magnitute顺序,否则我会选择长度(v)
inline::cfunction
N
的位置,将索引分配给该范围,将累计和减少超过N
的任何值,并重复,直到向量用尽。其余的是记账(初始化值和增加值)
bucketIndex2cumsum
是否为您处理此问题<代码>光标]不,那是另一个函数。。sum()只返回一个长度为1的向量。你能评论一下它应该做什么吗?它接近于累积和的整数除法(cumsum(v)%/%N
),但复杂的部分是curSum
被设置回0(而不是模cumsum(v)%%N
。请参见我第一次尝试的答案。我想对v的连续元素进行分组,以便每个组中的和都大于N(可能最后一组除外),组必须尽可能小(在元素数量上)…但是上面的代码更好地描述了我想做的事情。cumsum的事情很接近,但不一样。只是要明确一点:v
是先验存在的吗,或者如果我们提出了一个在随机抽样中抽取数组的解决方案,这是允许的吗?bucketIndex比你的bucketIndex快。@Roland我不是特别喜欢它令人惊讶。其中(cs>N)
在v
的长度中是O(N)
,重复循环也是O(N)
(长度的一部分,但并不比一部分好),因此整个函数在v
的长度中应该是O(N^2)
。具有简单循环的原始函数应该是O(N)
长度为v
。关于你的第三和第四个要点:是的,这是你想要的行为。
curSum <- curSum + v[i]
if(curSum > N){
curSum <- 0
index <- index + 1
}
> bucketIndex (c(1, 1, 2, 1, 2, 1, 1, 2, 1, 5, 1), 3)
[1] 1 1 1 2 2 2 3 3 3 4 5
> bucketIndex (c(1, 1, 1, 2, 2, 1, 1, 2, 1, 5, 1), 3)
[1] 1 1 1 1 2 2 2 3 3 3 4
bucketIndex2 <- function(v, N) {
index <- 1
cs <- cumsum(v)
bk.old <- 0
o <- rep(0, length(v))
repeat {
bk <- suppressWarnings(min(which(cs > N)))
o[(bk.old+1):min(bk,length(v))] <- index
if (bk >= length(v)) break
cs <- cs - cs[bk]
index <- index + 1
bk.old <- bk
}
o
}
for (i in 1:200) {
v <- sample(sample(20,1), sample(50,1)+20, replace=TRUE)
N <- sample(10,1)
bi <- bucketIndex(v, N)
bi2 <- bucketIndex2(v, N)
if (any(bi != bi2)) {
print("MISMATCH:")
dump("v","")
dump("N","")
}
}