最小生成树循环不起作用

问题描述

我们三个朋友尝试使用 r 解决冲突问题的最小生成树。在解决这个问题时,我们读取 .txt 格式的文件,其中包含 for ex。 “1 2 5 2 4 6" 等表示从节点 1 到 2,存在权重为 5 的边,并且 “1 2 2 4”等表示边 1-2 和边 2-4 之间存在冲突关系。为了继续,我们必须形成一个 nxn 冲突矩阵,如果边之间不存在冲突关系,我们将在其中存储 0,如果存在冲突关系,我们将存储 1。为此,我们开发了一个 3-for 循环 for(i in 1:dim(edges_read)[1]){

for(i in 1:dim(edges_read)[1]){
  for(k in 1:dim(edges_read)[1]){
    for(t in 1:dim(conflicts)[1]){
      if(all(conflicts[t,] == c(edges_read[i,1],edges_read[i,2],edges_read[k,2]) )){
        conflictmatrix[i,k] <- 1
      }
    }
  }
}

然而,R 无法为我们提供解决方案,而且这个 for 循环需要很长时间。我们如何解决这种情况?感谢您的进一步帮助

解决方法

正如您所发现的,for() 循环在 R 中并不快。有更快的方法,但很难提供没有数据的示例。请使用 dput(edges_read)dput(conflicts) 之类的内容提供数据的小示例。

举个例子,您可以在 Rcpp 包中实现 for 循环以提高速度。根据您问题中的代码,您可以像这样重新实现 3 循环代码:

Rcpp::cppFunction('NumericVector MSTC_nxn_Cpp(NumericMatrix edges_read,NumericMatrix conflicts){
int n = edges_read.nrow(); //output matrix size (adjust to what you need)
int m = conflicts.nrow();  //output matrix size (adjust to what you need)
NumericMatrix conflictmatrix( n,m ); //the output matrix 
for(int i=0;i<n;i++){ //your i loop
  for(int k=0;k<n;k++){ // your k loop
  double te = edges_read( i,0 ); //same as edges_read[i,1]
  double tf = edges_read( i,1 ); //same as edges_read[i,2]
  double tg = edges_read( k,0 ); //same as edges_read[k,1]
  double th = edges_read( k,1 ); //same as edges_read[k,2]
  NumericVector w =  NumericVector::create(te,tf,tg,th); //this could probably be more simple
    for(int t=0;t<m;t++){   //your t loop
        NumericVector v = conflicts( t,_ ); // same as conflicts[t,]
        LogicalVector r;   //vector for checking if conflicts and edges are the same
        for(int p=0; p<4; p++){  //loop to check logic 
          r[p]=v[p]==w[p];  //True / False stored
        };
        int q = r.size();
  for (int ii = 0; ii < q; ++ii) {  //similar to all() This code could be simplified!
    if (!r[ii]) {false;}
  else{conflictmatrix[i,k] = 1;}}
  }}}
  return conflictmatrix;  //your output
}')

#Then run the function
MSTC_nxn_Cpp(edges_read,conflicts )