图分析
igraph 支持对图/网络进行分析,从添加和移除节点等简单操作到社区检测等复杂的理论构建。请阅读 API 参考 以获取每个函数和类的详细信息。
以下示例的上下文是导入 igraph(通常命名为 ig),拥有 Graph 类,并拥有一个或多个可用的图。
>>> import igraph as ig
>>> from igraph import Graph
>>> g = Graph(edges=[[0, 1], [2, 3]])
要获取图的摘要表示,请使用 Graph.summary()。例如
>>> g.summary(verbosity=1)
将提供相当详细的描述。
要复制图,请使用 Graph.copy()。这是一个“浅”复制:属性中的任何可变对象都不会被复制(它们将引用相同的实例)。如果您想复制一个包含所有属性的图,请使用 Python 的 deepcopy 模块。
顶点和边
顶点编号从 0 到 n-1,其中 n 是图中顶点的数量。这些被称为“顶点 ID”。要计算顶点数量,请使用 Graph.vcount()
>>> n = g.vcount()
边也具有从 0 到 m-1 的 ID,并通过 Graph.ecount() 计算。
>>> m = g.ecount()
要获取顶点序列,请使用它们的 ID 和 Graph.vs
>>> for v in g.vs:
>>> print(v)
类似地,对于边,请使用 Graph.es
>>> for e in g.es:
>>> print(e)
您可以像索引和切片列表一样索引和切片顶点和边
>>> g.vs[:4]
>>> g.vs[0, 2, 4]
>>> g.es[3]
注意
vs 和 es 属性是特殊的序列,它们有自己有用的方法。请参阅 API 参考 以获取完整列表。
如果您偏好简单的边列表,可以使用 Graph.get_edge_list()。
关联
要获取一条边两端的顶点,请使用 Edge.source 和 Edge.target
>>> e = g.es[0]
>>> v1, v2 = e.source, e.target
反之,要从源顶点和目标顶点获取边,可以使用 Graph.get_eid();或者,对于多对源/目标,使用 Graph.get_eids()。布尔版本,询问两个顶点是否直接连接,是 Graph.are_adjacent()。
要获取顶点上的关联边,可以使用 Vertex.incident()、Vertex.out_edges() 和 Vertex.in_edges()。这三者在无向图上是等价的,但在有向图上则不然。
>>> v = g.vs[0]
>>> edges = v.incident()
Graph.incident() 函数实现相同目的,但语法略有不同,基于顶点 ID。
>>> edges = g.incident(0)
要获取图的完整邻接/关联列表表示,请使用 Graph.get_adjlist()、Graph.g.get_inclist() 或者,对于二部图,使用 Graph.get_biadjacency()。
邻域
要计算邻居、后继和前驱,可以使用方法 Graph.neighbors()、Graph.successors() 和 Graph.predecessors()。这三者在无向图中给出相同结果,但在有向图中则不然。
>>> neis = g.vs[0].neighbors()
>>> neis = g.neighbors(0)
要获取距离一个或多个初始顶点在一定距离内的顶点列表,可以使用 Graph.neighborhood()
>>> g.neighborhood([0, 1], order=2)
要查找邻域大小,有 Graph.neighborhood_size()。
度
要计算节点的度、入度或出度,请使用 Vertex.degree()、Vertex.indegree() 和 Vertex.outdegree()
>>> deg = g.vs[0].degree()
>>> deg = g.degree(0)
要计算顶点列表中最大度,请使用 Graph.maxdegree()。
Graph.knn() 计算邻居的平均度。
添加和移除顶点与边
要向图添加节点,请使用 Graph.add_vertex() 和 Graph.add_vertices()
>>> g.add_vertex()
>>> g.add_vertices(5)
这会就地更改图 g。如果需要,可以指定顶点的名称。
要移除节点,请使用 Graph.delete_vertices()
>>> g.delete_vertices([1, 2])
同样,您可以指定名称或实际的 Vertex 对象。
要添加边,请使用 Graph.add_edge() 和 Graph.add_edges()
>>> g.add_edge(0, 2)
>>> g.add_edges([(0, 2), (1, 3)])
要移除边,请使用 Graph.delete_edges()
>>> g.delete_edges([0, 5]) # remove by edge id
您也可以移除源节点和目标节点之间的边。
要收缩顶点,请使用 Graph.contract_vertices()。收缩顶点之间的边将变成自环。
图操作
可以计算图之间的并集、交集、差集以及其他集合操作(运算符)。
要计算图的并集(保留任一图中的节点/边)
>>> gu = ig.union([g, g2, g3])
类似地,对于交集(保留所有图中都存在的节点/边)
>>> gu = ig.intersection([g, g2, g3])
这两个操作保留属性,并可以有几种变体。最重要的一点是,顶点可以在图中通过 ID(数字)或名称进行匹配。
这些及其他操作也可作为 Graph 类的方法使用
>>> g.union(g2)
>>> g.intersection(g2)
>>> g.disjoint_union(g2)
>>> g.difference(g2)
>>> g.complementer() # complement graph, same nodes but missing edges
甚至作为数值运算符
>>> g |= g2
>>> g_intersection = g and g2
拓扑排序
要对图进行拓扑排序,请使用 Graph.topological_sorting()
>>> g = ig.Graph.Tree(10, 2, mode=ig.TREE_OUT)
>>> g.topological_sorting()
图遍历
一个常见的操作是遍历图。igraph 当前通过 Graph.bfs() 和 Graph.bfsiter() 公开广度优先搜索(BFS)。
>>> [vertices, layers, parents] = g.bfs()
>>> it = g.bfsiter() # Lazy version
深度优先搜索通过 Graph.dfs() 和 Graph.dfsiter() 具有类似的架构。
>>> [vertices, parents] = g.dfs()
>>> it = g.dfsiter() # Lazy version
要从某个顶点执行随机游走,请使用 Graph.random_walk()
>>> vids = g.random_walk(0, 3)
路径查找与割
有几种路径查找算法可用
Graph.shortest_paths()或Graph.get_shortest_paths()Graph.get_all_shortest_paths()Graph.spanning_tree()查找最小生成树
以及与割和路径相关的函数
Graph.mincut()计算源顶点和目标顶点之间的最小割Graph.st_mincut()- 与前一个类似,但返回一个更简单的数据结构Graph.mincut_value()- 与前一个类似,但仅返回值Graph.edge_connectivity()或Graph.edge_disjoint_paths()或Graph.adhesion()Graph.vertex_connectivity()或Graph.cohesion()
另请参阅关于流的部分。
全局属性
提供了一些全局图度量。
基本
Graph.diameter()或Graph.get_diameter()Graph.girth()Graph.radius()Graph.average_path_length()
分布
连通性
Graph.all_minimal_st_separators()Graph.minimum_size_separators()Graph.cut_vertices()或Graph.articulation_points()
团和模体
Graph.clique_number()(又称Graph.omega())Graph.cliques()Graph.maximal_cliques()Graph.largest_cliques()Graph.motifs_randesu()和Graph.motifs_randesu_estimate()Graph.motifs_randesu_no()计算模体的数量
有向无环图
Graph.is_dag()Graph.feedback_arc_set()Graph.topological_sorting()
最优性
Graph.farthest_points()Graph.maximal_cliques()Graph.largest_cliques()Graph.independence_number()(又称Graph.alpha())Graph.maximal_independent_vertex_sets()Graph.largest_independent_vertex_sets()Graph.mincut_value()Graph.feedback_arc_set()
其他复杂度量包括
Graph.assortativity()Graph.assortativity_degree()Graph.assortativity_nominal()Graph.density()Graph.transitivity_undirected()Graph.reciprocity()(有向图)Graph.isoclass()(仅限 3 或 4 个顶点)
布尔属性
Graph.is_bipartite()Graph.is_connected()Graph.is_dag()Graph.is_directed()Graph.is_simple()Graph.has_multiple()
顶点属性
可以计算一系列顶点级别的属性。相似性度量包括
Graph.similarity_dice()Graph.similarity_jaccard()Graph.similarity_inverse_log_weighted()Graph.diversity()
结构
Graph.authority_score()Graph.hub_score()Graph.betweenness()Graph.bibcoupling()Graph.closeness()Graph.constraint()Graph.cocitation()Graph.coreness()(又称Graph.shell_index())Graph.eccentricity()Graph.eigenvector_centrality()Graph.harmonic_centrality()Graph.personalized_pagerank()Graph.strength()Graph.transitivity_local_undirected()
连通性
Graph.subcomponent()Graph.is_separator()Graph.is_minimal_separator()
边属性
与顶点类似,边属性也已实现。基本属性包括
Graph.is_loop()Graph.is_multiple()Graph.is_mutual()Graph.count_multiple()
以及更复杂的属性
Graph.edge_betweenness()
矩阵表示
与矩阵相关的功能包括
Graph.get_adjacency_sparse()(稀疏 CSR 矩阵版本)Graph.laplacian()
聚类
igraph 包含几种无监督图聚类和社区检测方法
Graph.community_multilevel()(Louvain 的一个版本)Graph.community_optimal_modularity()(精确解,< 100 个顶点)
简化、置换和重布线
要检查图是否简单,可以使用 Graph.is_simple()
>>> g.is_simple()
要简化图(移除多重边和自环),请使用 Graph.simplify()
>>> g_simple = g.simplify()
要返回图的有向/无向副本,请分别使用 Graph.as_directed() 和 Graph.as_undirected()。
要置换顶点的顺序,可以使用 Graph.permute_vertices()
>>> g = ig.Tree(6, 2)
>>> g_perm = g.permute_vertices([1, 0, 2, 3, 4, 5])
可以通过 Graph.canonical_permutation() 获取规范置换,然后可以直接传递给上述函数。
要随机重布线图,有以下方法:
Graph.rewire()- 保留度分布Graph.rewire_edges()- 每个端点的重布线概率固定
线图
要计算图 g 的线图(表示 g 的边的连通性),可以使用 Graph.linegraph()
>>> g = Graph(n=4, edges=[[0, 1], [0, 2]])
>>> gl = g.linegraph()
在这种情况下,线图有两个顶点,代表原始图的两条边,以及一条边,代表这两条原始边接触的点。
组合和子图
函数 Graph.decompose() 将图分解为子图。反之,函数 Graph.compose() 返回两个图的组合。
要计算由某些顶点/边张成的子图,请使用 Graph.subgraph() (又称 Graph.induced_subgraph())和 Graph.subgraph_edges()
>>> g_sub = g.subgraph([0, 1])
>>> g_sub = g.subgraph_edges([0])
要计算最小生成树,请使用 Graph.spanning_tree()。
要计算图 k 核,可以使用方法 Graph.k_core()。
可以从给定节点使用 Graph.dominator() 获取支配树。
可以使用 Graph.bipartite_projection() 分解二部图。投影的大小可以使用 Graph.bipartite_projection_size() 计算。
同态
igraph 支持图之间的比较
Graph.isomorphic()Graph.isomorphic_vf2()Graph.subisomorphic_vf2()Graph.subisomorphic_lad()Graph.get_isomorphisms_vf2()Graph.get_subisomorphisms_vf2()Graph.get_subisomorphisms_lad()Graph.count_isomorphisms_vf2()Graph.count_subisomorphisms_vf2()
流
流是有向图的一个特性。提供以下函数
Graph.maxflow()在两个节点之间Graph.maxflow_value()- 类似于前一个,但仅返回值
流和割密切相关,因此您可能会发现以下函数也很有用
Graph.mincut()计算源顶点和目标顶点之间的最小割Graph.st_mincut()- 与前一个类似,但返回一个更简单的数据结构Graph.mincut_value()- 与前一个类似,但仅返回值Graph.edge_connectivity()或Graph.edge_disjoint_paths()或Graph.adhesion()Graph.vertex_connectivity()或Graph.cohesion()