mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
[DOC]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43340 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
d51f0dde89
commit
6909b824ea
1 changed files with 91 additions and 9 deletions
100
lib/tsort.rb
100
lib/tsort.rb
|
@ -123,20 +123,33 @@ module TSort
|
|||
class Cyclic < StandardError
|
||||
end
|
||||
|
||||
#
|
||||
# Returns a topologically sorted array of nodes.
|
||||
# The array is sorted from children to parents, i.e.
|
||||
# the first element has no child and the last node has no parent.
|
||||
#
|
||||
# If there is a cycle, TSort::Cyclic is raised.
|
||||
#
|
||||
# class G
|
||||
# include TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# p graph.tsort #=> [4, 2, 3, 1]
|
||||
#
|
||||
# graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
|
||||
# p graph.tsort # raises TSort::Cyclic
|
||||
#
|
||||
def tsort
|
||||
result = []
|
||||
tsort_each {|element| result << element}
|
||||
result
|
||||
end
|
||||
|
||||
#
|
||||
# The iterator version of the #tsort method.
|
||||
# <tt><em>obj</em>.tsort_each</tt> is similar to <tt><em>obj</em>.tsort.each</tt>, but
|
||||
# modification of _obj_ during the iteration may lead to unexpected results.
|
||||
|
@ -144,6 +157,22 @@ module TSort
|
|||
# #tsort_each returns +nil+.
|
||||
# If there is a cycle, TSort::Cyclic is raised.
|
||||
#
|
||||
# class G
|
||||
# include TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# graph.tsort_each {|n| p n }
|
||||
# #=> 4
|
||||
# # 2
|
||||
# # 3
|
||||
# # 1
|
||||
#
|
||||
def tsort_each # :yields: node
|
||||
each_strongly_connected_component {|component|
|
||||
if component.size == 1
|
||||
|
@ -154,26 +183,60 @@ module TSort
|
|||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Returns strongly connected components as an array of arrays of nodes.
|
||||
# The array is sorted from children to parents.
|
||||
# Each elements of the array represents a strongly connected component.
|
||||
#
|
||||
# class G
|
||||
# include TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# p graph.strongly_connected_components #=> [[4], [2], [3], [1]]
|
||||
#
|
||||
# graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
|
||||
# p graph.strongly_connected_components #=> [[4], [2, 3], [1]]
|
||||
#
|
||||
def strongly_connected_components
|
||||
result = []
|
||||
each_strongly_connected_component {|component| result << component}
|
||||
result
|
||||
end
|
||||
|
||||
#
|
||||
# The iterator version of the #strongly_connected_components method.
|
||||
# <tt><em>obj</em>.each_strongly_connected_component</tt> is similar to
|
||||
# <tt><em>obj</em>.strongly_connected_components.each</tt>, but
|
||||
# modification of _obj_ during the iteration may lead to unexpected results.
|
||||
#
|
||||
#
|
||||
# #each_strongly_connected_component returns +nil+.
|
||||
#
|
||||
# class G
|
||||
# include TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# graph.each_strongly_connected_component {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2]
|
||||
# # [3]
|
||||
# # [1]
|
||||
#
|
||||
# graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
|
||||
# graph.each_strongly_connected_component {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2, 3]
|
||||
# # [1]
|
||||
#
|
||||
def each_strongly_connected_component # :yields: nodes
|
||||
id_map = {}
|
||||
stack = []
|
||||
|
@ -187,7 +250,6 @@ module TSort
|
|||
nil
|
||||
end
|
||||
|
||||
#
|
||||
# Iterates over strongly connected component in the subgraph reachable from
|
||||
# _node_.
|
||||
#
|
||||
|
@ -195,6 +257,25 @@ module TSort
|
|||
#
|
||||
# #each_strongly_connected_component_from doesn't call #tsort_each_node.
|
||||
#
|
||||
# class G
|
||||
# include TSort
|
||||
# def initialize(g)
|
||||
# @g = g
|
||||
# end
|
||||
# def tsort_each_child(n, &b) @g[n].each(&b) end
|
||||
# def tsort_each_node(&b) @g.each_key(&b) end
|
||||
# end
|
||||
#
|
||||
# graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
|
||||
# graph.each_strongly_connected_component_from(2) {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2]
|
||||
#
|
||||
# graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
|
||||
# graph.each_strongly_connected_component_from(2) {|scc| p scc }
|
||||
# #=> [4]
|
||||
# # [2, 3]
|
||||
#
|
||||
def each_strongly_connected_component_from(node, id_map={}, stack=[], &block) # :yields: nodes
|
||||
TSort.each_strongly_connected_component_from(node, method(:tsort_each_child), id_map, stack, &block)
|
||||
end
|
||||
|
@ -214,8 +295,11 @@ module TSort
|
|||
# graph = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
|
||||
# each_child = lambda {|n, &b| graph[n].each(&b) }
|
||||
# TSort.each_strongly_connected_component_from(1, each_child) {|scc|
|
||||
# p scc #=> [4], [2, 3], [1]
|
||||
# p scc
|
||||
# }
|
||||
# #=> [4]
|
||||
# # [2, 3]
|
||||
# # [1]
|
||||
#
|
||||
def TSort.each_strongly_connected_component_from(node, each_child, id_map={}, stack=[]) # :yields: nodes
|
||||
minimum_id = node_id = id_map[node] = id_map.size
|
||||
|
@ -244,7 +328,6 @@ module TSort
|
|||
minimum_id
|
||||
end
|
||||
|
||||
#
|
||||
# Should be implemented by a extended class.
|
||||
#
|
||||
# #tsort_each_node is used to iterate for all nodes over a graph.
|
||||
|
@ -253,7 +336,6 @@ module TSort
|
|||
raise NotImplementedError.new
|
||||
end
|
||||
|
||||
#
|
||||
# Should be implemented by a extended class.
|
||||
#
|
||||
# #tsort_each_child is used to iterate for child nodes of _node_.
|
||||
|
|
Loading…
Reference in a new issue