Class: Tangle::Graph

Inherits:
Object
  • Object
show all
Includes:
GraphPrivate, GraphProtected, Mixin::Initialize
Defined in:
lib/tangle/graph.rb

Overview

Base class for all kinds of graphs

Direct Known Subclasses

Directed::Graph, Simple::Graph

Constant Summary collapse

Edge =
Tangle::Edge
DEFAULT_MIXINS =
[Tangle::Mixin::Connectedness].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mixins: self.class::DEFAULT_MIXINS, **kwargs) ⇒ Graph

Initialize a new graph, optionally preloading it with vertices and edges

Graph.new() => Graph Graph.new(mixins: [MixinModule, …], …) => Graph

mixins is an array of modules that can be mixed into the various classes that makes up a graph. Initialization of a Graph, Vertex or Edge looks for submodules in each mixin, with the same name and extends any created object. Defaults to [Tangle::Mixin::Connectedness].

Any subclass of Graph should also subclass Edge to manage its unique constraints.



52
53
54
55
56
# File 'lib/tangle/graph.rb', line 52

def initialize(mixins: self.class::DEFAULT_MIXINS, **kwargs)
  initialize_vertices
  initialize_edges
  initialize_mixins(mixins, **kwargs)
end

Instance Attribute Details

#mixinsObject (readonly)

Returns the value of attribute mixins.



133
134
135
# File 'lib/tangle/graph.rb', line 133

def mixins
  @mixins
end

Class Method Details

.[](vertices, edges = {}, **kwargs) ⇒ Object

Initialize a new graph, preloading it with vertices and edges

Graph[vertices] => Graph Graph[vertices, edges) => Graph

When vertices is a hash, it contains initialization kwargs as values and vertex names as keys. When vertices is an array of initialization kwargs, the vertices will be be anonymous.

edges can contain an array of exactly two, either names of vertices or vertices.

Any kwarg supported by Graph.new is also allowed.



32
33
34
35
36
37
# File 'lib/tangle/graph.rb', line 32

def self.[](vertices, edges = {}, **kwargs)
  graph = new(**kwargs)
  graph.add_vertices(vertices)
  edges.each { |from, to| graph.add_edge(from, to) }
  graph
end

Instance Method Details

#add_edge(*vertices, **kvargs) ⇒ Object

Add a new edge to the graph

add_edge(vtx1, vtx2, …) => Edge



75
76
77
78
# File 'lib/tangle/graph.rb', line 75

def add_edge(*vertices, **kvargs)
  vertices = vertices.map { |v| get_vertex(v) }
  insert_edge(self.class::Edge.new(*vertices, graph: self, **kvargs))
end

#add_vertex(**kvargs) ⇒ Object

Add a new vertex to the graph

add_vertex(…) => Vertex

Optional named arguments:

name: unique name or label for vertex


99
100
101
# File 'lib/tangle/graph.rb', line 99

def add_vertex(**kvargs)
  insert_vertex(Vertex.new(graph: self, **kvargs))
end

#add_vertices(vertices) ⇒ Object



103
104
105
106
107
108
109
110
# File 'lib/tangle/graph.rb', line 103

def add_vertices(vertices)
  case vertices
  when Hash
    vertices.each { |name, kwargs| add_vertex(name: name, **kwargs) }
  else
    vertices.each { |kwargs| add_vertex(**kwargs) }
  end
end

#edges(vertex: nil, &selector) ⇒ Object

Get all edges.

edges => Array



62
63
64
65
66
67
68
69
# File 'lib/tangle/graph.rb', line 62

def edges(vertex: nil, &selector)
  edges = vertex.nil? ? @edges : @edges_by_vertex[vertex]
  if block_given?
    edges.select(&selector)
  else
    edges.to_a
  end
end

#get_vertex(name_or_vertex) ⇒ Object



112
113
114
115
116
117
118
119
120
# File 'lib/tangle/graph.rb', line 112

def get_vertex(name_or_vertex)
  case name_or_vertex
  when Vertex
    name_or_vertex
  else
    @vertices_by_name[name_or_vertex] ||
      @vertices_by_id.fetch(name_or_vertex)
  end
end

#subgraph(&selector) ⇒ Object

Return a subgraph, optionally filtered by a vertex selector block

subgraph => Graph subgraph { |vertex| … } => Graph

Unless a selector is provided, the subgraph contains the entire graph.



129
130
131
# File 'lib/tangle/graph.rb', line 129

def subgraph(&selector)
  clone.with_vertices(vertices(&selector)).with_edges(edges)
end

#to_sObject Also known as: inspect



135
136
137
# File 'lib/tangle/graph.rb', line 135

def to_s
  "#<#{self.class}: #{vertices.count} vertices, #{edges.count} edges>"
end

#verticesObject

Get all vertices.

vertices => Array



84
85
86
87
88
89
90
# File 'lib/tangle/graph.rb', line 84

def vertices
  if block_given?
    @vertices_by_id.select { |_, vertex| yield(vertex) }
  else
    @vertices_by_id
  end.values
end