R中Pareto锋的快速计算
因此,我试图计算R中Pareto锋的快速计算,r,performance,if-statement,R,Performance,If Statement,因此,我试图计算R中的帕累托前沿(),我能够做到,但是,我不能有效地做到。特别是当点对的数量增加时,计算速度大大降低 所以一般来说,我要做的是检查所有非支配(或支配)对。现在我这样做的方法是找到所有这样的点对,比如xi>X 和yi>Y其中(xi,yi)是一对,并且X和Y代表所有点X和Y。现在,这一部分工作非常快速且易于实现,但是,还有一种可能性,即多个x值可能相同,但它们将具有不同的y值,因此在这种情况下,我希望能够识别具有最低y值的x值(对于具有相同y值但不同x值的点,反之亦然) 为了说明这一
R
中的帕累托前沿(),我能够做到,但是,我不能有效地做到。特别是当点对的数量增加时,计算速度大大降低
所以一般来说,我要做的是检查所有非支配(或支配)对。现在我这样做的方法是找到所有这样的点对,比如xi>X
和yi>Y其中(xi,yi)是一对,并且X和Y代表所有点X和Y。现在,这一部分工作非常快速且易于实现,但是,还有一种可能性,即多个x值可能相同,但它们将具有不同的y值,因此在这种情况下,我希望能够识别具有最低y值的x值(对于具有相同y值但不同x值的点,反之亦然)
为了说明这一点,这里有一幅来自维基百科的图片:
所以基本上我希望能够识别红线上的所有点
下面是我的代码,它确实有效,但对于大型数据集来说效率非常低:
#Example Data that actually runs quickly
x = runif(10000)
y = runif(10000)
pareto = 1:length(x)
for(i in 1:length(x)){
cond1 = y[i]!=min(y[which(x==x[i])])
cond2 = x[i]!=min(x[which(y==y[i])])
for(n in 1:length(x)){
if((x[i]>x[n] & y[i]>y[n]) | (x[i]==x[n] & cond1) | (y[i]==y[n] & cond2)){
pareto[i] = NA
break
}
}
}
#All points not on the red line should be marks as NA in the pareto variable
速度的减慢肯定来自于计算(x[i]==x[n]&cond1)|(y[i]==y[n]&cond2)
,但我找不到解决方法或更好的布尔表达式来捕获我想要的所有内容。任何建议都非常感谢!编辑:新版本:
system.time( {
pareto.2 <- logical(length(x))
x.sort <- sort(x)
y.sort <- y[order(x)]
y.min <- max(y)
for(i in 1:length(x.sort)) {
if(pareto.2[i] <- y.sort[i] <= y.min) y.min <- y.sort[i]
}
} )
# user system elapsed
# 0.036 0.000 0.035
原件:
pareto = 1:length(x)
system.time(
for(i in 1:length(x)){
cond1 = y[i]!= min(y[which(x==x[i])])
cond2 = x[i]!= min(x[which(y==y[i])])
for(n in 1:length(x)){
if((x[i]>x[n] & y[i]>y[n]) | (x[i]==x[n] & cond1) | (y[i]==y[n] & cond2)){
pareto[i] = NA
break
}
}
}
)
# user system elapsed
# 5.32 0.00 5.33
显示这两种方法会产生相同的结果(有点棘手,因为我需要将pareto.2重新排序为原始的x
):
跟随@BrodieG
system.time( {
d = data.frame(x,y)
D = d[order(d$x,d$y,decreasing=FALSE),]
front = D[which(!duplicated(cummin(D$y))),]
} )
user system elapsed
0.02 0.00 0.02
这是0.86/0.02=43倍快!我实际上从其他人的帖子中找到了一种更快的方法来解决这个问题,尽管我喜欢for循环的可读性。要查看答案,请查看我现在问另一个问题的地方。@StatMan,在答案中查看新版本。似乎与您找到的另一个类似。在C++中帕累托边界(SkyLo线)的实现
all.equal(pareto.2[match(1:length(x), order(x))], !is.na(pareto))
# [1] TRUE
system.time( {
d = data.frame(x,y)
D = d[order(d$x,d$y,decreasing=FALSE),]
front = D[which(!duplicated(cummin(D$y))),]
} )
user system elapsed
0.02 0.00 0.02