【问题标题】:Python igraph vertex indicesPython igraph 顶点索引
【发布时间】:2015-04-20 03:52:25
【问题描述】:

我在 python 中使用 igraph 库。我想知道是否有一种使用字符串作为顶点索引的方法。我知道'name'属性并且我可以写

g = igraph.Graph(directed=True)
g.add_vertex('hello')
g.add_vertex('world')
g.add_edge('hello','world')

一切正常。除非我两次添加相同的顶点,例如:

g = igraph.Graph(directed=True)
g.add_vertex('world')
g.add_vertex('hello')
g.add_vertex('hello')

创建了两个不同的顶点,如果我现在添加一条边:

g.add_edge('hello','world')

边被添加到第一个匹配 'hello' 作为名称的顶点。这也表明这种形式的索引具有 O(n) 复杂性而不是 O(1)(即扫描整个顶点列表,直到找到一个顶点 v 以找到 v['name'] == 'hello')。

所以我在考虑保持顶点名称和索引之间的映射,例如:

mapping = {}
g = igraph.Graph(directed=True)
g.add_vertex('hello')
mapping['hello'] = len(g.vs)-1
g.add_vertex('world')
mapping['world'] = len(g.vs)-1
g.add_edge(mapping['hello'],mapping['world'])

我认为这应该可行,因为 我从不删除顶点,所以我猜索引应该保持不变。它还具有平均查找速度 O(1),应该比以前的解决方案更好。 但是我想知道:

  • 我是否总是保证g.vs[i].index == i? (即,我是否可以总是使用顶点在 vs 数组中的位置来在 add_edge() 等函数中引用该顶点?)
  • 我是否总是保证当我向图中添加一个新顶点时,它的索引将是len(g.vs)-1

编辑:关于边缘的相同问题:我保证我会在g.es[len(g.es)-1] 中找到最后添加的边缘吗?

【问题讨论】:

    标签: python indexing igraph


    【解决方案1】:

    这也表明这种形式的索引具有 O(n) 复杂度而不是 O(1)

    这不是真的; igraph 为name vertex 属性维护了一个从名称到顶点 ID(就像您建议的那样)的内部映射,该属性会在您添加或删除顶点时自动更新。如果有多个具有相同名称的顶点,则映射选择一个任意顶点,然后(一致地)返回该顶点以进行名称查找。在幕后,这一切都是用标准的 Python 字典完成的。因此,您可以安全地执行以下所有操作:

    • 当 igraph 函数或方法需要顶点 ID 时,使用顶点名称而不是顶点 ID
    • 使用g.vs.find("foo") 查找name 等于"foo" 的任意顶点。

    请注意,我们无法阻止用户创建具有相同名称的多个顶点,因为这在 igraph 可以读取的许多图形格式(例如 GraphML)中有效,并且我们不想阻止用户读取它们。

    我是否总是保证 g.vs[i].index == i?

    是的,这保证是真的。但是,以下不是:

    >>> v = g.vs[12]
    >>> g.delete_vertices(...)
    >>> g.vs[v.index] == v
    

    原因是顶点和边对象非常“愚蠢”,因为它们只存储对它们起源的图形的引用以及它们在图形中的索引 - 但是当图形本身更新时它们不会更新。经验法则是,一旦您对底层图进行变异,您持有引用的任何顶点或边对象都将变为“无效”。

    我是否总是保证当我向图中添加一个新顶点时,它的索引将为 len(g.vs)-1?

    严格来说,API 并不能保证这一点(作为正式的“合同”),但从 igraph 开发之初就一直如此,我认为未来任何时候都没有理由改变它。我也经常在自己的代码中依赖它。这同样适用于边缘。

    【讨论】:

    • 谢谢!因此,如果我不想依赖最后添加的顶点是 g.vs[len(g.vs)-1] 的事实,我该如何为最后添加的顶点设置属性,或者引用它来创建朝向它的边?
    • 目前不能;您必须相信 igraph 会将其添加为最后一个顶点。 (目前很多 igraph 用户都依赖这个,我认为这是一个安全的假设)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    • 1970-01-01
    • 2021-05-18
    • 2018-04-14
    • 2013-12-19
    • 2015-11-20
    相关资源
    最近更新 更多