Вычисление чисел "Кевин Бэкон"

Я играл с некоторыми вещами и придумал идею попытаться выяснить Kevin Bacon. У меня есть данные для сайта, для которого мы можем рассматривать социальную сеть. Пусть притворяется, что это Facebook (для упрощения обсуждения). У меня есть люди, и у меня есть список их друзей, поэтому у меня есть связи между ними. Как я могу рассчитать расстояние от одного человека к другому (в основном, номер Кевина Бэкона)?

Моя лучшая идея - Двунаправленный поиск с ограничением глубины (чтобы ограничить вычислительную сложность и избежать проблемы людей, которые просто могут" t подключен на графике), но я понимаю, что это довольно грубая сила.

Может быть, лучше сделать небольшие субграфы (скажем, что-то, что эквивалентно группам на Facebook), рассчитать кратчайшие расстояния между ними (возможно, раньше времени), а затем попытаться использовать THOSE, чтобы найти ссылку? В то время как для этого требуется предварительный расчет, он может обеспечить поиск по нескольким узлам (узлы могут быть группами вместо отдельных лиц, что делает график намного меньшим). Это все равно будет двунаправленный поиск.

Я мог бы также предварительно вычислить количество людей, к которым подключено отдельное лицо, сначала поиск узлов для "популярных" людей, так как они могли бы наилучшим образом подключиться к данному получателю. Я понимаю, что это будет компромисс скорости для возможного кратчайшего пути. Я бы подумал, что также хочу использовать поиск по глубине вместо поиска ширины в первый раз, который я планировал использовать в других случаях.

Может кто-нибудь подумать о более простом/более быстром способе сделать это? Я бы хотел найти самую короткую длину между двумя людьми, поэтому это не так просто, как всегда, с той же конечной точкой (например, в проблеме Кевина Бэкона).

Я понимаю, что есть такие проблемы, как я мог бы получить цепочки из 200 человек и т.д., но это может быть решено, что у меня есть предел для глубины, которую я хочу искать.

Ответ 1

Это стандартная кратчайшая проблема пути. Существует множество решений, в том числе алгоритм Дейкстры и Bellman-Ford. Вам может быть особенно интересно взглянуть на алгоритм A * и посмотреть, как он будет работать с функцией стоимости относительно обратного к любому конкретному node степень. Идея состояла бы в том, чтобы сначала посетить более популярные узлы (с более высокой степенью).

Ответ 2

Звучит как работа для алгоритм Дейкстры.

ЭД: Эх, я не должен был так быстро спустить курок. Dijkstra (и Bellman-Ford) сводится к поиску в ширину, когда вес равен 1, поэтому это не слишком полезно. О, хорошо.

алгоритм A *, упомянутый tvanfosson, может быть идеальным для этого. Идея состоит в том, что вместо поиска и рекурсии в любом порядке элементы находятся на каждом уровне дерева (внедренном в начало или конец), вы используете некоторую эвристику, чтобы определить, какой элемент вы собираетесь попробовать первым. В вашем случае хорошая ставка будет, вероятно, степенью node (количество "друзей" ), но вы, возможно, захотите использовать количество людей в пределах некоторого произвольного количества градусов данного человека (т.е. Парень у которого есть три друга, у каждого из которых есть 100 друзей, вероятно, будет лучше node, чем тот, у кого есть 20 друзей в клике, которая избегает посторонних). Там всевозможные другие вещи, которые вы могли бы использовать в качестве эвристики (друзья получают 2 балла, друзья друзей получают 1 очко, что угодно, эксперимент).

Объедините это с пределом глубины (отрезанным после 6 градусов разделения или любым другим), и вы можете значительно улучшить свой средний случай (худший вариант по-прежнему совпадает с базовым BFS).

Ответ 3

выполните поиск по ширине в обоих направлениях (с каждой конечной точки) и остановитесь, когда у вас есть соединение или достигнете предела глубины

Ответ 4

Это может быть лучше всего Floyd-Warshall все пары кратчайшего расстояния.