Найти и отсортировать топологически все деревья, включая данную группу узлов, из графа зависимостей - PullRequest
0 голосов
/ 04 ноября 2019

Предположим, у меня есть следующий график зависимостей (A => [B] означает, что A зависит / требует, чтобы B обновил свое значение, прежде чем значение A может быть обновлено). Я использую хэш Ruby и модуль TSort для топологических операций.

graph = {
  a: OpenStruct.new(dependencies: []),
  b: OpenStruct.new(dependencies: [:a]),
  c: OpenStruct.new(dependencies: [:b]),
  d: OpenStruct.new(dependencies: []),
  e: OpenStruct.new(dependencies: [:d]),
  f: OpenStruct.new(dependencies: []),
}
# Which gives 3 dependency trees
:c => :b => :a, :e => :d, :f 

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

Вот несколько примеров (в отношении вывода я могу справиться с любым массивом графиков TSorted). или просто упрощенная версия, мне все равно, например 3) , но массив сортированных графиков проще определить, как вы увидите ниже.

desired_function(:a) == [:c,:b,:a] # or [[:c,:b,:a]]
desired_function(:b) == [:c,:b,:a] # or [[:c,:b,:a]]
desired_function(:c) == [:c,:b,:a] # or [[:c,:b,:a]]
desired_function(:c,:d) == [:c,:b,:a,:d,:e] # or [:d,:e,:c,:b,:a] or [[:d,:e], [:c,:b,:a]], or [[:c,:b,:a], [:d,:e]]
desired_function(:f) == [:f] # or [[:f]]

IЯ пытался реализовать алгоритм TSort, но я не уверен, как я могу указать, что мне также нужно включить родителей узла, который я запрашиваю tsort из

Моя текущая реализация (на данной graphвыше)

def incomplete_function_to_get_tsorted_subgraphs(graph, node_names) 
  each_node = lambda { |&b| graph.slice(*node_names).each_key(&b) }
  each_child = lambda do |node_name, &b|
    graph[node_name].dependencies.each(&b)
  end
  TSort.tsort(each_node, each_child)
end

Это неполно, поскольку в настоящее время он будет получать зависимости только до запрошенных узлов incomplete_function_to_get_tsorted_subgraphs(graph, :b) # returns [:a, :b] instead of [:a,:b,:c] Если я удаляю slice, то он просто становится цортом на полном графе, который не являетсячто я хочу (и мне нужно как-то сократить это)

Спецификации для того, чего я хочу достичь (при условии, что мы возвращаем массивы из отсортированных графов зависимостей)

expect(complete_function_to_get_tsorted_subgraphs(:b)).to include([:a,:b,:c])

expect(complete_function_to_get_tsorted_subgraphs(:b,:d).to 
  include([:a,:b,:c], [:d, :e])

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

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