我的算法类中的一个任务是设计一个详尽的搜索算法来解决clique问题。也就是说,给定大小 n 的图表,该算法应该确定是否存在大小 k 的完整子图。我想我已经得到了答案,但我不禁想到它可以改进。这就是我所拥有的:
输入:由数组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
输入:大小为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
有人有任何想法,意见或建议吗?这包括我可能错过的错误以及使其更具可读性的方法(我不习惯使用很多伪代码)。
幸运的是,在提交作业之前,我和我的教授谈过了。当我向他展示我写的伪代码时,他微笑着告诉我,我做了太多的工作 way 。首先,我没有提交伪代码;我只需证明我理解了这个问题。还有两个,他想要蛮力解决方案。所以我上交的内容看起来像这样:
输入:图表G =(V,E),要找到的集团的大小 k
输出:如果clique确实存在则为True,否则为false
算法:
更新:添加了第二个版本。虽然我没有添加任何花哨的动态编程(我知道),但我认为这会越来越好。
更新2 :添加了更多评论和文档,以使版本2更具可读性。这可能是我今天转的版本。谢谢大家的帮助!我希望我能接受不止一个答案,但我接受了最能帮助我的人的答案。我会让你们知道我的教授的想法。
答案 0 :(得分:8)
一些意见:
connected(tuple)
看起来不正确。你不需要在循环中重置unconnected
吗?答案 1 :(得分:2)
我曾经使用算法来查找图表中的所有最大派系,这与您的问题类似。我这样做的方式是基于这篇论文:http://portal.acm.org/citation.cfm?doid=362342.362367 - 它描述了一个回溯解决方案,我发现它非常有用作为指南,尽管我从那篇论文中做了很多改变。虽然你需要订阅才能获得,但我认为你的大学将有一个可用。
关于那篇论文的一件事是,我真的认为他们应该将“未设置”命名为“已经考虑过的设置”,因为它太混乱了。
答案 2 :(得分:2)
算法“对于每个k元组的顶点,如果它是一个集团,那么返回true”肯定是有效的。然而,这是一种蛮力,这可能不是算法课程所寻求的。相反,请考虑以下事项:
这个想法可能会带来更好的方法。
答案 3 :(得分:1)
答案 4 :(得分:0)
令人惊讶的是,输入内容的问题将向您展示您刚刚撰写的内容。这一行:
P = A x A x A //Cartesian product
应该是这样的:
P = A k //笛卡儿积
你是什么意思A ^ k?你正在服用基质产品吗?如果是这样,A是一个邻接矩阵(你说它是一个n + 1个元素的数组)?
在setbuilder表示法中,它看起来像这样:
P = {(x0,x1,... xk)| x0∈A和x1∈A......和xk∈A}
它基本上只是A的笛卡尔乘积k次。在纸面上,我写下来,因为k是A的上标(我刚才想到如何使用降价来做到这一点)。
另外,A只是每个顶点的数组而不考虑邻接。