【问题标题】:compute matrix distance using dynamic programming使用动态规划计算矩阵距离
【发布时间】:2015-03-02 23:12:45
【问题描述】:

我有一个由值 0、1 和 2 组成的矩阵。99% 的值是 0。该矩阵有 100 万行和 700 列。每行至少有一个非零值。

我需要使用以下公式计算每对列之间的距离,用于计算列 x 和 y 之间的距离: D=(Sum(|xi-yi|)/2L for i from 1 to L, L=100万,即行数。

我写了一段 R 代码,但是计算时间太长,是否可以使用动态编程来更快地完成它?这是我的代码:

#mac is the matrix
nCols=ncol(mac)
nRows=nrow(mac)
#the pairwise distance matrix
distMat=matrix(data=-1,nrow=nCols,ncol=nCols)

abs.dist=function(x){return(abs(x[1]-x[2]))} 

for(i in 1:(nCols-1)){
    for(j in (i+1):nCols){
        d1=apply(mac[,c(i,j),1,abs.dist)
        k=sum(d1)/(2*nRows)
        distMat[i,j]=k
        distMat[j,i]=k
    }
}

for(i in 1:nCols) distMat[i,i]=0

非常感谢您的帮助?

【问题讨论】:

  • 我认为您使用apply 计算绝对差异会降低性能。减法和求绝对值是矢量化的,所以你可以简单地做d1 <- abs(mac[,i]-mac[,j])
  • 顺便说一句,你可以在最后一行做diag(distMat) <- 0
  • 有了这么大的矩阵,您可能会考虑使用并行处理和Rcpp。以下是一些您应该能够适应的代码:Parallel Distance Matrix in R with Rcpp.

标签: r dynamic matrix


【解决方案1】:

我将总结一下 cmets 中已有的内容:

#mac is the matrix
nCols=ncol(mac)
nRows=nrow(mac)
#the pairwise distance matrix
distMat=matrix(data=-1,nrow=nCols,ncol=nCols)

for(i in 1:(nCols-1)){
    for(j in (i+1):nCols){
        d1=abs(mac[,i]-mac[,j])
        k=sum(d1)/(2*nRows)
        distMat[i,j]=k
        distMat[j,i]=k
    }
}

diag(distMat) <- 0

对于 2000x500 矩阵,这大约快 100 倍。 1e6x700 矩阵大约需要半分钟。

【讨论】:

  • 感谢Marat的总结和重点!没有意识到apply 是问题所在。
【解决方案2】:

计算距离矩阵意味着您需要 (n^2-n)/2 次操作。我并不奇怪这需要一段时间。

由于您需要所有对,因此这些计算必须独立完成。动态编程将无济于事。当您从较小的部件构建解决方案时,DP 会有所帮助。这里的一切都是独立的,所以 DP 无济于事(据我所知)。

您说大多数条目都是 0。尝试查看稀疏矩阵库。这个blog post 可能会给你一些在 R 中这样做的想法。

【讨论】:

  • 谢谢,我会看看博客。我不知道我是否完全理解动态编程,但这里可能会浪费很多计算。例如,如果可以将一对列转换为模式,例如,00 对、01 对、02、12 和 22 对的数量。然后可以保存距离并重新用于具有相同模式的其他对。
  • 我认为这样做会浪费很多精力来获得微薄的收益。 DP 是一种特定的优化算法,通过求解最优子问题来计算全局最优值。在矩阵领域,一个常见的 DP 应用是确定最佳乘法顺序。看看here.
  • 我同意在这种情况下增益可能很小,因为计算模式可能比计算距离还要慢(除非有办法按位计算)。但在前者比后者快得多的问题中,这种方法可以加快运行速度。
猜你喜欢
  • 2018-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多