graphunk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/lib/graph.rb +191 -0
  3. data/lib/graphunk.rb +1 -0
  4. metadata +46 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: db25940291ff0dba0ccab4d46a61f1caf520bbd4
4
+ data.tar.gz: 9fa3edb089b77c4075805f84dd9e135486d656e1
5
+ SHA512:
6
+ metadata.gz: c1f02220f4bd9b6f650ae202d5e2f80e7cb74bb0b6ccadb13c0874dfb2e7288b1c87c79de6ae1c82a3f16f32df0a3471f0afb5725a65c248900b21616058df85
7
+ data.tar.gz: 8c2e00a649ad8e78a7fd6ed71cff5c74b104de15124e75db4af78ff1280b18fb570ff6c5f14713a93677732238f095d107114853b9a97efd17713dc4c37e4b4c
data/lib/graph.rb ADDED
@@ -0,0 +1,191 @@
1
+ require 'set'
2
+
3
+ # Undirected graph
4
+ # Vertices represented by strings
5
+ class Graph < Hash
6
+ def vertices
7
+ keys
8
+ end
9
+
10
+ def edges
11
+ [].tap do |edge_constructor|
12
+ vertices.each do |vertex|
13
+ self[vertex].each do |neighbor|
14
+ edge_constructor << [vertex, neighbor]
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ def add_vertex(name)
21
+ unless vertex_exists?(name)
22
+ self[name] = []
23
+ else
24
+ raise ArgumentError, "Vertex already exists"
25
+ end
26
+ end
27
+
28
+ def add_edge(first_vertex, second_vertex)
29
+ if edge_exists?(first_vertex, second_vertex)
30
+ raise ArgumentError, "This edge already exists"
31
+ elsif vertex_exists?(first_vertex) && vertex_exists?(second_vertex)
32
+ ordered_vertices = order_vertices(first_vertex, second_vertex)
33
+ self[ordered_vertices.first] << ordered_vertices.last
34
+ else
35
+ raise ArgumentError, "One of the vertices referenced does not exist in the graph"
36
+ end
37
+ end
38
+
39
+ def remove_vertex(name)
40
+ if vertex_exists?(name)
41
+ self.each_pair do |key, value|
42
+ self[key].delete(name) if value.include?(name)
43
+ end
44
+ self.delete(name)
45
+ else
46
+ raise ArgumentError, "That vertex does not exist in the graph"
47
+ end
48
+ end
49
+
50
+ def remove_edge(first_vertex, second_vertex)
51
+ if edge_exists?(first_vertex, second_vertex)
52
+ ordered_vertices = order_vertices(first_vertex, second_vertex)
53
+ self[ordered_vertices.first].delete(ordered_vertices.last)
54
+ else
55
+ raise ArgumentError, "That edge does not exist in the graph"
56
+ end
57
+ end
58
+
59
+ def edges_on_vertex(name)
60
+ if vertex_exists?(name)
61
+ edges.select { |edge| edge.include?(name) }
62
+ else
63
+ raise ArgumentError, "That vertex does not exist in the graph"
64
+ end
65
+ end
66
+
67
+ def neighbors_of_vertex(name)
68
+ if vertex_exists?(name)
69
+ edges.select { |edge| edge.include? name }.map do |edge|
70
+ if edge.first == name
71
+ edge.last
72
+ else
73
+ edge.first
74
+ end
75
+ end
76
+ else
77
+ raise ArgumentError, "That vertex does not exist in the graph"
78
+ end
79
+ end
80
+
81
+ def edge_exists?(first_vertex, second_vertex)
82
+ edges.include?(order_vertices(first_vertex, second_vertex))
83
+ end
84
+
85
+ def vertex_exists?(name)
86
+ vertices.include?(name)
87
+ end
88
+
89
+ def lexicographic_bfs
90
+ sets = [vertices]
91
+ output_vertices = []
92
+
93
+ until sets.empty?
94
+ v = sets.first.delete_at(0)
95
+ sets.delete_at(0) if sets.first.empty?
96
+ output_vertices << v
97
+ replaced = []
98
+ neighbors_of_vertex(v).each do |neighbor|
99
+ s = sets.select{ |set| set.include?(neighbor) }.first
100
+ if s
101
+ if replaced.include?(s)
102
+ t = sets[sets.find_index(s)-1]
103
+ else
104
+ t = []
105
+ sets.insert(sets.find_index(s), t)
106
+ replaced << s
107
+ end
108
+ s.delete(neighbor)
109
+ t << neighbor
110
+ sets.delete(s) if s.empty?
111
+ end
112
+ end
113
+ end
114
+
115
+ output_vertices
116
+ end
117
+
118
+ def clique?(vertex_list)
119
+ clique = true
120
+ vertex_list.each do |vertex|
121
+ unless (neighbors_of_vertex(vertex) & vertex_list).to_set == (vertex_list - [vertex]).to_set
122
+ clique = false
123
+ break
124
+ end
125
+ end
126
+ clique
127
+ end
128
+
129
+ def chordal?
130
+ chordal = true
131
+ (lexicographic_ordering = lexicographic_bfs.reverse).each_with_index do |v, i|
132
+ successors_of_v = lexicographic_ordering[i, lexicographic_ordering.size]
133
+ unless clique?([v] | (neighbors_of_vertex(v) & successors_of_v))
134
+ chordal = false
135
+ break
136
+ end
137
+ end
138
+ chordal
139
+ end
140
+ alias_method :triangulated?, :chordal?
141
+
142
+ def complete?
143
+ n = vertices.count
144
+ edges.count == (n * (n-1) / 2)
145
+ end
146
+
147
+ def bipartite?
148
+ colors = Hash.new
149
+ d = Hash.new
150
+ partition = Hash.new
151
+ vertices.each do |vertex|
152
+ colors[vertex] = "white"
153
+ d[vertex] = Float::INFINITY
154
+ partition[vertex] = 0
155
+ end
156
+
157
+ start = vertices.first
158
+ colors[start] = "gray"
159
+ partition[start] = 1
160
+ d[start] = 0
161
+
162
+ stack = []
163
+ stack.push(start)
164
+
165
+ until stack.empty?
166
+ vertex = stack.pop
167
+ neighbors_of_vertex(vertex).each do |neighbor|
168
+ if partition[neighbor] == partition[vertex]
169
+ return false
170
+ else
171
+ if colors[neighbor] == "white"
172
+ colors[neighbor] == "gray"
173
+ d[neighbor] = d[vertex] + 1
174
+ partition[neighbor] = 3 - partition[vertex]
175
+ stack.push(neighbor)
176
+ end
177
+ end
178
+ end
179
+ stack.pop
180
+ colors[vertex] = "black"
181
+ end
182
+
183
+ true
184
+ end
185
+
186
+ private
187
+
188
+ def order_vertices(first_vertex, second_vertex)
189
+ [first_vertex, second_vertex].sort
190
+ end
191
+ end
data/lib/graphunk.rb ADDED
@@ -0,0 +1 @@
1
+ require 'graph'
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: graphunk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Evan Hemsley
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2010-04-28 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: This gem defines a Graph class which you can is useful in various mathematical
14
+ applications.
15
+ email: evan.hemsley@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/graph.rb
21
+ - lib/graphunk.rb
22
+ homepage: http://rubygems.org/gems/graphunk
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.2.2
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: A funky Ruby library for working with graphs (as related to graph theory).
46
+ test_files: []