假设我有一个带有0和1的方阵,如下例所示:
1 2 3 4 5 6
1 0 1 0 1 0 0
2 1 0 0 1 0 0
3 0 0 0 0 0 0
4 1 1 0 0 0 0
5 0 0 0 0 0 1
6 0 0 0 0 1 0
我们可以认为这是一个邻接矩阵,有6个顶点,所有对角元素都必须为0.当然,矩阵必须关于对角线对称。
在R中,给出一堆具有不同大小的矩阵,找到每个矩阵中的所有“派系”并给出每个集团的成员,最有效的方法是什么? ('clique'是指一组顶点,每个顶点都有一个边缘到集合中的每个顶点)例如,在上面的矩阵中,有两个集团;通过行/列号表示顶点,派系是(1,2,4)和(5,6)。因此,对于输出,我想要每个集团中所有顶点(行或列名称)的列表,用于该矩阵中的所有派系。我想为大量不同大小的矩阵做这个(尽管所有矩阵都是方矩阵)。有关最佳方法的任何想法是什么?
我一直在考虑在for循环中使用for循环,但是因为可能派系的大小是不确定的(但最多可以等于矩阵中行/列的数量)让我觉得我可能我需要使用while循环,但我不确定它是多么精确。
我将粘贴一些我刚刚编写的代码,这些代码应该按照我所描述的方式进行操作,其中列表'cliquelist'包含循环结束时矩阵中的所有派系。邻接矩阵称为“mat”。
cliquelist <- NULL
for(i in 1:nrow(mat)){
for(j in 1:ncol(mat)){
if(mat[i,j]==1){
clique <- c(i, j)
pool <- j:ncol(mat)
while(length(pool)>0) {
add <- which(mat[,pool[1]]==1)
if(length(add)==0){
pool <- NULL
}else{
pool <- pool[which(!pool %in% add)]
clique <- c(clique, add)
}
}
cliquelist[length(cliquelist)+1] <- clique
}
}
}
我确定这段代码中有一些错误;在上面展示的示例矩阵中,我还没弄清楚它们是什么,因为它仍在运行(经过几分钟),所以我怀疑它们的某个地方存在无限循环。
但它有几个问题,甚至让我不愿意回去调试它。 1)最明显的是,它会将每个clique添加到列表中的次数与列表中的元素一样多,因此存在大量冗余。 2)它不会过滤掉较大派系中较小的派系。所以,如果一个集团由顶点1,3和5组成,那么类似上面代码的东西将返回(1,3),(1,5),(3,5),(1,3,5)等但我只希望独特的派系不被包含在更大的派系中。我想知道在R中是否有一种不同的,更有效的方法。
非常感谢任何建议。