二分图最大独立集(最大团)

最大独立集的定义

二分图的最大独立集是:一个最大的点的集合,该集合内的任意两点没有边相连。

二分图最大团的定义是:一个最大的点的集合,该集合内的任意两点都有边相连。

从定义可以看出"二分图的最大独立集"和"二分图补图的最大团"是一样的。

 

最大独立集的求法

二分图的最大独立集 = 二分图顶点数 - 二分图最大匹配数。

设二分图的顶点数为n,最大匹配数是v。

二分图的最大独立集 = n - v。

(1)把二分图的最大匹配从原图中去掉,剩下的n - 2 * v个顶点肯定是没有边相连的,如果还有边相连那还叫二分图最大匹配吗。此时的n - 2 * v个顶点就是一个独立集,但不是最大的。

(2)从每条匹配边的两端取一个结点加入独立集中,可以使得独立集仍然是独立集,所以此时独立集的顶点数是n - v。为什么可以从每条匹配边的两端各取一个点加入独立集中呢?因为①要么{x}到y4有一条边,要么②{y}到x4有一条边,③要么{x}到y4没有边且{y}到x4也没有边。不可能出现下图这种情况,④{x}到y4有边且{y}到x4也有边,那么这就是一条增广路了,与原先求出的最大匹配相矛盾,所以不可能出现下图的情况。

综上所述,只会发生①②③这三种情况,所以我们一定可以从每条匹配边的两端取一个结点加入到独立集中。

 

该文章在我的个人博客地址是:http://www.alphaway.org/post-451.html

 

转载于:https://www.cnblogs.com/justPassBy/p/5416668.html

### 最大独立集求解算法的概述与实现 最大独立集问题是图论中的一个经典问题,其目标是从图中找到一个顶点子集,使得该子集中没有任何两个顶点在图中相邻。如果每个顶点都有权重,则需要找到权重和最大独立集,称为最大加权独立集[^1]。由于该问题已被证明为NP完全问题[^1],因此通常需要使用启发式方法或近似算法来解决大规模实例。 以下是几种常见的求解最大独立集的方法及其程序实现: --- #### 1. **暴力枚举法** 暴力枚举法通过检查所有可能的顶点子集来找到最大独立集。这种方法的时间复杂度为 \(O(2^n)\),其中 \(n\) 是图中顶点的数量,因此仅适用于小规模图。 ```python from itertools import combinations def max_independent_set(graph): nodes = list(graph.keys()) max_set = [] for r in range(len(nodes), 0, -1): for subset in combinations(nodes, r): if all(u not in graph[v] for u, v in combinations(subset, 2)): return subset return max_set ``` 上述代码中,`graph` 是一个邻接表表示的图。通过枚举所有可能的顶点子集,并验证是否满足独立集条件(即子集中任意两点不相邻),最终返回最大独立集[^1]。 --- #### 2. **基于最大团的转换** 最大独立集问题可以转化为求补图的最大团问题。具体来说,图 \(G\)最大独立集等价于其补图 \(\overline{G}\)最大团。这种方法可以通过 Bron-Kerbosch 算法或其他最大团算法实现。 ```python def bron_kerbosch(r, p, x, graph): if not p and not x: return [r] max_cliques = [] for v in list(p): new_r = r.union({v}) new_p = p.intersection(graph[v]) new_x = x.intersection(graph[v]) max_cliques += bron_kerbosch(new_r, new_p, new_x, graph) p.remove(v) x.add(v) return max_cliques def max_clique(graph): nodes = set(graph.keys()) return max(bron_kerbosch(set(), nodes, set(), graph), key=len) def max_independent_set_via_clique(graph): complement_graph = {u: set(graph.keys()) - graph[u] - {u} for u in graph} return max_clique(complement_graph) ``` 上述代码实现了 Bron-Kerbosch 算法以求解最大团,并将其应用于补图以求解最大独立集[^1]。 --- #### 3. **二分图的特殊性质** 对于二分图最大独立集可以通过最大匹配来求解。根据引用内容[^3],设 \(V'\)最大独立集,\(M\)最大匹配的边数,则有 \(|V'| = |V| - \frac{|M|}{2}\)。这提供了一种高效的解决方案。 ```python from collections import defaultdict def bfs_matching(graph, match, visited, u): queue = [u] parent = {} while queue: v = queue.pop(0) for w in graph[v]: if not visited[w]: visited[w] = True parent[w] = v if match[w] == -1 or bfs_matching(graph, match, visited, match[w]): match[w] = v match[v] = w return True return False def max_matching(graph, left_nodes, right_nodes): match = defaultdict(lambda: -1) result = 0 for u in left_nodes: visited = defaultdict(bool) if bfs_matching(graph, match, visited, u): result += 1 return result def max_independent_set_bipartite(graph, left_nodes, right_nodes): matching_size = max_matching(graph, left_nodes, right_nodes) return len(left_nodes) + len(right_nodes) - matching_size ``` 上述代码实现了基于最大匹配的二分图最大独立集求解方法[^3]。 --- #### 4. **启发式算法** 对于大规模图,可以使用启发式算法来近似求解最大独立集。一种简单的方法是贪心算法:每次选择度数最小的顶点加入独立集,并从图中移除该顶点及其邻居。 ```python def greedy_max_independent_set(graph): independent_set = set() nodes = list(graph.keys()) while nodes: # 选择度数最小的顶点 u = min(nodes, key=lambda x: len(graph[x])) independent_set.add(u) # 移除 u 及其邻居 nodes = [v for v in nodes if v != u and v not in graph[u]] return independent_set ``` --- ### 总结 最大独立集问题是一个经典的NP完全问题,其求解方法包括暴力枚举、基于最大团的转换、二分图的特殊性质以及启发式算法。每种方法都有其适用场景,具体选择取决于图的规模和结构。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值