我试图在R中使用igraph :: cluster_walktrap来查找图中的社区,但是我注意到一种奇怪的行为(或者至少是一种我无法解释的行为)。
假设您通过定义边缘列表给出了无向图。说
a,b
c,d
e,f
...
然后,如果我通过在边列表定义中交换随机选择的顶点来定义另一个图形:
a,b
d,c
e,f
...
我希望这两个图是同构的,两个图之间的差异是空的。这正是我的玩具示例中R中发生的事情。按照这一推理,在两个图上调用cluster_walktrap(适当地使用set.seed)应该产生相同的结果,因为两个图是相同的。这种情况没有发生,我能给出的唯一解释是每个随机游走的起点对于两个图不同。为什么是这样?
您可以在下面的玩具示例中按照我的推理。我不明白为什么最后两个对象不相同。
require(igraph)
# Number of vertices
verteces <- 50
# Swap randomly some elements in the edges definition
set.seed(20)
row_swapped <- sample(1:verteces,25,replace=F)
m_values <- sample(letters, verteces*2, replace=T) #1:100
# Build edge lists
m1 <- matrix(m_values, verteces, 2)
m1
a <- m1
colS <- seq(round(ncol(m1)*0.3))
m1[row_swapped, 2:1] <- m1[row_swapped, 1:2]
m1
b <- m1
# Define the two graphs
ag <- igraph::graph_from_edgelist(a, directed = F)
bg <- igraph::graph_from_edgelist(b, directed = F)
# Another way of building an isomorphic graph for testing
#bg <- permute(ag, sample(vcount(ag)))
# Should be empty: ok
difference(ag, bg)
# Should be TRUE: ok
isomorphic(ag,bg)
# I expect it to be TRUE but it isn't...
identical(ag, bg)
# Vertices
V(ag)
ag
V(bg)
bg
# Calculate community
set.seed(100)
ac1 <- cluster_walktrap(ag)
set.seed(100)
bc1 <- cluster_walktrap(bg)
# I expect all to be TRUE, however
# merges is different
# membership is different
# names are different
identical(ac1$merges, bc1$merges)
identical(ac1$modularity, bc1$modularity)
identical(ac1$membership, bc1$membership)
identical(ac1$names, bc1$names)
identical(ac1$vcount, bc1$vcount)
identical(ac1$algorithm, bc1$algorithm)
答案 0 :(得分:2)
结果没有什么不同。你有两件事正在使你的图表不相同但是同构。我强调相同,因为它有一个非常严格的定义。
1)identical(ag, bg)
不相同,因为顶点和边在两个图之间的顺序不同。确切地说,存在相同的节点和边缘,但它们不在完全相同的位置或方向。例如,如果我将a
的行洗牌并创建一个新图...
a1 <- a[sample(1:nrow(a)), ]
a1g <- igraph::graph_from_edgelist(a1, directed = F)
identical(ag, a1g)
#[1] FALSE
2)这也适用于边缘。如果边缘是否被定向,则边缘被存储为node1,node2和标志。因此,当您交换行时,即使关系相同,“字节级别”(我松散地使用这个术语)的表示也是不同的。边44表示相同的关系,但是根据它的构造方式存储。
E(ag)[44]
# + 1/50 edge from 6318240 (vertex names):
# [1] q--d
E(bg)[44]
# + 1/50 edge from 38042e0 (vertex names):
# [1] d--q
首先,在cluster_walktrap
上,函数返回顶点的索引,而不是可能误导的名称。这意味着对象不是相同的原因是因为ag
和bg
在对象中具有不同的节点排序。
如果我按节点名称重新排序成员资格,那么两者就会变得相同。
identical(membership(bc1)[order(names(membership(bc1)))], membership(ac1)[order(names(membership(ac1)))])
#[1] TRUE