Sha256: 3f167e6522e2abbef9dbc0611d8eeb46a72f77d3711cda5e2e24a3a2a83f24ec

Contents?: true

Size: 1.73 KB

Versions: 1

Compression:

Stored size: 1.73 KB

Contents

# topsort.rb

require 'rgl/graph_iterator'

module RGL

  # Topological Sort Iterator
  #
  # The topological sort algorithm creates a linear ordering of the vertices
  # such that if edge (u,v) appears in the graph, then u comes before v in
  # the ordering. The graph must be a directed acyclic graph (DAG).
  #
  # The iterator can also be applied to an undirected graph or to a directed graph
  # which contains a cycle. In this case, the Iterator does not reach all
  # vertices. The implementation of {Graph#acyclic?} uses this fact.
  #
  # @see Graph#topsort_iterator
  class TopsortIterator

    include GraphIterator

    def initialize(g)
      super(g)
      set_to_begin
    end

    def set_to_begin
      @waiting   = Array.new
      @inDegrees = Hash.new(0)

      graph.each_vertex do |u|
        @inDegrees[u] = 0 unless @inDegrees.has_key?(u)
        graph.each_adjacent(u) do |v|
          @inDegrees[v] += 1
        end
      end

      @inDegrees.each_pair do |v, indegree|
        @waiting.push(v) if indegree.zero?
      end
    end

    # @private
    def basic_forward
      u = @waiting.pop
      graph.each_adjacent(u) do |v|
        @inDegrees[v] -= 1
        @waiting.push(v) if @inDegrees[v].zero?
      end
      u
    end

    def at_beginning?
      true
    end

    def at_end?
      @waiting.empty?
    end

  end # class TopsortIterator

  module Graph

    # @return [TopsortIterator] for the graph.
    #
    def topsort_iterator
      TopsortIterator.new(self)
    end

    # Returns true if the graph contains no cycles. This is only meaningful
    # for directed graphs. Returns false for undirected graphs.
    #
    def acyclic?
      topsort_iterator.length == num_vertices
    end

  end # module Graph

end # module RGL

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
rgl-0.5.10 lib/rgl/topsort.rb