在距离矩阵中查找边缘较短的三角形

时间:2018-09-28 11:01:48

标签: r matrix igraph adjacency-matrix

我试图在距离矩阵中找到三角形,在该矩阵中,直接路径比通过另一个点的路径更长。目标是减少完全连接图中的边数。 该函数对于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)

1 个答案:

答案 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

}