我在算法课中的一个任务是设计一种穷举搜索算法来解决团问题。也就是说,给定一个大小为n的图,该算法应确定是否存在一个大小为k的完全子图。我认为我已经得出了答案,但我觉得它可以改进。以下是我的算法:
版本 1
输入:由数组 A[0,...n-1] 表示的图,要查找的子图大小为 k。
输出:如果存在子图,则为 True,否则为 False。
算法(类似于 Python 的伪代码):
def clique(A, k):
P = A x A x A //Cartesian product
for tuple in P:
if connected(tuple):
return true
return false
def connected(tuple):
unconnected = tuple
for vertex in tuple:
for test_vertex in unconnected:
if vertex is linked to test_vertex:
remove test_vertex from unconnected
if unconnected is empty:
return true
else:
return false
版本 2
输入: 一个大小为n×n的邻接矩阵,以及要查找的子图大小k
输出: A中所有大小为k的完全子图。
算法(这次使用函数式/Python伪代码):
//Base case: return all vertices in a list since each
//one is a 1-clique
def clique(A, 1):
S = new list
for i in range(0 to n-1):
add i to S
return S
//Get a tuple representing all the cliques where
//k = k - 1, then find any cliques for k
def clique(A,k):
C = clique(A, k-1)
S = new list
for tuple in C:
for i in range(0 to n-1):
//make sure the ith vertex is linked to each
//vertex in tuple
for j in tuple:
if A[i,j] != 1:
break
//This means that vertex i makes a clique
if j is the last element:
newtuple = (i | tuple) //make a new tuple with i added
add newtuple to S
//Return the list of k-cliques
return S
有没有人有什么想法、评论或建议?这包括我可能错过的错误以及使此更易读的方法(我不习惯使用伪代码)。
版本3
幸运的是,我在提交作业之前与教授交谈了。当我向他展示我写的伪代码时,他微笑着告诉我,我做的功夫实在太多了。首先,我不必提交伪代码;我只需要证明我理解了这个问题。其次,他是想要暴力解决方案的。所以我提交的东西看起来像这样:
输入:一个图G = (V,E),要查找的最大团的大小k
输出:若存在最大团则返回true,否则返回false
算法:
- 找到笛卡尔积 Vk。
- 对于结果中的每个元组,测试每个顶点是否与其他所有顶点相连通。如果全部相连,则返回true并退出。
- 返回false并退出。
更新:添加了第二个版本。我认为这一版越来越好了,虽然我还没有添加任何花哨的动态编程(至少我不知道)。
更新2:添加了一些注释和文档,使第二个版本更易读。这可能是我今天要提交的版本。感谢大家的帮助!我希望我能接受不止一个答案,但我接受了最帮助我的人的答案。我会让你们知道我教授的想法。