为什么igraph :: cluster_walktrap为非定向同构图提供了不同的结果?

时间:2018-03-08 14:09:21

标签: r igraph

我试图在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)

1 个答案:

答案 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上,函数返回顶点的索引,而不是可能误导的名称。这意味着对象不是相同的原因是因为agbg在对象中具有不同的节点排序。 如果我按节点名称重新排序成员资格,那么两者就会变得相同。

identical(membership(bc1)[order(names(membership(bc1)))], membership(ac1)[order(names(membership(ac1)))])
#[1] TRUE