好了,我們不能讓你訴諸for循環,我們現在可以:)
當然有如何表示稀疏矩陣的問題。一個簡單的方法是讓它只包含最近點的索引(並根據需要重新計算)。但在下面的溶液中,我把二者的距離(「D1」等)和索引(「I1」等)在一個單一的矩陣:
sparseDist <- function(m, k) {
m <- t(m)
n <- ncol(m)
d <- vapply(seq_len(n-1L), function(i) {
d<-colSums((m[, seq(i+1L, n), drop=FALSE]-m[,i])^2)
o<-sort.list(d, na.last=NA, method='quick')[seq_len(k)]
c(sqrt(d[o]), o+i)
}, numeric(2*k)
)
dimnames(d) <- list(c(paste('d', seq_len(k), sep=''),
paste('i', seq_len(k), sep='')), colnames(m)[-n])
d
}
嘗試出來9 2D點:
> m <- matrix(c(0,0, 1.1,0, 2,0, 0,1.2, 1.1,1.2, 2,1.2, 0,2, 1.1,2, 2,2),
9, byrow=TRUE, dimnames=list(letters[1:9], letters[24:25]))
> print(dist(m), digits=2)
a b c d e f g h
b 1.1
c 2.0 0.9
d 1.2 1.6 2.3
e 1.6 1.2 1.5 1.1
f 2.3 1.5 1.2 2.0 0.9
g 2.0 2.3 2.8 0.8 1.4 2.2
h 2.3 2.0 2.2 1.4 0.8 1.2 1.1
i 2.8 2.2 2.0 2.2 1.2 0.8 2.0 0.9
> print(sparseDist(m, 3), digits=2)
a b c d e f g h
d1 1.1 0.9 1.2 0.8 0.8 0.8 1.1 0.9
d2 1.2 1.2 1.5 1.1 0.9 1.2 2.0 NA
d3 1.6 1.5 2.0 1.4 1.2 2.2 NA NA
i1 2.0 3.0 6.0 7.0 8.0 9.0 8.0 9.0
i2 4.0 5.0 5.0 5.0 6.0 8.0 9.0 NA
i3 5.0 6.0 9.0 8.0 9.0 7.0 NA NA
並試圖解決更大的問題(10k點)。儘管如此,在100k點和更多維度上需要很長時間(比如15-30分鐘)。
n<-1e4; m<-3; m=matrix(runif(n*m), n)
system.time(d <- sparseDist(m, 3)) # 9 seconds on my machine...
P.S.剛纔注意到,當我寫這篇文章時,你發佈了一個答案:這裏的解決方案大概是兩倍的速度,因爲它不會計算兩次相同的距離(點1和點13之間的距離與點13和點1之間的距離相同)。
只要確保...你知道'dist' http:// stat。 ethz.ch/R-manual/R-patched/library/stats/html/dist.html,對嗎? – Benjamin 2011-04-06 17:08:21
對不起,我不清楚爲什麼dist()不適合我的情況。它導致了一個稠密的矩陣,並且存儲NxN矩陣有點煩人。 – 2011-04-07 01:10:41
您應該或者接受其中一個答案,您認爲它實際上回答了問題(如果您認爲它最合適,那麼是您自己的問題),或者編輯您的問題以澄清問題的原因。 – Tommy 2011-07-25 16:45:58