graphunk 0.1.1 → 0.2.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.
- checksums.yaml +4 -4
- data/lib/graph.rb +1 -145
- data/lib/graphunk.rb +2 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46c47981120e7088ae585e40b7402ccf1564ce06
|
4
|
+
data.tar.gz: 5f9024dd3e9c0b16923da07509d1c7899f5925c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16fd98c21c9d45c123295f3f83c60234d2f073f68b7ee4f56a53fd667f1b76046a25c8ff6147e69c4ceb5a6f4c4f8b2053793448fb9e1cd4e7f76b4b76a3429e
|
7
|
+
data.tar.gz: b5d498ad86b94efbe7dd8eeae32ca70e9c8a12724374274c23106a651b8f254bac7db8aed9bb9bf5a38c32a743560e0b175e77ecdc1d21d7204c32059ed6355f
|
data/lib/graph.rb
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
# Undirected graph
|
4
|
-
# Vertices represented by strings
|
1
|
+
# this class should not be invoked directly
|
5
2
|
class Graph < Hash
|
6
3
|
def vertices
|
7
4
|
keys
|
@@ -25,17 +22,6 @@ class Graph < Hash
|
|
25
22
|
end
|
26
23
|
end
|
27
24
|
|
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
25
|
def remove_vertex(name)
|
40
26
|
if vertex_exists?(name)
|
41
27
|
self.each_pair do |key, value|
|
@@ -47,15 +33,6 @@ class Graph < Hash
|
|
47
33
|
end
|
48
34
|
end
|
49
35
|
|
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
36
|
def edges_on_vertex(name)
|
60
37
|
if vertex_exists?(name)
|
61
38
|
edges.select { |edge| edge.include?(name) }
|
@@ -64,128 +41,7 @@ class Graph < Hash
|
|
64
41
|
end
|
65
42
|
end
|
66
43
|
|
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
44
|
def vertex_exists?(name)
|
86
45
|
vertices.include?(name)
|
87
46
|
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
47
|
end
|
data/lib/graphunk.rb
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
require '
|
1
|
+
require 'undirected_graph'
|
2
|
+
require 'directed_graph'
|