graph_matching 0.2.0 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9fb85654523ce9fe2560a9973b2371062627116e
4
- data.tar.gz: 73dcf437cc9eeef96045c5d0a3a7ff9213f4e7bc
2
+ SHA256:
3
+ metadata.gz: 5fa48ec20940e407788ff34b0193dc83d8c6ce4d95c562631b8d20171107839d
4
+ data.tar.gz: 97d33ef07e6ced8896713a083f97128aaedf961292e5a217533a5cc5010d25e5
5
5
  SHA512:
6
- metadata.gz: 5ac775ea72a05fc3ab61b046f81e0b5e7cd24e3a7cfb58b7d3481351a0bc8ee3a3c3bd73457520cfc7d4c18b093698a86eead01783e46538ef4c50e97ef7bea4
7
- data.tar.gz: 164e1863a6460a46fbb844463618e1ee1a1c95e20a830765fd6c590d68d6f4cdf034a5df3553060cebea63fdcc36a5e02aa515a6ca3ed58a40d3bcd077a371d2
6
+ metadata.gz: 514665406895b92245a4171560bafe40fd2366c90c907b90eb45cfd68d91434c7e54ae759c004a1480391a698249d2db4f74558e8f272061fc20824d74ecf134
7
+ data.tar.gz: 94febc02ecfd5350ea26d5c4d51fa6079cfe60a209a5826338213925af9ce91cc188334f4c364607e7fa05334489d60dd0369a47fc06aa34802a1625255ffd38
@@ -3,6 +3,10 @@ inherit_from: .rubocop_todo.yml
3
3
  AllCops:
4
4
  TargetRubyVersion: 2.3
5
5
 
6
+ # Personal preference
7
+ Layout/EmptyLineAfterGuardClause:
8
+ Enabled: false
9
+
6
10
  Layout/MultilineOperationIndentation:
7
11
  EnforcedStyle: indented
8
12
 
@@ -18,11 +22,30 @@ Metrics/ClassLength:
18
22
  Metrics/MethodLength:
19
23
  Enabled: false
20
24
 
25
+ # Too subtle to lint
26
+ Naming/HeredocDelimiterNaming:
27
+ Enabled: false
28
+
29
+ # We use some mathematical symbols because those symbols are used in the papers
30
+ # we reference.
31
+ Style/AsciiComments:
32
+ AllowedChars:
33
+ - π
34
+ - ≠
35
+
36
+ # Too subtle to lint. Favor semantic style.
37
+ Style/BlockDelimiters:
38
+ Enabled: false
39
+
21
40
  # Avoid postfix conditionals, except on the shortest of lines. Never use postfix
22
41
  # conditional after an assignment.
23
42
  Style/IfUnlessModifier:
24
43
  Enabled: false
25
44
 
45
+ # Too subtle to lint. Definitely use guard clauses though, they're great.
46
+ Style/GuardClause:
47
+ Enabled: false
48
+
26
49
  # For this project, where performance matters, do not use the nil predicate method
27
50
  # (`nil?`), as it is slower than the `==` operator.
28
51
  Style/NilComparison:
@@ -6,74 +6,6 @@
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Cop supports --auto-correct.
10
- Layout/CommentIndentation:
11
- Exclude:
12
- - 'lib/graph_matching/algorithm/mcm_general.rb'
13
-
14
- # Cop supports --auto-correct.
15
- Layout/EmptyLineAfterGuardClause:
16
- Exclude:
17
- - 'benchmark/mwm_general/incomplete_graphs/benchmark.rb'
18
- - 'lib/graph_matching/algorithm/mcm_bipartite.rb'
19
- - 'lib/graph_matching/algorithm/mcm_general.rb'
20
- - 'lib/graph_matching/algorithm/mwm_bipartite.rb'
21
- - 'lib/graph_matching/algorithm/mwm_general.rb'
22
- - 'lib/graph_matching/algorithm/mwmg_delta_assertions.rb'
23
- - 'lib/graph_matching/core_ext/set.rb'
24
- - 'lib/graph_matching/graph/bigraph.rb'
25
- - 'lib/graph_matching/graph/graph.rb'
26
- - 'lib/graph_matching/graph/weighted.rb'
27
- - 'lib/graph_matching/integer_vertexes.rb'
28
- - 'lib/graph_matching/matching.rb'
29
- - 'lib/graph_matching/visualize.rb'
30
- - 'spec/spec_helper.rb'
31
-
32
- # Cop supports --auto-correct.
33
- Layout/EmptyLineAfterMagicComment:
34
- Exclude:
35
- - 'graph_matching.gemspec'
36
-
37
- # Cop supports --auto-correct.
38
- # Configuration parameters: EnforcedStyle.
39
- # SupportedStyles: empty_lines, no_empty_lines
40
- Layout/EmptyLinesAroundBlockBody:
41
- Exclude:
42
- - 'lib/graph_matching/algorithm/mcm_general.rb'
43
-
44
- # Cop supports --auto-correct.
45
- # Configuration parameters: EnforcedStyle.
46
- # SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines, beginning_only, ending_only
47
- Layout/EmptyLinesAroundClassBody:
48
- Exclude:
49
- - 'lib/graph_matching/algorithm/mcm_bipartite.rb'
50
- - 'lib/graph_matching/algorithm/mcm_general.rb'
51
- - 'lib/graph_matching/algorithm/mwm_bipartite.rb'
52
- - 'lib/graph_matching/algorithm/mwm_general.rb'
53
-
54
- # Cop supports --auto-correct.
55
- Layout/EmptyLinesAroundMethodBody:
56
- Exclude:
57
- - 'lib/graph_matching/algorithm/mcm_general.rb'
58
-
59
- # Cop supports --auto-correct.
60
- # Configuration parameters: EnforcedStyle.
61
- # SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines
62
- Layout/EmptyLinesAroundModuleBody:
63
- Exclude:
64
- - 'lib/graph_matching/algorithm/matching_algorithm.rb'
65
- - 'lib/graph_matching/algorithm/mcm_bipartite.rb'
66
- - 'lib/graph_matching/algorithm/mcm_general.rb'
67
- - 'lib/graph_matching/algorithm/mwm_bipartite.rb'
68
- - 'lib/graph_matching/algorithm/mwm_general.rb'
69
-
70
- # Cop supports --auto-correct.
71
- # Configuration parameters: EnforcedStyle.
72
- # SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent
73
- Layout/IndentHeredoc:
74
- Exclude:
75
- - 'lib/graph_matching/errors.rb'
76
-
77
9
  Metrics/AbcSize:
78
10
  Max: 74
79
11
 
@@ -87,14 +19,6 @@ Metrics/ParameterLists:
87
19
  Metrics/PerceivedComplexity:
88
20
  Max: 17
89
21
 
90
- # Configuration parameters: Blacklist.
91
- # Blacklist: (?-mix:(^|\s)(EO[A-Z]{1}|END)(\s|$))
92
- Naming/HeredocDelimiterNaming:
93
- Exclude:
94
- - 'graph_matching.gemspec'
95
- - 'lib/graph_matching/algorithm/mwm_general.rb'
96
- - 'lib/graph_matching/errors.rb'
97
-
98
22
  # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
99
23
  # AllowedNames: io, id, to, by, on, in, at, ip, db
100
24
  Naming/UncommunicativeMethodParamName:
@@ -124,33 +48,6 @@ Style/Alias:
124
48
  Exclude:
125
49
  - 'lib/graph_matching/ordered_set.rb'
126
50
 
127
- # Configuration parameters: AllowedChars.
128
- Style/AsciiComments:
129
- Exclude:
130
- - 'lib/graph_matching/algorithm/mwm_bipartite.rb'
131
- - 'lib/graph_matching/algorithm/mwm_general.rb'
132
-
133
- # Cop supports --auto-correct.
134
- # Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, IgnoredMethods.
135
- # SupportedStyles: line_count_based, semantic, braces_for_chaining
136
- # ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
137
- # FunctionalMethods: let, let!, subject, watch
138
- # IgnoredMethods: lambda, proc, it
139
- Style/BlockDelimiters:
140
- Exclude:
141
- - 'benchmark/mwm_general/incomplete_graphs/benchmark.rb'
142
- - 'lib/graph_matching/algorithm/mcm_bipartite.rb'
143
- - 'lib/graph_matching/algorithm/mwm_bipartite.rb'
144
- - 'lib/graph_matching/algorithm/mwm_general.rb'
145
- - 'lib/graph_matching/graph/graph.rb'
146
- - 'lib/graph_matching/matching.rb'
147
- - 'lib/graph_matching/ordered_set.rb'
148
- - 'spec/graph_matching/algorithm/mcm_bipartite_spec.rb'
149
-
150
- Style/CommentedKeyword:
151
- Exclude:
152
- - 'lib/graph_matching/algorithm/mcm_general.rb'
153
-
154
51
  # Cop supports --auto-correct.
155
52
  # Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions.
156
53
  # SupportedStyles: assign_to_condition, assign_inside_condition
@@ -164,146 +61,3 @@ Style/ConditionalAssignment:
164
61
  Style/EmptyElse:
165
62
  Exclude:
166
63
  - 'lib/graph_matching/algorithm/mwm_general.rb'
167
-
168
- # Cop supports --auto-correct.
169
- Style/Encoding:
170
- Exclude:
171
- - 'benchmark/mcm_bipartite/complete_bigraphs/benchmark.rb'
172
- - 'benchmark/mcm_general/complete_graphs/benchmark.rb'
173
- - 'benchmark/mwm_bipartite/complete_bigraphs/benchmark.rb'
174
- - 'benchmark/mwm_bipartite/misc/calc_d2/benchmark.rb'
175
- - 'benchmark/mwm_general/complete_graphs/benchmark.rb'
176
- - 'benchmark/mwm_general/incomplete_graphs/benchmark.rb'
177
- - 'graph_matching.gemspec'
178
- - 'lib/graph_matching.rb'
179
- - 'lib/graph_matching/algorithm/matching_algorithm.rb'
180
- - 'lib/graph_matching/algorithm/mcm_bipartite.rb'
181
- - 'lib/graph_matching/algorithm/mcm_general.rb'
182
- - 'lib/graph_matching/algorithm/mwm_bipartite.rb'
183
- - 'lib/graph_matching/algorithm/mwm_general.rb'
184
- - 'lib/graph_matching/assertion.rb'
185
- - 'lib/graph_matching/core_ext/set.rb'
186
- - 'lib/graph_matching/directed_edge_set.rb'
187
- - 'lib/graph_matching/errors.rb'
188
- - 'lib/graph_matching/graph/bigraph.rb'
189
- - 'lib/graph_matching/graph/graph.rb'
190
- - 'lib/graph_matching/graph/weighted.rb'
191
- - 'lib/graph_matching/graph/weighted_bigraph.rb'
192
- - 'lib/graph_matching/graph/weighted_graph.rb'
193
- - 'lib/graph_matching/integer_vertexes.rb'
194
- - 'lib/graph_matching/matching.rb'
195
- - 'lib/graph_matching/ordered_set.rb'
196
- - 'lib/graph_matching/version.rb'
197
- - 'lib/graph_matching/visualize.rb'
198
- - 'spec/graph_matching/algorithm/matching_algorithm_spec.rb'
199
- - 'spec/graph_matching/algorithm/mcm_bipartite_spec.rb'
200
- - 'spec/graph_matching/algorithm/mcm_general_spec.rb'
201
- - 'spec/graph_matching/algorithm/mwm_bipartite_spec.rb'
202
- - 'spec/graph_matching/algorithm/mwm_general_spec.rb'
203
- - 'spec/graph_matching/graph/bigraph_spec.rb'
204
- - 'spec/graph_matching/graph/graph_spec.rb'
205
- - 'spec/graph_matching/graph/weighted_spec.rb'
206
- - 'spec/graph_matching/integer_vertexes_spec.rb'
207
- - 'spec/graph_matching/matching_spec.rb'
208
- - 'spec/graph_matching/visualize_spec.rb'
209
- - 'spec/graph_matching_spec.rb'
210
- - 'spec/spec_helper.rb'
211
-
212
- # Cop supports --auto-correct.
213
- Style/ExpandPathArguments:
214
- Exclude:
215
- - 'graph_matching.gemspec'
216
- - 'spec/spec_helper.rb'
217
-
218
- # Cop supports --auto-correct.
219
- # Configuration parameters: EnforcedStyle.
220
- # SupportedStyles: format, sprintf, percent
221
- Style/FormatString:
222
- Exclude:
223
- - 'benchmark/mcm_bipartite/complete_bigraphs/benchmark.rb'
224
- - 'benchmark/mcm_general/complete_graphs/benchmark.rb'
225
- - 'benchmark/mwm_bipartite/complete_bigraphs/benchmark.rb'
226
- - 'benchmark/mwm_general/complete_graphs/benchmark.rb'
227
- - 'benchmark/mwm_general/incomplete_graphs/benchmark.rb'
228
-
229
- # Cop supports --auto-correct.
230
- # Configuration parameters: EnforcedStyle.
231
- # SupportedStyles: when_needed, always, never
232
- Style/FrozenStringLiteralComment:
233
- Exclude:
234
- - 'Gemfile'
235
- - 'Rakefile'
236
- - 'benchmark/mcm_bipartite/complete_bigraphs/benchmark.rb'
237
- - 'benchmark/mcm_general/complete_graphs/benchmark.rb'
238
- - 'benchmark/mwm_bipartite/complete_bigraphs/benchmark.rb'
239
- - 'benchmark/mwm_bipartite/misc/calc_d2/benchmark.rb'
240
- - 'benchmark/mwm_general/complete_graphs/benchmark.rb'
241
- - 'benchmark/mwm_general/incomplete_graphs/benchmark.rb'
242
- - 'graph_matching.gemspec'
243
- - 'lib/graph_matching.rb'
244
- - 'lib/graph_matching/algorithm/matching_algorithm.rb'
245
- - 'lib/graph_matching/algorithm/mcm_bipartite.rb'
246
- - 'lib/graph_matching/algorithm/mcm_general.rb'
247
- - 'lib/graph_matching/algorithm/mwm_bipartite.rb'
248
- - 'lib/graph_matching/algorithm/mwm_general.rb'
249
- - 'lib/graph_matching/algorithm/mwmg_delta_assertions.rb'
250
- - 'lib/graph_matching/assertion.rb'
251
- - 'lib/graph_matching/core_ext/set.rb'
252
- - 'lib/graph_matching/directed_edge_set.rb'
253
- - 'lib/graph_matching/errors.rb'
254
- - 'lib/graph_matching/graph/bigraph.rb'
255
- - 'lib/graph_matching/graph/graph.rb'
256
- - 'lib/graph_matching/graph/weighted.rb'
257
- - 'lib/graph_matching/graph/weighted_bigraph.rb'
258
- - 'lib/graph_matching/graph/weighted_graph.rb'
259
- - 'lib/graph_matching/integer_vertexes.rb'
260
- - 'lib/graph_matching/matching.rb'
261
- - 'lib/graph_matching/ordered_set.rb'
262
- - 'lib/graph_matching/version.rb'
263
- - 'lib/graph_matching/visualize.rb'
264
- - 'profile/mwm_general/profile.rb'
265
- - 'spec/graph_matching/algorithm/matching_algorithm_spec.rb'
266
- - 'spec/graph_matching/algorithm/mcm_bipartite_spec.rb'
267
- - 'spec/graph_matching/algorithm/mcm_general_spec.rb'
268
- - 'spec/graph_matching/algorithm/mwm_bipartite_spec.rb'
269
- - 'spec/graph_matching/algorithm/mwm_general_spec.rb'
270
- - 'spec/graph_matching/graph/bigraph_spec.rb'
271
- - 'spec/graph_matching/graph/graph_spec.rb'
272
- - 'spec/graph_matching/graph/weighted_spec.rb'
273
- - 'spec/graph_matching/integer_vertexes_spec.rb'
274
- - 'spec/graph_matching/matching_spec.rb'
275
- - 'spec/graph_matching/visualize_spec.rb'
276
- - 'spec/graph_matching_spec.rb'
277
- - 'spec/spec_helper.rb'
278
-
279
- # Configuration parameters: MinBodyLength.
280
- Style/GuardClause:
281
- Exclude:
282
- - 'lib/graph_matching/algorithm/mcm_bipartite.rb'
283
- - 'lib/graph_matching/algorithm/mcm_general.rb'
284
- - 'lib/graph_matching/algorithm/mwm_bipartite.rb'
285
- - 'lib/graph_matching/algorithm/mwm_general.rb'
286
- - 'lib/graph_matching/algorithm/mwmg_delta_assertions.rb'
287
- - 'lib/graph_matching/assertion.rb'
288
-
289
- Style/MultipleComparison:
290
- Exclude:
291
- - 'lib/graph_matching/algorithm/mwmg_delta_assertions.rb'
292
-
293
- # Cop supports --auto-correct.
294
- # Configuration parameters: PreferredDelimiters.
295
- Style/PercentLiteralDelimiters:
296
- Exclude:
297
- - 'lib/graph_matching/algorithm/mwm_general.rb'
298
- - 'spec/graph_matching/integer_vertexes_spec.rb'
299
-
300
- # Cop supports --auto-correct.
301
- Style/StderrPuts:
302
- Exclude:
303
- - 'lib/graph_matching/visualize.rb'
304
-
305
- # Cop supports --auto-correct.
306
- # Configuration parameters: MinSize.
307
- # SupportedStyles: percent, brackets
308
- Style/SymbolArray:
309
- EnforcedStyle: brackets
@@ -2,8 +2,13 @@ cache: bundler
2
2
  language: ruby
3
3
  notifications:
4
4
  email: false
5
+
6
+ # Do not request the very latest ruby patch. It'll slow down the build by
7
+ # making rvm download a ruby. Instead, specify only major/minor and travis
8
+ # will just use whatever patch level it has, and that's good enough for this
9
+ # project.
5
10
  rvm:
6
- - "2.3.8"
7
- - "2.4.5"
8
- - "2.5.3"
9
- - "2.6.1"
11
+ - "2.3"
12
+ - "2.4"
13
+ - "2.5"
14
+ - "2.6"
@@ -3,7 +3,12 @@
3
3
  This project follows [semver 2.0.0][1] and the recommendations
4
4
  of [keepachangelog.com][2].
5
5
 
6
- ## Unreleased
6
+ ## 0.2.1 (2020-02-10)
7
+
8
+ ### Fixed
9
+
10
+ - [#10](https://github.com/jaredbeck/graph_matching/pull/10) -
11
+ `WeightedBigraph#maximum_weighted_matching` hangs forever
7
12
 
8
13
  ## 0.2.0 (2019-02-15)
9
14
 
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in graph_matching.gemspec
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
 
3
5
  task(:spec).clear
@@ -9,4 +11,4 @@ end
9
11
  require 'rubocop/rake_task'
10
12
  RuboCop::RakeTask.new
11
13
 
12
- task default: [:rubocop, :spec]
14
+ task default: %i[rubocop spec]
@@ -1,5 +1,6 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'graph_matching/version'
5
6
 
@@ -23,11 +24,10 @@ Gem::Specification.new do |spec|
23
24
  spec.require_paths = ['lib']
24
25
  spec.required_ruby_version = '>= 2.3.0'
25
26
  spec.add_runtime_dependency 'rgl', '~> 0.5.0'
26
- spec.add_development_dependency 'bundler', '~> 1.12'
27
- spec.add_development_dependency 'pry-byebug', '~> 3.4'
28
- spec.add_development_dependency 'rake', '~> 12.0'
29
- spec.add_development_dependency 'rspec-core', '~> 3.6'
30
- spec.add_development_dependency 'rspec-expectations', '~> 3.6'
31
- spec.add_development_dependency 'rspec-mocks', '~> 3.6'
27
+ spec.add_development_dependency 'byebug', '~> 11.0'
28
+ spec.add_development_dependency 'rake', '~> 12.3'
29
+ spec.add_development_dependency 'rspec-core', '~> 3.8'
30
+ spec.add_development_dependency 'rspec-expectations', '~> 3.8'
31
+ spec.add_development_dependency 'rspec-mocks', '~> 3.8'
32
32
  spec.add_development_dependency 'rubocop', '~> 0.64.0'
33
33
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'graph_matching/core_ext/set'
4
4
  require 'graph_matching/graph/graph'
@@ -1,10 +1,9 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require_relative '../assertion'
4
4
 
5
5
  module GraphMatching
6
6
  module Algorithm
7
-
8
7
  # All matching algorithms operate on a graph, hence the
9
8
  # common constructor.
10
9
  class MatchingAlgorithm
@@ -18,6 +17,5 @@ module GraphMatching
18
17
  Assertion.new(obj)
19
18
  end
20
19
  end
21
-
22
20
  end
23
21
  end
@@ -1,11 +1,10 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require_relative '../matching'
4
4
  require_relative 'matching_algorithm'
5
5
 
6
6
  module GraphMatching
7
7
  module Algorithm
8
-
9
8
  # `MCMBipartite` implements Maximum Cardinality Matching in
10
9
  # bipartite graphs.
11
10
  class MCMBipartite < MatchingAlgorithm
@@ -24,9 +23,11 @@ module GraphMatching
24
23
  predecessors = {}
25
24
  aug_path = nil
26
25
 
27
- # Label unmatched vertexes in U with label R. These R-vertexes
28
- # are candidates for the start of an augmenting path.
29
- unmarked = r = u.select { |i| m[i] == nil }
26
+ # Label unmatched vertexes in U with label R.
27
+ r = u.select { |i| m[i] == nil }
28
+
29
+ # These R-vertexes are candidates for the start of an augmenting path.
30
+ unmarked = r.dup.to_a
30
31
 
31
32
  # While there are unmarked R-vertexes
32
33
  loop do
@@ -47,6 +48,7 @@ module GraphMatching
47
48
 
48
49
  adj_u_in_m.each do |ui|
49
50
  r << ui
51
+ unmarked << ui
50
52
  predecessors[ui] = vi
51
53
  end
52
54
 
@@ -113,7 +115,6 @@ module GraphMatching
113
115
  m[v] != i && !t.include?(i)
114
116
  }
115
117
  end
116
-
117
118
  end
118
119
  end
119
120
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require_relative '../directed_edge_set'
4
4
  require_relative '../matching'
@@ -6,11 +6,9 @@ require_relative 'matching_algorithm'
6
6
 
7
7
  module GraphMatching
8
8
  module Algorithm
9
-
10
9
  # `MCMGeneral` implements Maximum Cardinality Matching in
11
10
  # general graphs (as opposed to bipartite).
12
11
  class MCMGeneral < MatchingAlgorithm
13
-
14
12
  # An LFlag represents a flag on an edge during Gabow's `l` function.
15
13
  class LFlag
16
14
  attr_reader :edge
@@ -66,17 +64,17 @@ module GraphMatching
66
64
  label[u] = first[u] = 0
67
65
  end
68
66
 
69
- # E2 [Choose an edge ] Choose an edge xy, where x is an outer
70
- # vertex. (An edge vw may be chosen twice in a search--once
71
- # with x = v, and once with x = w.) If no such edge exists,
72
- # go to E7. (Edges xy can be chosen in an arbitrary order. A
73
- # possible choice method is "breadth-first": an outer vertex
74
- # x = x1 is chosen, and edges (x1,y) are chosen in succeeding
75
- # executions of E2, when all such edges have been chosen, the
76
- # vertex x2 that was labeled immediately after x1 is chosen,
77
- # and the process is repeated for x = x2. This breadth-first
78
- # method requires that Algorithm E maintain a list of outer
79
- # vertices, x1, x2, ...)
67
+ # E2 [Choose an edge ] Choose an edge xy, where x is an outer
68
+ # vertex. (An edge vw may be chosen twice in a search--once
69
+ # with x = v, and once with x = w.) If no such edge exists,
70
+ # go to E7. (Edges xy can be chosen in an arbitrary order. A
71
+ # possible choice method is "breadth-first": an outer vertex
72
+ # x = x1 is chosen, and edges (x1,y) are chosen in succeeding
73
+ # executions of E2, when all such edges have been chosen, the
74
+ # vertex x2 that was labeled immediately after x1 is chosen,
75
+ # and the process is repeated for x = x2. This breadth-first
76
+ # method requires that Algorithm E maintain a list of outer
77
+ # vertices, x1, x2, ...)
80
78
 
81
79
  searching = true
82
80
  visited_nodes = Set.new
@@ -91,9 +89,9 @@ module GraphMatching
91
89
  discovered.each do |y|
92
90
  visited_edges.add(x, y)
93
91
 
94
- # E3. [Augment the matching.] If y is unmatched and y != u,
95
- # set MATE(y) = x, call R(x, y): then go to E7 (R
96
- # completes the augment along path (y)*P(x))
92
+ # E3. [Augment the matching.] If y is unmatched and y != u,
93
+ # set MATE(y) = x, call R(x, y): then go to E7 (R
94
+ # completes the augment along path (y)*P(x))
97
95
 
98
96
  if mate[y] == 0 && y != u
99
97
  mate[y] = x
@@ -101,18 +99,18 @@ module GraphMatching
101
99
  searching = false # go to E7
102
100
  break
103
101
 
104
- # E4. [Assign edge labels.] If y is outer, call L, then go to
105
- # E2 (L assigns edge label n(xy) to nonouter vertices in P(x)
106
- # and P(y))
102
+ # E4. [Assign edge labels.] If y is outer, call L, then go to
103
+ # E2 (L assigns edge label n(xy) to nonouter vertices in P(x)
104
+ # and P(y))
107
105
 
108
106
  elsif outer?(label[y])
109
107
  l(x, y, first, label, mate, q, visited_nodes)
110
108
 
111
- # E5. [Assign a vertex label.] Set v <- MATE(y). If v is
112
- # nonouter, set LABEL(v) <- x, FIRST(v) <- y, and go to E2
113
- #
114
- # E6. [Get next edge.] Go to E2 (y is nonouter and MATE(y) is
115
- # outer, so edge xy adds nothing).
109
+ # E5. [Assign a vertex label.] Set v <- MATE(y). If v is
110
+ # nonouter, set LABEL(v) <- x, FIRST(v) <- y, and go to E2
111
+ #
112
+ # E6. [Get next edge.] Go to E2 (y is nonouter and MATE(y) is
113
+ # outer, so edge xy adds nothing).
116
114
 
117
115
  else
118
116
  v = mate[y]
@@ -124,15 +122,14 @@ module GraphMatching
124
122
  q.enq(v)
125
123
  end
126
124
  end
127
-
128
125
  end
129
126
  end
130
127
 
131
- #
132
- # E7. [Stop the search] Set LABEL(O) <- -1. For all outer
133
- # vertices i set LABEL(i) <- LABEL(MATE(i)) <- -1 Then go
134
- # to E1 (now all vertexes are nonouter for the next search).
135
- #
128
+ #
129
+ # E7. [Stop the search] Set LABEL(O) <- -1. For all outer
130
+ # vertices i set LABEL(i) <- LABEL(MATE(i)) <- -1 Then go
131
+ # to E1 (now all vertexes are nonouter for the next search).
132
+ #
136
133
 
137
134
  label[0] = -1
138
135
  label.each_with_index do |obj, ix|
@@ -140,8 +137,7 @@ module GraphMatching
140
137
  label[ix] = label[mate[ix]] = -1
141
138
  end
142
139
  end
143
-
144
- end # while e0_loop
140
+ end
145
141
 
146
142
  Matching.gabow(mate)
147
143
  end
@@ -155,7 +151,6 @@ module GraphMatching
155
151
  # vertex in both P(x) and P(y). Then it labels all nonouter
156
152
  # vertices preceding join in P(x) or P(y).
157
153
  def l(x, y, first, label, mate, q, visited_nodes)
158
-
159
154
  # L0. [Initialize.] Set r <- FIRST(x), s <= FIRST(y).
160
155
  # If r = s, return (no vertices can be labeled).
161
156
  # Otherwise flag r and s. (Steps L1-L2 find join by advancing
@@ -184,10 +179,10 @@ module GraphMatching
184
179
  s = temp
185
180
  end
186
181
 
187
- # L2. [Next nonouter vertex.] Set r <- FIRST(LABEL(MATE(r)))
188
- # (r is set to the next nonouter vertex in P(x) or P(y)). If
189
- # r is not flagged, flag r and go to L1 Otherwise set
190
- # join <- r and go to L3.
182
+ # L2. [Next nonouter vertex.] Set r <- FIRST(LABEL(MATE(r)))
183
+ # (r is set to the next nonouter vertex in P(x) or P(y)). If
184
+ # r is not flagged, flag r and go to L1 Otherwise set
185
+ # join <- r and go to L3.
191
186
 
192
187
  r = first[label[mate[r]]]
193
188
  if label[r].is_a?(LFlag)
@@ -204,10 +199,9 @@ module GraphMatching
204
199
  # set v <- FIRST(y) and do L4. Then go to L5.
205
200
 
206
201
  [first[x], first[y]].each do |v|
207
-
208
- # L4 [Label v] If v != join, set LABEL(v) <- n(xy), FIRST(v) <- join,
209
- # v <- FIRST(LABEL(MATE(v))) and repeat step L4
210
- # Otherwise continue as specified in L3.
202
+ # L4 [Label v] If v != join, set LABEL(v) <- n(xy), FIRST(v) <- join,
203
+ # v <- FIRST(LABEL(MATE(v))) and repeat step L4
204
+ # Otherwise continue as specified in L3.
211
205
 
212
206
  until v == join
213
207
  label[v] = n(x, y)
@@ -250,7 +244,6 @@ module GraphMatching
250
244
  # does not set MATE(w) <- v. This is done in step E3 or another
251
245
  # call to R.) R is a recursive routine.
252
246
  def r(v, w, label, mate)
253
-
254
247
  # R1. [Match v to w ] Set t <- MATE(v), MATE(v) <- w.
255
248
  # If MATE(t) != v, return (the path is completely re-matched)
256
249
 
@@ -282,8 +275,6 @@ module GraphMatching
282
275
  def vertex_label?(label_value)
283
276
  label_value.is_a?(Integer) && label_value > 0
284
277
  end
285
-
286
278
  end
287
-
288
279
  end
289
280
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require_relative '../graph/weighted_bigraph'
4
4
  require_relative '../matching'
@@ -6,12 +6,14 @@ require_relative 'matching_algorithm'
6
6
 
7
7
  module GraphMatching
8
8
  module Algorithm
9
-
10
9
  # `MWMBipartite` implements Maximum Weighted Matching in
11
10
  # bipartite graphs. It extends Maximum Cardinality
12
11
  # Matching for `Weighted` graphs.
12
+ #
13
+ # > In each stage we look for an augmenting path, as in the simple algorithm
14
+ # > for Problem 1 [Maximum Cardinality Matching], except that we use only
15
+ # > edges with zero slack. (Galil, 1986, p. 30)
13
16
  class MWMBipartite < MCMBipartite
14
-
15
17
  def initialize(graph)
16
18
  assert(graph).is_a(Graph::WeightedBigraph)
17
19
  super
@@ -50,13 +52,14 @@ module GraphMatching
50
52
  t << j
51
53
  predecessors[j] = i
52
54
 
53
- # If there are matched edges, follow each to a dog and
54
- # label the dog with S. Otherwise, backtrack to
55
- # construct an augmenting path.
55
+ # If `j` has matched edges (other than the one we just traversed,
56
+ # `i`) then follow each to a dog and label the dog with S.
57
+ # Otherwise, backtrack to construct an augmenting path.
56
58
  m_dogs = matched_adjacent(j, i, g, m)
57
59
 
58
60
  m_dogs.each do |md|
59
61
  s << md
62
+ q << md
60
63
  predecessors[md] = j
61
64
  end
62
65
 
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require_relative '../graph/weighted_graph'
4
4
  require_relative '../matching'
@@ -6,11 +6,9 @@ require_relative 'matching_algorithm'
6
6
 
7
7
  module GraphMatching
8
8
  module Algorithm
9
-
10
9
  # `MWMGeneral` implements Maximum Weighted Matching in
11
10
  # general graphs.
12
11
  class MWMGeneral < MatchingAlgorithm
13
-
14
12
  # If b is a top-level blossom,
15
13
  # label[b] is 0 if b is unlabeled (free);
16
14
  # 1 if b is an S-vertex/blossom;
@@ -19,7 +17,7 @@ module GraphMatching
19
17
  LBL_S = 1
20
18
  LBL_T = 2
21
19
  LBL_CRUMB = 5
22
- LBL_NAMES = %w(Free S T Crumb).freeze
20
+ LBL_NAMES = %w[Free S T Crumb].freeze
23
21
 
24
22
  def initialize(graph)
25
23
  assert(graph).is_a(Graph::WeightedGraph)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module GraphMatching
2
4
  module Algorithm
3
5
  # Can be mixed into MWMGeneral to add runtime assertions
@@ -67,7 +69,7 @@ module GraphMatching
67
69
  end
68
70
  next if @best_edge[b].nil?
69
71
  i, j = @edges[@best_edge[b]].to_a
70
- unless @in_blossom[i] == b || @in_blossom[j] == b
72
+ unless @in_blossom.values_at(i, j).include?(b)
71
73
  raise 'Assertion failed'
72
74
  end
73
75
  unless @in_blossom[i] != b || @in_blossom[j] != b
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module GraphMatching
4
4
  # Provides expressive methods for common runtime assertions, e.g.
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'set'
4
4
 
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module GraphMatching
4
4
  # A `DirectedEdgeSet` is simply a set of directed edges in a
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module GraphMatching
4
4
  class GraphMatchingError < StandardError
@@ -7,9 +7,9 @@ module GraphMatching
7
7
  # no-doc
8
8
  class InvalidVertexNumbering < GraphMatchingError
9
9
  def initialize(msg = nil)
10
- msg ||= <<-EOS
11
- Expected vertexes to be consecutive positive integers \
12
- starting with zero
10
+ msg ||= <<~EOS
11
+ Expected vertexes to be consecutive positive integers \
12
+ starting with zero
13
13
  EOS
14
14
  super(msg)
15
15
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'rgl/bipartite'
4
4
  require_relative 'graph'
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'rgl/adjacency'
4
4
  require 'rgl/connected_components'
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module GraphMatching
4
4
  module Graph
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require_relative 'weighted'
4
4
  require_relative '../algorithm/mwm_bipartite'
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require_relative 'weighted'
4
4
  require_relative '../algorithm/mwm_general'
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module GraphMatching
4
4
  # Converts the vertices of a graph to integers. Many graph
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module GraphMatching
4
4
  # > In .. graph theory, a matching .. in a graph is a set of
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module GraphMatching
4
4
  # An `OrderedSet` acts like a `Set`, but preserves insertion order.
@@ -1,8 +1,8 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  # no-doc
4
4
  module GraphMatching
5
5
  def self.gem_version
6
- ::Gem::Version.new('0.2.0')
6
+ ::Gem::Version.new('0.2.1')
7
7
  end
8
8
  end
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'open3'
4
4
  require 'rgl/rdot'
@@ -6,8 +6,8 @@ require 'rgl/rdot'
6
6
  module GraphMatching
7
7
  # Renders `GraphMatching::Graph` objects using `graphviz`.
8
8
  class Visualize
9
- TMP_DIR = '/tmp/graph_matching'.freeze
10
- USR_BIN_ENV = '/usr/bin/env'.freeze
9
+ TMP_DIR = '/tmp/graph_matching'
10
+ USR_BIN_ENV = '/usr/bin/env'
11
11
 
12
12
  attr_reader :graph
13
13
 
@@ -34,8 +34,8 @@ module GraphMatching
34
34
 
35
35
  def check_that_dot_is_installed
36
36
  return if dot_installed?
37
- $stderr.puts 'Executable not found: dot'
38
- $stderr.puts 'Please install graphviz'
37
+ warn 'Executable not found: dot'
38
+ warn 'Please install graphviz'
39
39
  exit(1)
40
40
  end
41
41
 
@@ -56,7 +56,7 @@ module GraphMatching
56
56
 
57
57
  def assert_usr_bin_env_exists
58
58
  return if File.exist?(USR_BIN_ENV)
59
- $stderr.puts "File not found: #{USR_BIN_ENV}"
59
+ warn "File not found: #{USR_BIN_ENV}"
60
60
  exit(1)
61
61
  end
62
62
 
@@ -85,8 +85,8 @@ module GraphMatching
85
85
  def write_png(abs_path)
86
86
  _so, se, st = Open3.capture3("dot -T png > #{abs_path}", stdin_data: dot)
87
87
  return if st.success?
88
- $stderr.puts 'Failed to generate .png'
89
- $stderr.puts se
88
+ warn 'Failed to generate .png'
89
+ warn se
90
90
  exit(1)
91
91
  end
92
92
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graph_matching
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jared Beck
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-16 00:00:00.000000000 Z
11
+ date: 2020-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rgl
@@ -25,89 +25,75 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.5.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: bundler
28
+ name: byebug
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.12'
33
+ version: '11.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.12'
41
- - !ruby/object:Gem::Dependency
42
- name: pry-byebug
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '3.4'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '3.4'
40
+ version: '11.0'
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: rake
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
45
  - - "~>"
60
46
  - !ruby/object:Gem::Version
61
- version: '12.0'
47
+ version: '12.3'
62
48
  type: :development
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
52
  - - "~>"
67
53
  - !ruby/object:Gem::Version
68
- version: '12.0'
54
+ version: '12.3'
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: rspec-core
71
57
  requirement: !ruby/object:Gem::Requirement
72
58
  requirements:
73
59
  - - "~>"
74
60
  - !ruby/object:Gem::Version
75
- version: '3.6'
61
+ version: '3.8'
76
62
  type: :development
77
63
  prerelease: false
78
64
  version_requirements: !ruby/object:Gem::Requirement
79
65
  requirements:
80
66
  - - "~>"
81
67
  - !ruby/object:Gem::Version
82
- version: '3.6'
68
+ version: '3.8'
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: rspec-expectations
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
73
  - - "~>"
88
74
  - !ruby/object:Gem::Version
89
- version: '3.6'
75
+ version: '3.8'
90
76
  type: :development
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
80
  - - "~>"
95
81
  - !ruby/object:Gem::Version
96
- version: '3.6'
82
+ version: '3.8'
97
83
  - !ruby/object:Gem::Dependency
98
84
  name: rspec-mocks
99
85
  requirement: !ruby/object:Gem::Requirement
100
86
  requirements:
101
87
  - - "~>"
102
88
  - !ruby/object:Gem::Version
103
- version: '3.6'
89
+ version: '3.8'
104
90
  type: :development
105
91
  prerelease: false
106
92
  version_requirements: !ruby/object:Gem::Requirement
107
93
  requirements:
108
94
  - - "~>"
109
95
  - !ruby/object:Gem::Version
110
- version: '3.6'
96
+ version: '3.8'
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: rubocop
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -181,8 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
167
  - !ruby/object:Gem::Version
182
168
  version: '0'
183
169
  requirements: []
184
- rubyforge_project:
185
- rubygems_version: 2.5.2.3
170
+ rubygems_version: 3.0.3
186
171
  signing_key:
187
172
  specification_version: 4
188
173
  summary: Finds maximum matchings in undirected graphs.