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_mixins(mixins, **kwargs)
  initialize_vertices
  initialize_edges
end

Instance Attribute Details

#mixinsObject (readonly)

Returns the value of attribute mixins.



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

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



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

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


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

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

#add_vertices(vertices) ⇒ Object



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

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(&selector) ⇒ Object

Get all edges.

edges => Array



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

def edges(&selector)
  if block_given?
    @edges.select(&selector)
  else
    @edges.to_a
  end
end

#get_vertex(name_or_vertex) ⇒ Object



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

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.



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

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

#verticesObject

Get all vertices.

vertices => Array



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

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