我特别擅长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是。所以我的问题是:考虑到顶点的标签,我如何确定图形的交点(和模拟联合)。
答案 0 :(得分:2)
在由paqmo链接的问题Perform union of graphs based on vertex names Python igraph中,维护者说这个功能(顶点名称的联合或交叉)在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
我们可以为交点做类似的事情,除了我们从每个图中删除不在另一个图中的顶点,然后在使用标准{{{}之前将其余顶点置换为两个图中的相同顺序1}}方法(或intersection
运算符)。
&
琐事: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
在给定集合时做正确的事情,但delete_vertices
没有,除非我们先将集合转换为列表。例如,一组有两个元素' A'和' B'导致添加两个顶点,都名为add_vertices
- 这似乎是一个错误。