派系问题算法设计
我的算法课上的作业之一是设计一种穷举搜索算法来解决派系问题。 也就是说,给定一个大小为 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
有人有任何想法、评论或建议吗? 这包括我可能错过的错误以及使其更具可读性的方法(我不习惯使用太多伪代码)。
第三版
幸运的是,我在提交作业之前和我的教授谈过。 当我向他展示我编写的伪代码时,他微笑着告诉我,我做了太多工作。 其一,我不必提交伪代码; 我只需证明我理解这个问题。 第二,他想要暴力解决方案。 所以我提交的内容看起来像这样:
的团的大小
输入:图形 G = (V,E),找到k 输出 strong>:如果派确实存在,则为 true,否则为 false
算法:
- 求笛卡尔积 Vk。
- 对于结果中的每个元组,测试每个顶点是否相互连接。 如果全部连接,则返回 true 并退出。
- 返回 false 并退出。
更新:添加了第二个版本。 我认为这正在变得更好,尽管我没有添加任何花哨的动态编程(据我所知)。
更新 2:添加了更多注释和文档,使版本 2 更具可读性。 这可能就是我今天提交的版本。 感谢大家的帮助! 我希望我能接受多个答案,但我接受了对我帮助最大的人的答案。 我会让你们知道我的教授的想法。
One of the assignments in my algorithms class is to design an exhaustive search algorithm to solve the clique problem. That is, given a graph of size n, the algorithm is supposed to determine if there is a complete sub-graph of size k. I think I've gotten the answer, but I can't help but think it could be improved. Here's what I have:
Version 1
input: A graph represented by an array A[0,...n-1], the size k of the subgraph to find.
output: True if a subgraph exists, False otherwise
Algorithm (in python-like pseudocode):
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
Version 2
input: An adjacency matrix of size n by n, and k the size of the subgraph to find
output: All complete subgraphs in A of size k.
Algorithm (this time in functional/Python pseudocode):
//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
Does anybody have any thoughts, comments, or suggestions? This includes bugs I might have missed as well as ways to make this more readable (I'm not used to using much pseudocode).
Version 3
Fortunately, I talked to my professor before submitting the assignment. When I showed him the pseudo-code I had written, he smiled and told me that I did way too much work. For one, I didn't have to submit pseudo-code; I just had to demonstrate that I understood the problem. And two, he was wanting the brute force solution. So what I turned in looked something like this:
input: A graph G = (V,E), the size of the clique to find k
output: True if a clique does exist, false otherwise
Algorithm:
- Find the Cartesian Product Vk.
- For each tuple in the result, test whether each vertex is connected to every other. If all are connected, return true and exit.
- Return false and exit.
UPDATE: Added second version. I think this is getting better although I haven't added any fancy dynamic programming (that I know of).
UPDATE 2: Added some more commenting and documentation to make version 2 more readable. This will probably be the version I turn in today. Thanks for everyone's help! I wish I could accept more than one answer, but I accepted the answer by the person that's helped me out the most. I'll let you guys know what my professor thinks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
一些评论:
connected(tuple)
看起来不对。 您不需要在循环内重置unconnected
吗?Some comments:
connected(tuple)
doesn't look right. Don't you need to resetunconnected
inside the loop?我曾经实现了一种算法来查找图中的所有最大派系,这与您的问题类似。 我的做法是基于这篇论文: http://portal.acm.org /itation.cfm?doid=362342.362367 - 它描述了一个回溯解决方案,我发现它作为指南非常有用,尽管我对该论文进行了很多更改。 不过,您需要订阅才能获得此服务,但我想您的大学应该有订阅服务。
不过,关于那篇论文的一件事是,我真的认为他们应该将“未设置”命名为“已考虑设置”,因为否则就太混乱了。
I once implemented an algorithm to find all maximal cliques in a graph, which is a similar problem to yours. The way I did it was based on this paper: http://portal.acm.org/citation.cfm?doid=362342.362367 - it described a backtracking solution which I found very useful as a guide, although I changed quite a lot from that paper. You'd need a subscription to get at that though, but I presume your University would have one available.
One thing about that paper though is I really think they should have named the "not set" the "already considered set" because it's just too confusing otherwise.
“对于每个 k 元组顶点,如果它是一个派系,则返回 true”的算法肯定有效。 然而,它是蛮力,这可能不是算法课程所寻求的。 相反,请考虑以下事项:
这个想法可能会带来更好的方法。
The algorithm "for each k-tuple of vertices, if it is a clique, then return true" works for sure. However, it's brute force, which is probably not what an algorithms course is searching for. Instead, consider the following:
This idea might lead to a better approach.
令人惊奇的是,将内容作为问题写下来会告诉你刚刚写的内容。 这一行:
应该是这样的:
P = A k //笛卡尔积
在 setbuilder 表示法中,它看起来像这样:
它基本上只是 A 乘 k 次的笛卡尔积。 在纸上,我把它写下来,k 是 A 的上标(我现在才知道如何使用 markdown 来做到这一点)。
另外,A 只是每个单独顶点的数组,不考虑邻接关系。
It's amazing what typing things down as a question will show you about what you've just written. This line:
should be this:
P = A k //Cartesian product
In setbuilder notation, it would look something like this:
It's basically just a Cartesian product of A taken k times. On paper, I wrote it down as k being a superscript of A (I just now figured out how to do that using markdown).
Plus, A is just an array of each individual vertex without regard for adjacency.