проблема алгоритма

Граф — это подграф графа, в котором любая вершина связана с остальными вершинами.

В k-задаче входными данными являются неориентированный граф и число k, а выходными данными является clof размера k, если он существует (или, иногда, все cl размера k)


person Cristo    schedule 01.01.2010    source источник
comment
Домашнее задание? Если это так, используйте тег домашнего задания.   -  person Mark Byers    schedule 01.01.2010
comment
Это скопировано прямо из вопроса домашнего задания? В чем ваше сомнение? Как далеко вы можете пройти без посторонней помощи?   -  person R. Martinho Fernandes    schedule 01.01.2010
comment
В чем именно заключается ваш вопрос? У вас есть конкретный вопрос или вы просто хотите, чтобы мы отправили код? Кроме того, на каком языке? Как далеко вы продвинулись в решении проблемы самостоятельно? Если у вас есть какой-то нерабочий код, можете ли вы опубликовать его и сообщить нам, какую ошибку вы получаете?   -  person Mark Byers    schedule 01.01.2010
comment
если вы нажмете на тег clique-problem выше, вы, вероятно, получите мгновенную помощь.   -  person Alon    schedule 01.01.2010
comment
В любом языке программирования Марк. Допустим, это какое-то домашнее задание. Мартиньо, немного кода дало бы мне огромный толчок. Спасибо. ;)   -  person Cristo    schedule 01.01.2010
comment
Я думаю этот вопрос вам очень поможет   -  person TheVillageIdiot    schedule 01.01.2010
comment
... или даже лучше какой-нибудь псевдокод. :)   -  person Cristo    schedule 01.01.2010


Ответы (2)


Предположим без ограничения общности, что узлы графа идентифицируются целыми числами от 0 до N-1 (без потери общности, потому что, если каждый узел должен нести другую информацию, вы можете иметь массив/вектор/список объектов N узлов, и принять эти целые числа как индексы в рассматриваемом массиве). Связность графа может быть указана, например, путем сопоставления каждого узла с набором, являющимся непосредственными соседями узла.

Для проверки соединения, а не непосредственной смежности, вам скорее понадобится другое сопоставление — переходное замыкание отображения непосредственных соседей. Конечно, для этого есть хорошие алгоритмы (см., например, исходный код Python для networkx package), но грубая сила может просто начать с копирования непосредственного сопоставления смежности в сопоставление соединения, а затем итеративно расширять наборы до тех пор, пока одна итерация не перестанет расширять какой-либо набор.

Например, пример грубой силы Python 2.6:

import copy

def transitive_closure(immediate_neighbors):
  result = copy.deepcopy(immediate_neighbors)
  changes = True
  while changes:
    changes = False
    for node in result:
      newset = set(result[node])
      for neighbor in result[node]:
        newset.update(result[neighbor])
      if newset != result[node]:
        changes = True
        result[node] = newset
  return result

immediate = {0:[1,2], 1:[0], 2:[0], 3:[4], 4:[3]}
connections = transitive_closure(immediate)
for node in sorted(connections):
  print node, sorted(connections[node])

печатает:

0 [0, 1, 2]
1 [0, 1, 2]
2 [0, 1, 2]
3 [3, 4]
4 [3, 4]

Имея под рукой словарь connections, все, что нам нужно сделать, это проверить каждую комбинацию узлов k (например, в Python 2.6 или выше itertools.combinations(range(N), k) дает нам эти комбинации): это будет клика, если это подмножество (не обязательно правильное подмножество, конечно) набора элементов, связанных с любым из его элементов.

Так, например, приведенный выше код может продолжаться, чтобы показать все 2 клика:

import itertools
cliques = set()
for somenodes in itertools.combinations(range(5), 2):
  if set(somenodes) <= connections[somenodes[0]]:
    cliques.add(somenodes)
print '%d cliques:' % len(cliques)
for c in sorted(cliques): print ' ', c

который печатает с данными, использованными в предыдущем примере:

4 cliques:
  (0, 1)
  (0, 2)
  (1, 2)
  (3, 4)

Для подходов, не использующих грубую силу, я рекомендую снова изучить исходный код networkx, на который я указывал ранее.

person Alex Martelli    schedule 01.01.2010
comment
Большое спасибо Алекс. Хотя я не знаю Python. Я попытаюсь сделать это на C/C++ или Java. Есть идеи? - person Cristo; 01.01.2010
comment
@Cristo, должен быть точно такой же алгоритм - например, в C++ используйте std::set, где в приведенном выше коде Python я использую set, используйте std::map для представления сопоставлений вместо Python dicts, выполняйте комбинации, например. ж. код из codeguru.com/cpp/cpp/algorithms/combinations /article.php/c5117 и т. д. В конце концов, Python — это исполняемый псевдокод, поэтому нетрудно понять приведенный выше псевдокод и перевести его на C++!-) Задавайте конкретные вопросы, если у вас есть проблемы с пониманием любой из приведенных выше псевдокодов, конечно. - person Alex Martelli; 01.01.2010
comment
Большое спасибо Алекс. Если у меня возникнут проблемы с пониманием, я спрошу конкретно как можно скорее. Ваше здоровье. ;) - person Cristo; 01.01.2010

Хорошо, пронумеруйте вершины 1 ... n и преобразуйте граф в логическую матрицу смежности - 1 в (i, j), что означает, что i и j связаны. В неориентированном графе матрица должна быть симметричной. Теперь ваша задача сводится к поиску «подквадрата» размера k x k со всеми единицами. «Подквадрат» забавен тем, что строки и столбцы не обязательно должны быть рядом друг с другом. Чтобы получить подквадрат, вы начинаете с n строк, n столбцов, удаляете (n-k) строк и столбцов — и вуаля! ты получил это.

Теперь каждый уникальный подквадрат из всех единиц будет соответствовать клике. Чтобы проверить уникальность, представьте подквадрат в виде неизменного кортежа ((i1,j1), (i2, j2) ... (ik,jk)) (нотация Python).

В Python вы можете добавлять кортежи в неупорядоченный набор и спрашивать набор, содержит ли он уже искомый элемент.

person Hamish Grubijan    schedule 01.01.2010
comment
Это имеет смысл. Не могли бы вы опубликовать мне код для sub-square? - person Cristo; 01.01.2010
comment
Извини, Кристо, ты просишь слишком много. - person Hamish Grubijan; 01.01.2010
comment
Редактировать: что вы имеете в виду под квадратом? Родной язык: не английский - person Cristo; 01.01.2010
comment
Подквадрат — это набор строк и столбцов матрицы смежности. как указано в ответе, они не должны быть соседними. - person R. Martinho Fernandes; 01.01.2010
comment
Хорошо, большое спасибо, ребята. Еще один: как я могу создать другой подквадрат из матрицы? - person Cristo; 01.01.2010