Предположим, у меня есть следующий график зависимостей (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, и вы можете помочь мне исправить мою функцию, или я должен пойти совершенно другим путем, чтобы получить то, что я хочу?