关于无向图的最大团的问题。
今天观摩别人代码的时候,出现了求无向图最大团。
描述:团就是最大完全子图。(极大团)
给定无向图G=(V,E)。如果U包含于V,且对任意u,v属于U且有(u,v)属于E,则称U是G的完全子图。
G的完全子图U是G的团当且仅当U不包含在G的更大的完全子图中,即U就是最大完全子图。
G的最大团是指G中所含顶点数最多的团。(团中的顶点两两互连)
// 最大团: V中取K个顶点,两点间相互连接
// 最大独立集: V中取K个顶点,两点间不连接
// 最大团数量: 补图中最大独立集数
在看最大团,学习api的过程中,看到一个很有趣的问题:n个汉字两两组成常见词语,求n的最大值,任意两个字只要能组成一个常用词语就行,不需要正反都能组成词语。
解答:
作者:王赟 Maigo
链接:https://www.zhihu.com/question/50112280/answer/119428441
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
链接:https://www.zhihu.com/question/50112280/answer/119428441
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
原问题可以抽象成一个图论问题:把每个汉字看成无向图中的一个顶点,若两个字可以组成词,则在两个点之间连一条边,求图中最大的「团」(clique,即顶点全部两两相连的子图)。
首先,构造图的数据从哪儿来呢?我从网上找了一个《现代汉语常用词汇表》,用其中的所有双字词建了一个图。
然后,就要找图中的团了。不幸的是,Clique problem是一个NP-complete问题,无法在多项式时间内求解。但是,我们的图有它的特殊性,即里面不太可能有很大的团。为何不试试运气呢?而且算法都不需要我亲手实现,有现成的库可以用:
Clique — NetworkX 1.9.1 documentation
# -*- coding: utf-8 -*-
import codecs
import networkx as nx
DICT_FILE = u'现代汉语常用词汇表.txt'
G = nx.Graph()
with codecs.open(DICT_FILE, 'r', encoding = 'utf-8') as f:
for line in f:
if len(line.strip()) == 2:
G.add_edge(line[0], line[1])
cliques = list(nx.find_cliques(G))
N = max(len(c) for c in cliques)
for c in sorted(''.join(sorted(c)) for c in cliques if len(c) == N):
print c