![show/hide quicksearch [+]](../images/find.png)
The iterator version of the Gem::TSort.strongly_connected_components method.
The graph is represented by each_node and each_child. each_node should have call method which yields for each node in the graph. each_child should have call method which takes a node argument and yields for each child node.
g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]} each_node = lambda {|&b| g.each_key(&b) } each_child = lambda {|n, &b| g[n].each(&b) } Gem::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc } #=> [4] # [2] # [3] # [1] g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]} each_node = lambda {|&b| g.each_key(&b) } each_child = lambda {|n, &b| g[n].each(&b) } Gem::TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc } #=> [4] # [2, 3] # [1]
 
               # File rubygems/tsort/lib/tsort.rb, line 343
def TSort.each_strongly_connected_component(each_node, each_child) # :yields: nodes
  return to_enum(__method__, each_node, each_child) unless block_given?
  id_map = {}
  stack = []
  each_node.call {|node|
    unless id_map.include? node
      Gem::TSort.each_strongly_connected_component_from(node, each_child, id_map, stack) {|c|
        yield c
      }
    end
  }
  nil
end
             
            Iterates over strongly connected components in a graph. The graph is represented by node and each_child.
node is the first node. each_child should have call method which takes a node argument and yields for each child node.
Return value is unspecified.
#Gem::TSort.each_strongly_connected_component_from is a class method and it doesn't need a class to represent a graph which includes Gem::TSort.
graph = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]} each_child = lambda {|n, &b| graph[n].each(&b) } Gem::TSort.each_strongly_connected_component_from(1, each_child) {|scc| p scc } #=> [4] # [2, 3] # [1]
 
               # File rubygems/tsort/lib/tsort.rb, line 409
def TSort.each_strongly_connected_component_from(node, each_child, id_map={}, stack=[]) # :yields: nodes
  return to_enum(__method__, node, each_child, id_map, stack) unless block_given?
  minimum_id = node_id = id_map[node] = id_map.size
  stack_length = stack.length
  stack << node
  each_child.call(node) {|child|
    if id_map.include? child
      child_id = id_map[child]
      minimum_id = child_id if child_id && child_id < minimum_id
    else
      sub_minimum_id =
        Gem::TSort.each_strongly_connected_component_from(child, each_child, id_map, stack) {|c|
          yield c
        }
      minimum_id = sub_minimum_id if sub_minimum_id < minimum_id
    end
  }
  if node_id == minimum_id
    component = stack.slice!(stack_length .. -1)
    component.each {|n| id_map[n] = nil}
    yield component
  end
  minimum_id
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.
The graph is represented by each_node and each_child. each_node should have call method which yields for each node in the graph. each_child should have call method which takes a node argument and yields for each child node.
g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]} each_node = lambda {|&b| g.each_key(&b) } each_child = lambda {|n, &b| g[n].each(&b) } p Gem::TSort.strongly_connected_components(each_node, each_child) #=> [[4], [2], [3], [1]] g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]} each_node = lambda {|&b| g.each_key(&b) } each_child = lambda {|n, &b| g[n].each(&b) } p Gem::TSort.strongly_connected_components(each_node, each_child) #=> [[4], [2, 3], [1]]
 
               # File rubygems/tsort/lib/tsort.rb, line 281
def TSort.strongly_connected_components(each_node, each_child)
  Gem::TSort.each_strongly_connected_component(each_node, each_child).to_a
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.
The graph is represented by each_node and each_child. each_node should have call method which yields for each node in the graph. each_child should have call method which takes a node argument and yields for each child node.
If there is a cycle, Gem::TSort::Cyclic is raised.
g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]} each_node = lambda {|&b| g.each_key(&b) } each_child = lambda {|n, &b| g[n].each(&b) } p Gem::TSort.tsort(each_node, each_child) #=> [4, 2, 3, 1] g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]} each_node = lambda {|&b| g.each_key(&b) } each_child = lambda {|n, &b| g[n].each(&b) } p Gem::TSort.tsort(each_node, each_child) # raises Gem::TSort::Cyclic
 
               # File rubygems/tsort/lib/tsort.rb, line 176
def TSort.tsort(each_node, each_child)
  Gem::TSort.tsort_each(each_node, each_child).to_a
end
             
            The iterator version of the Gem::TSort.tsort method.
The graph is represented by each_node and each_child. each_node should have call method which yields for each node in the graph. each_child should have call method which takes a node argument and yields for each child node.
g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]} each_node = lambda {|&b| g.each_key(&b) } each_child = lambda {|n, &b| g[n].each(&b) } Gem::TSort.tsort_each(each_node, each_child) {|n| p n } #=> 4 # 2 # 3 # 1
 
               # File rubygems/tsort/lib/tsort.rb, line 224
def TSort.tsort_each(each_node, each_child) # :yields: node
  return to_enum(__method__, each_node, each_child) unless block_given?
  Gem::TSort.each_strongly_connected_component(each_node, each_child) {|component|
    if component.size == 1
      yield component.first
    else
      raise Cyclic.new("topological sort failed: #{component.inspect}")
    end
  }
end
             
            The iterator version of the strongly_connected_components method. obj.each_strongly_connected_component is similar to obj.strongly_connected_components.each, but modification of obj during the iteration may lead to unexpected results.
each_strongly_connected_component returns nil.
class G include Gem::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]
 
               # File rubygems/tsort/lib/tsort.rb, line 314
def each_strongly_connected_component(&block) # :yields: nodes
  each_node = method(:tsort_each_node)
  each_child = method(:tsort_each_child)
  Gem::TSort.each_strongly_connected_component(each_node, each_child, &block)
end
             
            Iterates over strongly connected component in the subgraph reachable from node.
Return value is unspecified.
each_strongly_connected_component_from doesn't call tsort_each_node.
class G include Gem::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]
 
               # File rubygems/tsort/lib/tsort.rb, line 384
def each_strongly_connected_component_from(node, id_map={}, stack=[], &block) # :yields: nodes
  Gem::TSort.each_strongly_connected_component_from(node, method(:tsort_each_child), id_map, stack, &block)
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 Gem::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]]
 
               # File rubygems/tsort/lib/tsort.rb, line 255
def strongly_connected_components
  each_node = method(:tsort_each_node)
  each_child = method(:tsort_each_child)
  Gem::TSort.strongly_connected_components(each_node, each_child)
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, Gem::TSort::Cyclic is raised.
class G include Gem::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 Gem::TSort::Cyclic
 
               # File rubygems/tsort/lib/tsort.rb, line 150
def tsort
  each_node = method(:tsort_each_node)
  each_child = method(:tsort_each_child)
  Gem::TSort.tsort(each_node, each_child)
end
             
            The iterator version of the tsort method. obj.tsort_each is similar to obj.tsort.each, but modification of obj during the iteration may lead to unexpected results.
tsort_each returns nil. If there is a cycle, Gem::TSort::Cyclic is raised.
class G include Gem::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
 
               # File rubygems/tsort/lib/tsort.rb, line 203
def tsort_each(&block) # :yields: node
  each_node = method(:tsort_each_node)
  each_child = method(:tsort_each_child)
  Gem::TSort.tsort_each(each_node, each_child, &block)
end
             
            Should be implemented by a extended class.
tsort_each_child is used to iterate for child nodes of node.
 
               # File rubygems/tsort/lib/tsort.rb, line 450
def tsort_each_child(node) # :yields: child
  raise NotImplementedError.new
end
             
            Should be implemented by a extended class.
tsort_each_node is used to iterate for all nodes over a graph.
 
               # File rubygems/tsort/lib/tsort.rb, line 442
def tsort_each_node # :yields: node
  raise NotImplementedError.new
end