python,带顶点重新编号的igraph

python,带顶点重新编号的igraph,python,igraph,Python,Igraph,我正在使用python+igraph实现一个在有向图中查找稠密子图的算法。主循环维护两个子图S和T,这两个子图最初是相同的,并根据这些节点相对于另一个图的indegree(或outdegree)计数删除节点(和入射边)。我遇到的问题是,igraph对顶点重新编号,所以当我从T中删除一些顶点时,剩下的节点不再对应于S中的相同节点 这里是循环的主要部分,它是关键 def directed(S): T = S.copy() c = 2 while(S.vcount() >

我正在使用python+igraph实现一个在有向图中查找稠密子图的算法。主循环维护两个子图S和T,这两个子图最初是相同的,并根据这些节点相对于另一个图的indegree(或outdegree)计数删除节点(和入射边)。我遇到的问题是,igraph对顶点重新编号,所以当我从T中删除一些顶点时,剩下的节点不再对应于S中的相同节点

这里是循环的主要部分,它是关键

def directed(S):
    T = S.copy()
    c = 2
    while(S.vcount() > 0 and T.vcount() > 0):
        if (S.vcount()/T.vcount() > c):
            AS = S.vs.select(lambda vertex: T.outdegree(vertex) < 1.01*E(S,T)/S.vcount())
            S.delete_vertices(AS)
        else:
            BT = T.vs.select(lambda vertex: S.indegree(vertex) < 1.01*E(S,T)/T.vcount())
            T.delete_vertices(BT)
def定向:
T=S.copy()
c=2
而(S.vcount()>0和T.vcount()>0):
如果(S.vcount()/T.vcount()>c):
AS=S.vs.select(lambda顶点:T.outdegree(顶点)<1.01*E(S,T)/S.vcount())
S.delete_顶点(如图所示)
其他:
BT=T.vs.select(lambda顶点:S.indegree(顶点)<1.01*E(S,T)/T.vcount())
T.删除顶点(BT)

这不起作用,因为删除顶点ID上的顶点会产生影响。是否有解决此问题的标准方法?

一种可能是为
name
顶点属性中的顶点指定唯一的名称。移除顶点时,这些顶点保持不变(与顶点ID不同),您可以使用它们在函数中引用顶点,如
indegree
outdegree
。例如:

>>> g = Graph.Ring(4)
>>> g.vs["name"] = ["A", "B", "C", "D"]
>>> g.degree("C")
2
>>> g.delete_vertices(["B"])
>>> g.degree("C")
1
请注意,我已经删除了vertex
B
,因此vertex
C
也获得了一个新ID,但名称仍然相同

在您的情况下,具有
select
条件的行可能会这样重新写入:

AS = S.vs.select(lambda vertex: T.outdegree(vertex["name"]) < 1.01 * E(S,T)/S.vcount())
AS=S.vs.select(lambda顶点:T.outdegree(顶点[“名称])<1.01*E(S,T)/S.vcount())

当然,这假设最初的顶点名称在
S
T
中是相同的,谢谢。如果使用graph.read\u Ncol()读入该图(它有数百万个节点/边),该方法将如何工作?我是否应该编写一个循环,用自己的id命名每个顶点?您可以使用
g.vs[“name”]=list\u of_names
,一次为所有顶点指定名称,就像我在示例中所做的那样(参见第二行)。但实际上,如果使用
Graph.Read\u Ncol
,name属性已经存在,它包含原始Ncol文件中的名称。