python igraph,基于顶点名称/标签的图形相交/并集

python igraph,基于顶点名称/标签的图形相交/并集,python,graph,igraph,intersection,Python,Graph,Igraph,Intersection,我对Python和igraph尤其陌生。在我的学士学位论文中,我必须比较图,从而确定图的交集和并集。我尝试了以下方法: from igraph import * import json with open('test_graphs.json') as data_file: data = json.load(data_file) test1 = data['test1'] test2 = data['test2'] t1 = Graph(directed=True) for v in

我对Python和igraph尤其陌生。在我的学士学位论文中,我必须比较图,从而确定图的交集和并集。我尝试了以下方法:

from igraph import *
import json

with open('test_graphs.json') as data_file:
    data = json.load(data_file)

test1 = data['test1']
test2 = data['test2']

t1 = Graph(directed=True)
for v in test1:
    t1.add_vertex(v)
for v in test1:
    for o in test1[v]:
        t1.add_edge(v, o)
print(t1)

t2 = Graph(directed=True)
for v in test2:
    t2.add_vertex(v)
for v in test2:
    for o in test2[v]:
        t2.add_edge(v, o)

print(t2)

gr = t1.intersection(t2)
print(gr)
其中,我的json文件如下所示:

{
    "test1" : {
        "A": ["B","C"],
        "B": [],
        "C": []
    },

    "test2" : {
        "A": ["B","D"],
        "B": [],
        "D": []
    }
}
我希望交叉口的输出是A->B,但结果是出现了以下输出:

IGRAPH DN-- 3 2 --
+ attr: name (v)
+ edges (vertex names):
A->B, A->C
IGRAPH DN-- 3 2 --
+ attr: name (v)
+ edges (vertex names):
A->B, A->D
IGRAPH D--- 3 2 --
+ edges:
2->0 2->1
第一个和第二个打印的图形显示,两个输入图形都按预期工作(即使很难,我也不明白“attr”来自哪里?)。 但是输出图没有考虑两个图中的顶点A和B是相同的,而C和D是相同的。所以我的问题是:考虑到顶点的标签,如何确定图的交点(并模拟并集)

在由paqmo链接的问题中,维护人员表示,此功能(按顶点名称的并集或交集)在python igraph中不可用。因此,您必须自己编写函数来完成这项工作

这是欧盟的一种做法。将孤立的顶点添加到两个图中,以便它们都具有相同的顶点名称集,然后排列它们的两个顶点集,以便名称的顺序相同。然后标准的
union
方法(相当于
|
操作符)将做正确的事情。不幸的是,
union
方法没有维护属性,因此您必须重新添加名称以及所需的任何其他属性

def named_union(graph1, graph2):
    A = graph1.copy()
    B = graph2.copy() # so added vertices don't affect original graphs
    Anams = set(A.vs['name'])
    Bnams = set(B.vs['name'])
    A.add_vertices(list(Bnams - Anams))
    B.add_vertices(list(Anams - Bnams))
    nams = sorted(Anams | Bnams)
    Aind = [nams.index(nm) for nm in A.vs['name']]
    Bind = [nams.index(nm) for nm in B.vs['name']]
    A = A.permute_vertices(Aind) # permute vertices to come in same order as in nams
    B = B.permute_vertices(Bind) # ditto
    Z = A | B
    Z.vs['name'] = nams
    return Z
我们可以对交叉点执行类似的操作,除了从每个图中移除不在另一个图中的顶点,然后在使用标准的
交叉
方法(或
&
操作符)之前,将其余顶点以相同的顺序排列在两个图中

琐事:
delete_顶点
在给定一个集合时做正确的事情,但是
add_顶点
做不到,除非我们先将集合转换为列表。比如说,一个包含两个元素“A”和“B”的集合会导致添加两个顶点,这两个顶点都命名为
{'A','B'}
-这似乎是一个bug。

请查看此帖子:
def named_intersect(graph1, graph2):
    A = graph1.copy()
    B = graph2.copy() # so removed vertices don't affect original graphs
    Anams = set(A.vs['name'])
    Bnams = set(B.vs['name'])
    A.delete_vertices(Anams - Bnams)
    B.delete_vertices(Bnams - Anams)
    nams = sorted(Anams & Bnams)
    Aind = [nams.index(nm) for nm in A.vs['name']]
    Bind = [nams.index(nm) for nm in B.vs['name']]
    A = A.permute_vertices(Aind)
    B = B.permute_vertices(Bind)
    Z = A & B
    Z.vs['name'] = nams
    return Z