lib/yargraph.rb
# Run depth first search, returning an array of Hamiltonian paths.
# Or, if a block is given, yield each Hamiltonian path that comes
# along (in no defined order), and don't return the array (to potentially
# save RAM).
#
# The operational limit is used to make sure this algorithm doesn't
# get out of hand - only this many 'operations' are used when traversing
# the graph, as in #hamiltonian_paths_brute_force. When nil, there is no operational
# limit
Run depth first search, returning an array of Hamiltonian paths.
Or, if a block is given, yield each Hamiltonian path that comes
along (in no defined order), and don't return the array (to potentially
save RAM).

The operational limit is used to make sure this algorithm doesn't
get out of hand - only this many 'operations' are used when traversing
the graph, as in #hamiltonian_paths_brute_force. When nil, there is no operational
limit
Run depth first search returning an array of Hamiltonian paths . Or if a block is given yield each Hamiltonian path that comes along ( in no defined order ) and don ' t return the array ( to potentially save RAM ) . The operational limit is used to make sure this algorithm doesn ' t get out of hand - only this many ' operations ' are used when traversing the graph as in #hamiltonian_paths_brute_force . When nil there is no operational limit
def hamiltonian_cycles_brute_force(operational_limit=nil)
      stack = DS::Stack.new
      return [] if @vertices.empty?
      origin_vertex = @vertices.to_a[0]
      hamiltonians = []
      num_operations = 0
      path = Path.new
      path << origin_vertex
      stack.push path
      while path = stack.pop
        last_vertex = path[path.length-1]
        if last_vertex == origin_vertex and path.length > 1
          if path.length == vertices.length + 1
            hpath = path.copy[0...(path.length-1)]
            if block_given?
              yield hpath
            else
              hamiltonians << hpath
            end
          else
          end
        elsif path.find_index(last_vertex) != path.length - 1
        else
          neighbours(last_vertex).each do |neighbour|
            unless operational_limit.nil?
              num_operations += 1
              if num_operations > operational_limit
                raise OperationalLimitReachedException
              end
            end
            new_path = Path.new(path.copy+[neighbour])
            stack.push new_path
          end
        end
      end
      return hamiltonians
    end
def hamiltonian_cycles_brute_force ( operational_limit = nil ) stack = DS :: Stack . new return [ ] if @vertices . empty? origin_vertex = @vertices . to_a [ 0 ] hamiltonians = [ ] num_operations = 0 path = Path . new path << origin_vertex stack . push path while path = stack . pop last_vertex = path [ path . length - 1 ] if last_vertex == origin_vertex and path . length > 1 if path . length == vertices . length + 1 hpath = path . copy [ 0 ... ( path . length - 1 ) ] if block_given? yield hpath else hamiltonians << hpath end else end elsif path . find_index ( last_vertex ) != path . length - 1 else neighbours ( last_vertex ) . each do | neighbour | unless operational_limit . nil? num_operations += 1 if num_operations > operational_limit raise OperationalLimitReachedException end end new_path = Path . new ( path . copy + [ neighbour ] ) stack . push new_path end end end return hamiltonians end
Run depth first search, returning an array of Hamiltonian paths.
Run depth first search returning an array of Hamiltonian paths .
# Cycle of some sort detected. Is it Hamiltonian? # Found a Hamiltonian path. Yield or save it for later # non-Hamiltonian path found. Ignore # Found a loop, go no further # No loop, just another regular thing.
operational_limit
<not_specific>