Source code for networkx.algorithms.approximation.clique

"""用于计算大型团和最大独立集的函数。"""

import networkx as nx
from networkx.algorithms.approximation import ramsey
from networkx.utils import not_implemented_for

__all__ = [
    "clique_removal",
    "max_clique",
    "large_clique_size",
    "maximum_independent_set",
]


[docs] @not_implemented_for("directed") @not_implemented_for("multigraph") @nx._dispatchable def maximum_independent_set(G): """返回一个近似最大独立集。 独立集或稳定集是图中的一个顶点集合,其中任意两个顶点都不相邻。也就是说,它是一个顶点集合 I,对于 I 中的任意两个顶点,它们之间没有边相连。等价地,图中的每条边在 I 中最多有一个端点。一个独立集的大小是它包含的顶点数 [1]。 最大独立集是给定图 G 中的一个最大独立集,其大小记为 $\alpha(G)$。寻找这样一个集合的问题被称为最大独立集问题,是一个 NP 难优化问题。因此,不太可能存在一个有效的算法来找到一个图的最大独立集。 独立集算法基于 [2]。 Parameters ---------- G : NetworkX 图 无向图 Returns ------- iset : 集合 近似最大独立集 Examples -------- >>> G = nx.path_graph(10) >>> nx.approximation.maximum_independent_set(G) {0, 2, 4, 6, 9} Raises ------ NetworkXNotImplemented 如果图是有向的或是一个多重图。 Notes ----- 在最坏情况下找到 $O(|V|/(log|V|)^2)$ 的独立集近似。 References ---------- .. [1] `Wikipedia: 独立集 <https://en.wikipedia.org/wiki/Independent_set_(graph_theory)>`_ .. [2] Boppana, R., & Halldórsson, M. M. (1992). 通过排除子图来近似最大独立集。 BIT 数值数学, 32(2), 180–196. Springer. """ iset, _ = clique_removal(G) return iset
[docs] @not_implemented_for("directed") @not_implemented_for("multigraph") @nx._dispatchable def max_clique(G): r"""寻找最大团 在最坏情况下,找到图的最大团/独立集的 $O(|V|/(log|V|)^2)$ 近似解。 Parameters ---------- G : NetworkX 图 无向图 Returns ------- clique : 集合 图的近似最大团 Examples -------- >>> G = nx.path_graph(10) >>> nx.approximation.max_clique(G) {8, 9} Raises ------ NetworkXNotImplemented 如果图是有向的或多重图。 Notes ----- 无向图 G = (V, E) 中的团是顶点集的一个子集 `C \subseteq V` ,使得 C 中的每两个顶点之间都存在一条边。这等价于说由 C 诱导的子图是完全的(在某些情况下,术语“团”也可能指该子图)。 最大团是给定图中可能的最大团。图 G 的团数 `\omega(G)` 是 G 中最大团的顶点数。G 的交集数是覆盖 G 所有边的团的最小数量。 https://en.wikipedia.org/wiki/Maximum_clique References ---------- .. [1] Boppana, R., & Halldórsson, M. M. (1992). 通过排除子图来近似最大独立集。 BIT Numerical Mathematics, 32(2), 180–196. Springer. doi:10.1007/BF01994876 """ # finding the maximum clique in a graph is equivalent to finding # the independent set in the complementary graph cgraph = nx.complement(G) iset, _ = clique_removal(cgraph) return iset
[docs] @not_implemented_for("directed") @not_implemented_for("multigraph") @nx._dispatchable def clique_removal(G): r"""重复地从图中移除团。 结果得到一个 $O(|V|/(\log |V|)^2)$ 的最大团和独立集的近似解。返回找到的最大独立集以及找到的最大团。 Parameters ---------- G : NetworkX 图 无向图 Returns ------- max_ind_cliques : (集合, 列表) 元组 最大独立集和最大团的列表(集合)的 2-元组。 Examples -------- >>> G = nx.path_graph(10) >>> nx.approximation.clique_removal(G) ({0, 2, 4, 6, 9}, [{0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}]) Raises ------ NetworkXNotImplemented 如果图是有向的或是一个多重图。 References ---------- .. [1] Boppana, R., & Halldórsson, M. M. (1992). 通过排除子图来近似最大独立集。 BIT 数值数学, 32(2), 180–196. Springer. """ graph = G.copy() c_i, i_i = ramsey.ramsey_R2(graph) cliques = [c_i] isets = [i_i] while graph: graph.remove_nodes_from(c_i) c_i, i_i = ramsey.ramsey_R2(graph) if c_i: cliques.append(c_i) if i_i: isets.append(i_i) # Determine the largest independent set as measured by cardinality. maxiset = max(isets, key=len) return maxiset, cliques
[docs] @not_implemented_for("directed") @not_implemented_for("multigraph") @nx._dispatchable def large_clique_size(G): """寻找图中的一个大型团的大小。 *团* 是图中节点的一个子集,其中每对节点都相邻。此函数是一种启发式方法,用于寻找图中一个大型团的大小。 Parameters ---------- G : NetworkX 图 Returns ------- k: 整数 图中一个大型团的大小。 Examples -------- >>> G = nx.path_graph(10) >>> nx.approximation.large_clique_size(G) 2 Raises ------ NetworkXNotImplemented 如果图是有向的或是一个多重图。 Notes ----- 此实现来自 [1]。其最坏情况时间复杂度为 :math:`O(n d^2)` ,其中 *n* 是图中的节点数,*d* 是最大度数。 此函数是一种启发式方法,这意味着它在实践中可能表现良好,但对于返回的数字与图中实际最大团大小之间的比率,没有严格的数学保证。 References ---------- .. [1] Pattabiraman, Bharath, 等。 "大规模图上最大团问题的快速算法及其在重叠社区检测中的应用。" *Internet Mathematics* 11.4-5 (2015): 421--448. <https://doi.org/10.1080/15427951.2014.986778> See Also -------- :func:`networkx.algorithms.approximation.clique.max_clique` 返回具有近似比率保证的近似最大团的函数。 :mod:`networkx.algorithms.clique` 用于在图中寻找精确最大团的功能。 """ degrees = G.degree def _clique_heuristic(G, U, size, best_size): if not U: return max(best_size, size) u = max(U, key=degrees) U.remove(u) N_prime = {v for v in G[u] if degrees[v] >= best_size} return _clique_heuristic(G, U & N_prime, size + 1, best_size) best_size = 0 nodes = (u for u in G if degrees[u] >= best_size) for u in nodes: neighbors = {v for v in G[u] if degrees[v] >= best_size} best_size = _clique_heuristic(G, neighbors, 1, best_size) return best_size