graphunk 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphunk/directed_graph.rb +23 -0
- data/lib/graphunk/undirected_graph.rb +78 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4679baf01a1d4c718afdf767d902cc84a707721e
|
4
|
+
data.tar.gz: 0321ab012c5fba8ae85d33c37e6f9e58e9aac334
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a918a86dad048a85b9300ab14f781ed8b313fcd433348ea7660eeecfaf40c40700681196c9316d0a2b295004e8042adb82b6d78e36204d2bafa102feeca47eab
|
7
|
+
data.tar.gz: 05bd5782911aeb7c4159dc6cb1d21eddb70944a86081dedf6c254245bf23cae8204f33dc82123dda3aefd50ea2d1a63395f34120759afa5b3ba32528f77fd126
|
@@ -105,5 +105,28 @@ module Graphunk
|
|
105
105
|
def topological_sort
|
106
106
|
dfs.sort_by { |vertex, times| times[:finish] }.map(&:first).reverse
|
107
107
|
end
|
108
|
+
|
109
|
+
def transitive?
|
110
|
+
transitive = true
|
111
|
+
vertices.each do |vertex|
|
112
|
+
reachable_by_two_edges(vertex).each do |reachable|
|
113
|
+
transitive = false unless neighbors_of_vertex(vertex).include?(reachable)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
transitive
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def reachable_by_two_edges(start)
|
122
|
+
reachable_by_two = []
|
123
|
+
reachable_by_one = neighbors_of_vertex(start)
|
124
|
+
reachable_by_one.each do |v|
|
125
|
+
neighbors_of_vertex(v).each do |u|
|
126
|
+
reachable_by_two << u
|
127
|
+
end
|
128
|
+
end
|
129
|
+
reachable_by_two
|
130
|
+
end
|
108
131
|
end
|
109
132
|
end
|
@@ -20,6 +20,22 @@ module Graphunk
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
def degree(vertex)
|
24
|
+
neighbors_of_vertex(vertex).count
|
25
|
+
end
|
26
|
+
|
27
|
+
def adjacent_edges?(first_edge, second_edge)
|
28
|
+
adjacent_edges(first_edge).include? second_edge
|
29
|
+
end
|
30
|
+
|
31
|
+
def adjacent_edges(v, u)
|
32
|
+
if edge_exists?(v, u)
|
33
|
+
edges.select { |edge| edge.include?(v) || edge.include?(u) } - [[v,u]]
|
34
|
+
else
|
35
|
+
raise ArgumentError, "That edge does not exist in the graph"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
23
39
|
def lexicographic_bfs
|
24
40
|
sets = [vertices]
|
25
41
|
output_vertices = []
|
@@ -63,7 +79,7 @@ module Graphunk
|
|
63
79
|
def chordal?
|
64
80
|
chordal = true
|
65
81
|
(lexicographic_ordering = lexicographic_bfs.reverse).each_with_index do |v, i|
|
66
|
-
successors_of_v = lexicographic_ordering[i
|
82
|
+
successors_of_v = lexicographic_ordering[i..-1]
|
67
83
|
unless clique?([v] | (neighbors_of_vertex(v) & successors_of_v))
|
68
84
|
chordal = false
|
69
85
|
break
|
@@ -116,5 +132,66 @@ module Graphunk
|
|
116
132
|
|
117
133
|
true
|
118
134
|
end
|
135
|
+
|
136
|
+
def comparability?
|
137
|
+
assign_orientation
|
138
|
+
end
|
139
|
+
|
140
|
+
def transitive_orientation
|
141
|
+
assign_orientation(true)
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
def assign_orientation(return_graph = false)
|
147
|
+
transitive_orientation = Graphunk::DirectedGraph.new
|
148
|
+
transitive_orientation.add_vertices(*vertices)
|
149
|
+
|
150
|
+
unconsidered_edges = edges
|
151
|
+
|
152
|
+
transitive = true
|
153
|
+
|
154
|
+
until unconsidered_edges.empty?
|
155
|
+
considered_edge = unconsidered_edges.first
|
156
|
+
unconsidered_edges.delete(considered_edge)
|
157
|
+
|
158
|
+
transitive_orientation.add_edge(considered_edge.first, considered_edge.last)
|
159
|
+
|
160
|
+
explore = lambda do |edge|
|
161
|
+
if unconsidered_edges.include? edge
|
162
|
+
adjacent_edges(edge.first, edge.last).each do |adjacent_edge|
|
163
|
+
next if unconsidered_edges.include? adjacent_edge
|
164
|
+
|
165
|
+
shared_vertex = adjacent_edge.select { |vertex| edge.include? vertex }.first
|
166
|
+
unshared_edge_vertex = edge.reject { |vertex| adjacent_edge.include? vertex }.first
|
167
|
+
unshared_adjacent_edge_vertex = adjacent_edge.reject { |vertex| edge.include? vertex }.first
|
168
|
+
|
169
|
+
unless edge_exists?(unshared_edge_vertex, unshared_adjacent_edge_vertex)
|
170
|
+
if transitive_orientation.edge_exists?(shared_vertex, unshared_adjacent_edge_vertex)
|
171
|
+
transitive = false if transitive_orientation.edge_exists?(unshared_edge_vertex, shared_vertex)
|
172
|
+
transitive_orientation.add_edge(shared_vertex, unshared_edge_vertex) unless transitive_orientation.edge_exists?(shared_vertex, unshared_edge_vertex)
|
173
|
+
unconsidered_edges.delete(order_vertices(shared_vertex, unshared_edge_vertex))
|
174
|
+
else
|
175
|
+
transitive = false if transitive_orientation.edge_exists?(shared_vertex, unshared_edge_vertex)
|
176
|
+
transitive_orientation.add_edge(unshared_edge_vertex, shared_vertex) unless transitive_orientation.edge_exists?(unshared_edge_vertex, shared_vertex)
|
177
|
+
unconsidered_edges.delete(order_vertices(shared_vertex, unshared_edge_vertex))
|
178
|
+
end
|
179
|
+
|
180
|
+
adjacent_edges(edge.first, edge.last).each { |neighbor| explore.call neighbor }
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
adjacent_edges(considered_edge.first, considered_edge.last).each { |neighbor_edge| explore.call neighbor_edge }
|
187
|
+
end
|
188
|
+
|
189
|
+
if transitive && return_graph
|
190
|
+
transitive_orientation
|
191
|
+
else
|
192
|
+
transitive
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
119
196
|
end
|
120
197
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphunk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Hemsley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|