mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-17 20:01:32 +03:00
75 lines
1.6 KiB
Ruby
75 lines
1.6 KiB
Ruby
|
def print_graph(graph)
|
||
|
graph.each do |parent, children|
|
||
|
puts "#{parent} ->"
|
||
|
children.each do |child|
|
||
|
puts " #{child}"
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def check_graph!(graph)
|
||
|
graph.each do |parent, children|
|
||
|
children.each do |child|
|
||
|
if !graph.key?(child)
|
||
|
raise "Graph is missing an entry for #{child}"
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def depth_first_search_exclude_start(graph, start)
|
||
|
stack = [graph.fetch(start).to_a.reverse]
|
||
|
visited = Set.new
|
||
|
until stack.empty?
|
||
|
node = stack.last.pop
|
||
|
if node.nil?
|
||
|
stack.pop
|
||
|
next
|
||
|
end
|
||
|
next if visited.include?(node)
|
||
|
visited << node
|
||
|
stack << graph.fetch(node).to_a.reverse
|
||
|
yield node
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def transitive_closure(graph)
|
||
|
tc = {}
|
||
|
graph.each_key do |node|
|
||
|
tc[node] = enum_for(:depth_first_search_exclude_start, graph, node).to_a
|
||
|
end
|
||
|
tc
|
||
|
end
|
||
|
|
||
|
def restricted_transitive_closure(graph, allowed)
|
||
|
rtc = {}
|
||
|
graph.each_key do |node|
|
||
|
next if !allowed.include?(node)
|
||
|
reached_nodes = []
|
||
|
depth_first_search_exclude_start(graph, node) do |reached_node|
|
||
|
next if !allowed.include?(reached_node)
|
||
|
reached_nodes << reached_node
|
||
|
end
|
||
|
rtc[node] = reached_nodes
|
||
|
end
|
||
|
rtc
|
||
|
end
|
||
|
|
||
|
def transitive_reduction(graph)
|
||
|
tr = {}
|
||
|
graph.each do |start_node, nodes|
|
||
|
nodes_with_max_distance_1 = Set.new(nodes)
|
||
|
distance = 1
|
||
|
until nodes.empty?
|
||
|
nodes = Set.new nodes.flat_map &graph.method(:fetch)
|
||
|
nodes_with_max_distance_1 -= nodes
|
||
|
distance += 1
|
||
|
if distance > graph.size
|
||
|
raise "Cycle detected: this algorithm only works with DAGs."
|
||
|
end
|
||
|
end
|
||
|
tr[start_node] = nodes_with_max_distance_1.to_a
|
||
|
end
|
||
|
tr
|
||
|
end
|