个人主页:丷从心
系列专栏:回溯法
给定无向图 G = ( V , E ) G = (V , E) G=(V,E),如果 U ? V U \subseteq V U?V,且对任意 u u u, v ∈ U v \in U v∈U有 ( u , v ) ∈ E (u , v) \in E (u,v)∈E,则称 U U U是 G G G的完全子图
G G G的完全子图 U U U是 G G G的一个团当且仅当 U U U不包含在 G G G的更大的完全子图中, G G G的最大团是指 G G G中所含顶点数最多的团
如果 U ? V U \subseteq V U?V且对任意 u u u, v ∈ U v \in U v∈U,有 ( u , v ) ? E (u , v) \notin E (u,v)∈/E,则称 U U U是 G G G的空子图
G G G的空子图 U U U是 G G G的独立集当且仅当 U U U不包含在 G G G的更大的空子图中, G G G的最大独立集是 G G G中所含顶点数最多的独立集
对于任意无向图 G = ( V , E ) G = (V , E) G=(V,E),其补图 G ˉ = ( V ′ , E ′ ) \bar{G} = (V^{'} , E^{'}) Gˉ=(V′,E′)定义为: V ′ = V V^{'} = V V′=V, E ′ = { ? ( u , v ) ∣ ( u , v ) ? E ? } E^{'} = \set{(u , v) \mid (u , v) \notin E} E′={(u,v)∣(u,v)∈/E}
如果 U U U是 G G G的完全子图,则它是 G ˉ \bar{G} Gˉ的空子图,反之亦然,因此, G G G的团与 G ˉ \bar{G} Gˉ的独立集之间存在一一对应关系,特别地, U U U是 G G G的最大团,当且仅当 U U U是 G ˉ \bar{G} Gˉ的最大独立集
无向图 G G G和 G G G的补图 G ˉ \bar{G} Gˉ如下图所示
Python
实现def find_maximum_clique(graph):
n = len(graph)
vertices = list(range(n))
max_clique = []
def is_clique(graph, vertices):
# 约束函数: 判断给定的顶点集合是否构成一个团(完全子图)
for i in range(len(vertices)):
for j in range(i + 1, len(vertices)):
if not graph[vertices[i]][vertices[j]]:
return False
return True
def bound(current_clique, neighbors):
# 限界函数
return len(current_clique) + len(neighbors)
def backtrack(graph, vertices, current_clique, max_clique):
if not vertices:
if len(current_clique) > len(max_clique):
max_clique.clear()
max_clique.extend(current_clique)
return
vertex = vertices.pop(0)
current_clique.append(vertex)
neighbors = []
for v in vertices:
if graph[vertex][v]:
neighbors.append(v)
# 选择当前顶点并加入团
if is_clique(graph, current_clique):
backtrack(graph, neighbors, current_clique, max_clique)
# 不选择当前顶点
if bound(current_clique, neighbors) > len(max_clique):
backtrack(graph, neighbors, current_clique[:-1], max_clique)
vertices.insert(0, vertex)
current_clique.pop()
backtrack(graph, vertices, [], max_clique)
return max_clique
graph = [
[0, 1, 0, 1, 1],
[1, 0, 1, 0, 1],
[0, 1, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 1, 1, 1, 0]
]
maximum_clique = find_maximum_clique(graph)
print(f'最大团: {maximum_clique}')
最大团: [0, 1, 4]