Ранее я показал вам, как настроить Neo4j для работы с Ruby и как найти рекомендуемых друзей в социальной сети. Как насчет того, чтобы узнать, как вы подключены к кому-то за пределами сети друзей? Вы помните концепцию шести степеней разделения ? Нет, как насчет шести градусов Кевина Бэкона ?
Рекламный ролик кредитной карты объясняет, как это работает:
Актер Кевин Бэкон хочет выписать чек, чтобы купить книгу, но клерк спрашивает его удостоверение личности, которого у него нет. Он уходит и возвращается с группой людей, затем говорит клерку: «Хорошо, я был в фильме с дополнительной, Юнис, чей парикмахер Уэйн посещал воскресную школу с отцом О’Ниллом, который играет в ракетбол с доктором Санджай, который недавно удалил приложение Кима, который бросил тебя на втором курсе. Итак, вы видите, мы практически братья.
Возможно, вы не голливудский актер, но если вы использовали сайт социальной сети Linked In, вы увидели эту функцию в их окне «Как вы подключились». Итак, как мы можем сделать это с Ruby и Neo4j?
require 'rubygems'
require 'neography'
@neo = Neography::Rest.new
def create_person(name)
@neo.create_node("name" => name)
end
def make_mutual_friends(node1, node2)
@neo.create_relationship("friends", node1, node2)
@neo.create_relationship("friends", node2, node1)
end
def degrees_of_separation(start_node, destination_node)
paths = @neo.get_paths(start_node,
destination_node,
{"type"=> "friends", "direction" => "in"},
depth=4,
algorithm="allSimplePaths")
paths.each do |p|
p["names"] = p["nodes"].collect { |node|
@neo.get_node_properties(node, "name")["name"] }
end
end
johnathan = create_person('Johnathan')
mark = create_person('Mark')
phil = create_person('Phil')
mary = create_person('Mary')
make_mutual_friends(johnathan, mark)
make_mutual_friends(mark, phil)
make_mutual_friends(phil, mary)
make_mutual_friends(mark, mary)
degrees_of_separation(johnathan, mary).each do |path|
puts "#{(path["names"].size - 1 )} degrees: " + path["names"].join(' => friends => ')
end
# RESULT
# 3 degrees: Johnathan => friends => Mark => friends => Phil => friends => Mary
# 2 degrees: Johnathan => friends => Mark => friends => Mary
В этой функции мы даем Neo4j два узла и просим его выяснить, как они связаны через дружбу до глубины 4 (этого достаточно для нашего примера). Затем мы получаем свойство name этих узлов.
Мы использовали алгоритм «allSimplePaths», чтобы найти все способы их соединения, но если вы хотите выиграть раунд из шести степеней Кевина Бэкона, вам просто нужно найти кратчайший путь.
def degrees_of_separation(start_node, destination_node)
paths = @neo.get_paths(start_node,
destination_node,
{"type"=> "friends", "direction" => "in"},
depth=4,
algorithm="shortestPath")
paths.each do |p|
p["names"] = p["nodes"].collect { |node|
@neo.get_node_properties(node, "name")["name"] }
end
end
# RESULT
# 2 degrees: Johnathan => friends => Mark => friends => Mary
В Neo4j есть несколько графических алгоритмов , посмотрите на них в документации.
Это не слишком сложно, но если вы хотите немного сахара, то вы идете:
require 'rubygems'
require 'neography'
def create_person(name)
Neography::Node.create("name" => name)
end
johnathan = create_person('Johnathan')
mark = create_person('Mark')
phil = create_person('Phil')
mary = create_person('Mary')
johnathan.both(:friends) << mark
mark.both(:friends) << phil
phil.both(:friends) << mary
mark.both(:friends) << mary
johnathan.all_simple_paths_to(mary).incoming(:friends).depth(4).nodes.each
do |path|
puts "#{(path.size - 1 )} degrees: " + path.map{|n| n.name }.join(' => friends => ')
end
# RESULT
# 3 degrees: Johnathan => friends => Mark => friends => Phil => friends => Mary
# 2 degrees: Johnathan => friends => Mark => friends => Mary
Незначительное изменение последней части, чтобы получить только кратчайший путь:
johnathan.shortest_path_to(mary).incoming(:friends).depth(4).nodes.each
do |path|
puts "#{(path.size - 1 )} degrees: " + path.map{|n| n.name }.join(' => friends => ')
end
# RESULT
# 2 degrees: Johnathan => friends => Mark => friends => Mary
Вы можете взглянуть на различные функции пути в Neography, чтобы получить разные результаты.
Найдите меня и многих других поклонников графиков в Neo4j Google Group .
Источник: http://maxdemarzi.com/2012/01/05/how-youre-connected-to-kevin-bacon/
