class ChaosDetector::GraphTheory::Graph

Attributes

edges[R]
root_node[R]

Public Class Methods

new(root_node:, nodes: nil, edges: nil) click to toggle source
# File lib/chaos_detector/graph_theory/graph.rb, line 16
def initialize(root_node:, nodes: nil, edges: nil)
  # raise ArgumentError, 'Root node required.' unless root_node

  @root_node = root_node
  @nodes = nodes || []
  @edges = edges || []
end

Public Instance Methods

==(other) click to toggle source
# File lib/chaos_detector/graph_theory/graph.rb, line 122
def ==(other)
  root_node == other.root_node &&
    nodes == other.nodes &&
    edges == other.edges
end
children(node) click to toggle source
# File lib/chaos_detector/graph_theory/graph.rb, line 88
def children(node)
  @edges.select { |e| e.src_node == node }.map(&:dep_node).inject do |child_nodes|
    puts "Found children for #{node.label}: #{child_nodes}"
  end
end
edge_count() click to toggle source
# File lib/chaos_detector/graph_theory/graph.rb, line 12
def edge_count
  @edges.length
end
edge_for_nodes(src_node, dep_node) click to toggle source
# File lib/chaos_detector/graph_theory/graph.rb, line 111
def edge_for_nodes(src_node, dep_node)
  # puts "EEEDGE_FOR_NODES::: #{src_node.to_s} / #{dep_node.class.to_s}"
  edge = edges.find do |e|
    e.src_node == src_node && e.dep_node == dep_node
  end

  edges << edge = ChaosDetector::GraphTheory::Edge.new(src_node, dep_node) if edge.nil?

  edge
end
edges_for_node(node) click to toggle source
# File lib/chaos_detector/graph_theory/graph.rb, line 105
def edges_for_node(node)
  edges.filter do |e|
    e.src_node == node || e.dep_node == node
  end
end
inspect() click to toggle source
# File lib/chaos_detector/graph_theory/graph.rb, line 132
def inspect
  buffy = []
  buffy << "\tNodes (#{nodes.length})"
  buffy.concat(nodes.map { |n| "\t\t#{n.title}"})

  # buffy << "Edges (#{@edges.length})"
  # buffy.concat(@edges.map {|e|"\t\t#{e.to_s}"})

  buffy.join("\n")
end
node_count() click to toggle source
# File lib/chaos_detector/graph_theory/graph.rb, line 8
def node_count
  @nodes.length
end
node_for(obj) { || ... } click to toggle source
# File lib/chaos_detector/graph_theory/graph.rb, line 94
def node_for(obj)
  raise ArgumentError, '#node_for requires obj' unless obj

  node_n = @nodes.index(obj)
  if node_n
    @nodes[node_n]
  else
    yield.tap { |n| @nodes << n }
  end
end
nodes(include_root: true) click to toggle source
# File lib/chaos_detector/graph_theory/graph.rb, line 24
def nodes(include_root: true)
  include_root ? @nodes : @nodes.reject(&:root?)
end
to_s() click to toggle source
# File lib/chaos_detector/graph_theory/graph.rb, line 128
def to_s
  format('Nodes: %d, Edges: %d', @nodes.length, @edges.length)
end
traversal() click to toggle source
# File lib/chaos_detector/graph_theory/graph.rb, line 56
def traversal
  to_enum(:traverse).map(&:itself) # {|n| puts "TNode:#{n}"; n.label}
end
traverse(origin_node: nil) { |node| ... } click to toggle source
Depth-first traversal

Consumes each edge as it used

# File lib/chaos_detector/graph_theory/graph.rb, line 75
def traverse(origin_node: nil)
  raise ArgumentError, 'traverse requires block' unless block_given?
  edges = @edges
  nodes_to_visit = [origin_node || root_node]
  while nodes_to_visit.length > 0
    node = nodes_to_visit.shift
    yield(node)
    out_edges, edges = edges.partition { |e| e.src_node == node }
    child_nodes = out_edges.map(&:dep_node)
    nodes_to_visit = child_nodes + nodes_to_visit
  end
end
whack_node(node) click to toggle source

Remove node and src and dep edges:

# File lib/chaos_detector/graph_theory/graph.rb, line 51
def whack_node(node)
  @edges.delete_if { |e| e.src_node == node || e.dep_node == node }
  @nodes.delete(node)
end