我试图在距离矩阵中找到三角形,在该矩阵中,直接路径比通过另一个点的路径更长。目标是减少完全连接图中的边数。 该函数对于n的低值很好用,但对于较大的n却很慢。 我正在尝试找出如何加快此过程的速度。
我曾希望通过将数据保留为矩阵并进行处理,以使该过程可以矢量化并非常快速地进行,但是,事实并非如此。
我尝试使用lineprof
并单击以降低功能,但我不明白它在告诉我什么。我不知道igraph
中是否有某些功能可以帮助您?
library(purrr);library(magrittr); library(lineprof);library(shiny)
#The function used to find triangles
RemoveTri <- function(s){
Smat<- col(s)
RemoveEdge <- 1:ncol(s) %>%
map(~{
print(.x)
LogicMat <- s + s[,.x][Smat] < (s[,.x]) #I used this method to avoid transposing
matrix(data = rowSums(LogicMat, na.rm = TRUE ) > 0, ncol = 1) #TRUE means edge can be removed
}) %>%
do.call(cbind,.)
s[RemoveEdge] <- NA
return(s)
}
#This function just creates a dataframe
CreateData <- function(n, seed){
set.seed(seed)
s <- matrix(rnorm(n^2), n) #%>% cor
s <- s +abs(min(s))+0.001
s[lower.tri(s)] = t(s)[lower.tri(s)]
diag(s) <- 0
return(s)
}
#Using a small amount of data
s <- CreateData(100, 876)
RemoveTri(s)
#using a larger amount of data
s2 <- CreateData(4000, 876)
RemoveTri(s2)
l <- lineprof(RemoveTri(s))
shine(l)
答案 0 :(得分:0)
由于矩阵是对称的,因此仅通过计算下三角矩阵可以加快处理过程。通过这样做,我们可以将计算数量从$ n ^ 3 $减少到
$ \ frac {n} {6}(2n ^ 2 + 3n + 1)$得出$ \ frac {(2n + 1)(n + 1)} {6n ^ 2} $的比率,得出大约2当n大时,计算总数减少/ 3。
调整后的功能如下。
此功能启动缓慢,并随着计算更多行而加快速度。在n值较小的情况下,由于额外的开销,它比原始函数要慢,但在n大于几百时,它会变得更快。
RemoveTri <- function(s){
Smat <- col(s)
RemoveEdge <- 1:ncol(s) %>%
map(~{
print(.x)
TargetRows <- .x:ncol(s)
LogicMat <- s[TargetRows,TargetRows, drop = F] + s[TargetRows,.x][Smat[1:length(TargetRows),1:length(TargetRows)]] < s[TargetRows,.x]
matrix(data = c(rep(NA, .x-1),rowSums(LogicMat, na.rm = TRUE ) > 0), ncol = 1) #TRUE means edge should be removed
}) %>%
do.call(cbind,.)
RemoveEdge[upper.tri(RemoveEdge)] <- t(RemoveEdge)[upper.tri(RemoveEdge)]
s[RemoveEdge] <- NA
s
}