graphunk 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []