tangle 0.8.2 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.5.0
5
- before_install: gem install bundler -v 1.16.0
data/lib/tangle/graph.rb DELETED
@@ -1,81 +0,0 @@
1
- require 'tangle/mixin'
2
- require 'tangle/mixin/connectedness'
3
- require 'tangle/edge'
4
- require 'tangle/graph_vertices'
5
- require 'tangle/graph_edges'
6
-
7
- module Tangle
8
- #
9
- # Base class for all kinds of graphs
10
- #
11
- class Graph
12
- include Tangle::GraphVertices
13
- include Tangle::GraphEdges
14
- include Tangle::Mixin::Initialize
15
- Edge = Tangle::Edge
16
- DEFAULT_MIXINS = Tangle::Mixin::Connectedness::MIXINS
17
-
18
- # Initialize a new graph, preloading it with vertices and edges
19
- #
20
- # Graph[+vertices+] => Graph
21
- # Graph[+vertices+, +edges+) => Graph
22
- #
23
- # When +vertices+ is a hash, it contains initialization kwargs as
24
- # values and vertex names as keys. When +vertices+ is an array of
25
- # initialization kwargs, the vertices will be be anonymous.
26
- #
27
- # +edges+ can contain an array of exactly two, either names of vertices
28
- # or vertices.
29
- #
30
- # Any kwarg supported by Graph.new is also allowed.
31
- #
32
- def self.[](vertices, edges = {}, **kwargs)
33
- graph = new(**kwargs)
34
- vertices.each { |vertex| graph.add_vertex(vertex) }
35
- edges.each { |from, to| graph.add_edge(from, to) }
36
- graph
37
- end
38
-
39
- # Initialize a new graph, optionally preloading it with vertices and edges
40
- #
41
- # Graph.new() => Graph
42
- # Graph.new(mixins: [MixinModule, ...], ...) => Graph
43
- #
44
- # +mixins+ is an array of modules that can be mixed into the various
45
- # classes that makes up a graph. Initialization of a Graph, Vertex or Edge
46
- # looks for submodules in each mixin, with the same name and extends
47
- # any created object. Defaults to [Tangle::Mixin::Connectedness].
48
- #
49
- # Any subclass of Graph should also subclass Edge to manage its unique
50
- # constraints.
51
- #
52
- def initialize(mixins: self.class::DEFAULT_MIXINS, **kwargs)
53
- initialize_vertices
54
- initialize_edges
55
- initialize_mixins(mixins: mixins, **kwargs)
56
- end
57
-
58
- # Return a subgraph, optionally filtered by a vertex selector block
59
- #
60
- # subgraph => Graph
61
- # subgraph { |vertex| ... } => Graph
62
- #
63
- # Unless a selector is provided, the subgraph contains the entire graph.
64
- #
65
- def subgraph(included = nil)
66
- included ||= vertices
67
- result = clone
68
- vertices.each do |vertex|
69
- result.remove_vertex(vertex) unless included.include?(vertex)
70
- next unless block_given?
71
- result.remove_vertex(vertex) unless yield(vertex)
72
- end
73
- result
74
- end
75
-
76
- def to_s
77
- "#<#{self.class}: #{vertices.count} vertices, #{edges.count} edges>"
78
- end
79
- alias inspect to_s
80
- end
81
- end
@@ -1,49 +0,0 @@
1
- require 'set'
2
-
3
- module Tangle
4
- # Edge related methods in a graph
5
- module GraphEdges
6
- # Get all edges.
7
- #
8
- # edges => Array
9
- #
10
- def edges(vertex = nil)
11
- return @edges if vertex.nil?
12
- @vertices.fetch(vertex)
13
- end
14
-
15
- # Add a new edge to the graph
16
- #
17
- # add_edge(vtx1, vtx2, ...) => Edge
18
- #
19
- def add_edge(*vertices, **kvargs)
20
- insert_edge(self.class::Edge.new(*vertices, mixins: @mixins, **kvargs))
21
- end
22
-
23
- # Remove an edge from the graph
24
- def remove_edge(edge)
25
- edge.each_vertex do |vertex|
26
- @vertices.fetch(vertex).delete(edge)
27
- end
28
- @edges.delete(edge)
29
- end
30
-
31
- protected
32
-
33
- # Insert a prepared edge into the graph
34
- #
35
- def insert_edge(edge)
36
- @edges << edge
37
- edge.each_vertex do |vertex|
38
- @vertices.fetch(vertex) << edge
39
- end
40
- edge
41
- end
42
-
43
- private
44
-
45
- def initialize_edges
46
- @edges = Set[]
47
- end
48
- end
49
- end
@@ -1,68 +0,0 @@
1
- module Tangle
2
- module Mixin
3
- #
4
- # Mixins for adding connectedness features
5
- #
6
- module Connectedness
7
- MIXINS = [Tangle::Mixin::Connectedness].freeze
8
- #
9
- # Mixin for adding connectedness to a graph
10
- #
11
- module Graph
12
- # Two vertices are adjacent if there is an edge between them
13
- def adjacent?(vertex, other)
14
- edges(vertex).any? { |edge| edge[vertex] == other }
15
- end
16
-
17
- # Return the set of adjacent vertices
18
- def adjacent(vertex)
19
- Set.new(edges(vertex).map { |edge| edge.walk(vertex) })
20
- end
21
-
22
- # Get the largest connected subgraph for a vertex.
23
- # Also aliased as :component and :connected_component
24
- #
25
- # connected_subgraph(vertex) => Graph
26
- #
27
- def connected_subgraph(vertex)
28
- subgraph { |other| connected_vertices?(vertex, other) }
29
- end
30
- alias component connected_subgraph
31
- alias connected_component connected_subgraph
32
-
33
- # Get the largest subgraph that is not connected to a vertex, or what's
34
- # left after removing the connected subgraph.
35
- #
36
- def disconnected_subgraph(vertex)
37
- subgraph { |other| !connected_vertices?(vertex, other) }
38
- end
39
-
40
- # A graph is connected if all vertices are connected to all vertices
41
- # An empty graph is disconnected.
42
- #
43
- def connected?(*tested_vertices)
44
- tested_vertices = vertices if tested_vertices.empty?
45
- return false if tested_vertices.empty?
46
-
47
- tested_vertices.combination(2).all? do |pair|
48
- this, that = pair.to_a
49
- reachable(this).any? { |other| other == that }
50
- end
51
- end
52
-
53
- # A graph is disconnected if any vertex is not connected to all other.
54
- # An empty graph is disconnected.
55
- #
56
- def disconnected?(*tested_vertices)
57
- !connected?(*tested_vertices)
58
- end
59
-
60
- # Return a breadth-first Enumerator for all reachable vertices,
61
- # by transitive adjacency.
62
- def reachable(start_vertex)
63
- vertex_enumerator(start_vertex, :adjacent)
64
- end
65
- end
66
- end
67
- end
68
- end
@@ -1,17 +0,0 @@
1
- require 'tangle/graph'
2
-
3
- module Tangle
4
- module Simple
5
- #
6
- # A simple graph, without loops and multiple edges
7
- class Graph < Tangle::Graph
8
- protected
9
-
10
- def insert_edge(edge)
11
- raise LoopError if edge.loop?
12
- raise MultiEdgeError if adjacent?(*edge.each_vertex)
13
- super
14
- end
15
- end
16
- end
17
- end