Может ли кто-нибудь сказать мне, где в Интернете я могу найти объяснение алгоритма Брон-Кербоша для поиска кликов или объяснить здесь, как он работает?
Я знаю, что он был опубликован в книге «Алгоритм 457: поиск всех клик неориентированного графа», но я не могу найти бесплатный источник, описывающий алгоритм.
Мне не нужен исходный код алгоритма, мне нужно объяснение, как он работает.
Я имел в виду, что в Интернете нет книги, так как у меня не будет доступа к библиотеке около двух недель :(
Вместо того, чтобы спрашивать источник, лучше сказать «расскажите мне, как ... работает» вместе с описанием того, что конкретно вас озадачивает, тогда ответ (и контекст вашего вопроса) будет здесь для тех, кто столкнется с этим в будущем. Принятый здесь ответ почти бесполезен.





Попробуйте найти кого-нибудь со студенческой учетной записью ACM, который может дать вам копию статьи, которая находится здесь: http://portal.acm.org/citation.cfm?doid=362342.362367
Я только что скачал его, и это всего две страницы с реализацией на Algol 60!
не могли бы вы отправить его мне на [email protected]?
Как бы то ни было, я нашел реализацию на Java: http://joelib.cvs.sourceforge.net/joelib/joelib2/src/joelib2/algo/clique/BronKerbosch.java?view=markup
HTH.
Я нашел 2 реализации java и одну реализацию C. Может быть, это работает, но мне также нужно понимание того, как это работает, а в исходном коде не так много комментариев о том, как это работает.
Есть алгоритм справа здесь Я переписал его, используя связанные списки Java в качестве наборов R, P, X, и он работает как шарм (хорошо использовать функцию "keepAll" при выполнении операций с наборами в соответствии с алгоритмом).
Предлагаю немного подумать над реализацией из-за проблем с оптимизацией при переписывании алгоритма
Я нахожу объяснение алгоритма здесь: http://www.dfki.de/~neumann/ie-seminar/presentations/finding_cliques.pdf это хорошее объяснение ... но мне нужна библиотека или реализация на C# -.- '
Я реализовал обе версии, указанные в статье. Я узнал, что неоптимизированная версия, если она решена рекурсивно, очень помогает понять алгоритм. Вот реализация Python для версии 1 (неоптимизированная):
def bron(compsub, _not, candidates, graph, cliques):
if len(candidates) == 0 and len(_not) == 0:
cliques.append(tuple(compsub))
return
if len(candidates) == 0: return
sel = candidates[0]
candidates.remove(sel)
newCandidates = removeDisconnected(candidates, sel, graph)
newNot = removeDisconnected(_not, sel, graph)
compsub.append(sel)
bron(compsub, newNot, newCandidates, graph, cliques)
compsub.remove(sel)
_not.append(sel)
bron(compsub, _not, candidates, graph, cliques)
И вы вызываете эту функцию:
graph = # 2x2 boolean matrix
cliques = []
bron([], [], graph, cliques)
Переменная cliques будет содержать найденные клики.
Как только вы это поймете, легко реализовать оптимизированный вариант.
Разве даже версия 1 алгоритма не должна проверять, содержит ли она элемент, который является соседом каждого элемента в кандидатах, и возвращаться, если это так?
Boost :: Graph имеет отличную реализацию алгоритма Брон-Кербоша, проверьте его.
Я также пытался осмыслить алгоритм Брон-Кербоша, поэтому написал свою собственную реализацию на python. Он включает тестовый пример и некоторые комментарии. Надеюсь это поможет.
class Node(object):
def __init__(self, name):
self.name = name
self.neighbors = []
def __repr__(self):
return self.name
A = Node('A')
B = Node('B')
C = Node('C')
D = Node('D')
E = Node('E')
A.neighbors = [B, C]
B.neighbors = [A, C]
C.neighbors = [A, B, D]
D.neighbors = [C, E]
E.neighbors = [D]
all_nodes = [A, B, C, D, E]
def find_cliques(potential_clique=[], remaining_nodes=[], skip_nodes=[], depth=0):
# To understand the flow better, uncomment this:
# print (' ' * depth), 'potential_clique:', potential_clique, 'remaining_nodes:', remaining_nodes, 'skip_nodes:', skip_nodes
if len(remaining_nodes) == 0 and len(skip_nodes) == 0:
print 'This is a clique:', potential_clique
return
for node in remaining_nodes:
# Try adding the node to the current potential_clique to see if we can make it work.
new_potential_clique = potential_clique + [node]
new_remaining_nodes = [n for n in remaining_nodes if n in node.neighbors]
new_skip_list = [n for n in skip_nodes if n in node.neighbors]
find_cliques(new_potential_clique, new_remaining_nodes, new_skip_list, depth + 1)
# We're done considering this node. If there was a way to form a clique with it, we
# already discovered its maximal clique in the recursive call above. So, go ahead
# and remove it from the list of remaining nodes and add it to the skip list.
remaining_nodes.remove(node)
skip_nodes.append(node)
find_cliques(remaining_nodes=all_nodes)
Алекс, держу пари, что этот пост был отвергнут за «скажи мне, где в Интернете ...». Не проси людей делать твою работу. Просто попросите их пояснить, как это работает