graph_matching 0.2.0 → 0.2.1

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