graph_matching 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.rubocop.yml +112 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +9 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +205 -0
  9. data/Rakefile +9 -0
  10. data/benchmark/mcm_bipartite/complete_bigraphs/benchmark.rb +33 -0
  11. data/benchmark/mcm_bipartite/complete_bigraphs/compare.gnuplot +19 -0
  12. data/benchmark/mcm_bipartite/complete_bigraphs/edges_times_vertexes.data +500 -0
  13. data/benchmark/mcm_bipartite/complete_bigraphs/plot.gnuplot +21 -0
  14. data/benchmark/mcm_bipartite/complete_bigraphs/plot.png +0 -0
  15. data/benchmark/mcm_bipartite/complete_bigraphs/time.data +499 -0
  16. data/benchmark/mcm_general/complete_graphs/benchmark.rb +30 -0
  17. data/benchmark/mcm_general/complete_graphs/plot.gnuplot +19 -0
  18. data/benchmark/mcm_general/complete_graphs/plot.png +0 -0
  19. data/benchmark/mcm_general/complete_graphs/time.data +499 -0
  20. data/benchmark/mcm_general/complete_graphs/v_cubed.data +500 -0
  21. data/benchmark/mwm_bipartite/complete_bigraphs/benchmark.rb +43 -0
  22. data/benchmark/mwm_bipartite/complete_bigraphs/nmN.data +499 -0
  23. data/benchmark/mwm_bipartite/complete_bigraphs/nmN.xlsx +0 -0
  24. data/benchmark/mwm_bipartite/complete_bigraphs/plot.gnuplot +22 -0
  25. data/benchmark/mwm_bipartite/complete_bigraphs/plot.png +0 -0
  26. data/benchmark/mwm_bipartite/complete_bigraphs/time.data +299 -0
  27. data/benchmark/mwm_bipartite/misc/calc_d2/benchmark.rb +29 -0
  28. data/benchmark/mwm_general/complete_graphs/benchmark.rb +32 -0
  29. data/benchmark/mwm_general/complete_graphs/compare.gnuplot +19 -0
  30. data/benchmark/mwm_general/complete_graphs/mn_log_n.data +299 -0
  31. data/benchmark/mwm_general/complete_graphs/mn_log_n.xlsx +0 -0
  32. data/benchmark/mwm_general/complete_graphs/plot.gnuplot +22 -0
  33. data/benchmark/mwm_general/complete_graphs/plot.png +0 -0
  34. data/benchmark/mwm_general/complete_graphs/time.data +299 -0
  35. data/benchmark/mwm_general/incomplete_graphs/benchmark.rb +39 -0
  36. data/benchmark/mwm_general/incomplete_graphs/plot.gnuplot +22 -0
  37. data/benchmark/mwm_general/incomplete_graphs/plot.png +0 -0
  38. data/benchmark/mwm_general/incomplete_graphs/time_10_pct.data +299 -0
  39. data/benchmark/mwm_general/incomplete_graphs/time_20_pct.data +299 -0
  40. data/benchmark/mwm_general/incomplete_graphs/time_30_pct.data +299 -0
  41. data/graph_matching.gemspec +35 -0
  42. data/lib/graph_matching.rb +15 -0
  43. data/lib/graph_matching/algorithm/matching_algorithm.rb +23 -0
  44. data/lib/graph_matching/algorithm/mcm_bipartite.rb +118 -0
  45. data/lib/graph_matching/algorithm/mcm_general.rb +289 -0
  46. data/lib/graph_matching/algorithm/mwm_bipartite.rb +147 -0
  47. data/lib/graph_matching/algorithm/mwm_general.rb +1086 -0
  48. data/lib/graph_matching/algorithm/mwmg_delta_assertions.rb +94 -0
  49. data/lib/graph_matching/assertion.rb +41 -0
  50. data/lib/graph_matching/core_ext/set.rb +36 -0
  51. data/lib/graph_matching/directed_edge_set.rb +31 -0
  52. data/lib/graph_matching/errors.rb +23 -0
  53. data/lib/graph_matching/graph/bigraph.rb +37 -0
  54. data/lib/graph_matching/graph/graph.rb +63 -0
  55. data/lib/graph_matching/graph/weighted.rb +112 -0
  56. data/lib/graph_matching/graph/weighted_bigraph.rb +17 -0
  57. data/lib/graph_matching/graph/weighted_graph.rb +17 -0
  58. data/lib/graph_matching/integer_vertexes.rb +29 -0
  59. data/lib/graph_matching/matching.rb +120 -0
  60. data/lib/graph_matching/ordered_set.rb +59 -0
  61. data/lib/graph_matching/version.rb +6 -0
  62. data/lib/graph_matching/visualize.rb +93 -0
  63. data/profile/mcm_bipartite/compare.sh +15 -0
  64. data/profile/mcm_bipartite/publish.sh +12 -0
  65. data/profile/mwm_general/compare.sh +15 -0
  66. data/profile/mwm_general/profile.rb +28 -0
  67. data/profile/mwm_general/publish.sh +12 -0
  68. data/research/1965_edmonds.pdf +0 -0
  69. data/research/1975_even_kariv.pdf +0 -0
  70. data/research/1976_gabow.pdf +0 -0
  71. data/research/1980_micali_vazirani.pdf +0 -0
  72. data/research/1985_gabow.pdf +0 -0
  73. data/research/2002_tarjan.pdf +0 -0
  74. data/research/2013_zwick.pdf +0 -0
  75. data/research/examples/unweighted_general/1.txt +86 -0
  76. data/research/goodwin.pdf +0 -0
  77. data/research/kavathekar-scribe.pdf +0 -0
  78. data/research/kusner.pdf +0 -0
  79. data/research/van_rantwijk/mwm_example.py +19 -0
  80. data/research/van_rantwijk/mwmatching.py +945 -0
  81. data/spec/graph_matching/algorithm/matching_algorithm_spec.rb +14 -0
  82. data/spec/graph_matching/algorithm/mcm_bipartite_spec.rb +98 -0
  83. data/spec/graph_matching/algorithm/mcm_general_spec.rb +159 -0
  84. data/spec/graph_matching/algorithm/mwm_bipartite_spec.rb +82 -0
  85. data/spec/graph_matching/algorithm/mwm_general_spec.rb +439 -0
  86. data/spec/graph_matching/graph/bigraph_spec.rb +73 -0
  87. data/spec/graph_matching/graph/graph_spec.rb +53 -0
  88. data/spec/graph_matching/graph/weighted_spec.rb +29 -0
  89. data/spec/graph_matching/integer_vertexes_spec.rb +21 -0
  90. data/spec/graph_matching/matching_spec.rb +89 -0
  91. data/spec/graph_matching/visualize_spec.rb +38 -0
  92. data/spec/graph_matching_spec.rb +9 -0
  93. data/spec/spec_helper.rb +26 -0
  94. metadata +263 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2224cf0e34e3cc897fa1e0821db9f74ddc7f1c75
4
+ data.tar.gz: 3acc5640fc7c25a56526503c07cb07ecfe6e6762
5
+ SHA512:
6
+ metadata.gz: 6111293c87bcc34728de5324892c2ef84d0d0e74c88ede76ac299daf95192988541708c2872ceb853502a658490ff695688c2a55318f4e7a3932f90df75e60d8
7
+ data.tar.gz: 27827741f5b04a39d209fdf90970667fafc70c23f434d735593d866e6fdaeb4b352cba37c4dd4d50dec5e0b63bac0d574622f906ee274a04a2ebc7c12f691d81
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ *.pyc
4
+ .bundle
5
+ .config
6
+ .idea
7
+ .yardoc
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
20
+ .DS_Store
@@ -0,0 +1,112 @@
1
+ # Use `rubocop --display-cop-names` and consult
2
+ # https://github.com/bbatsov/rubocop/blob/master/config/default.yml
3
+ # for options.
4
+
5
+ # > Literal true appeared in a condition.
6
+ # The `while do break` loop is not my favorite type of loop
7
+ # either, but it's a valid technique and shouldn't be a lint
8
+ # error. At worst, it should be a style recommendation.
9
+ # Finally, there is a `loop do .. end` alternative to `while true`
10
+ # but it's nearly 3x slower. (https://www.ruby-forum.com/topic/179264)
11
+ Lint/LiteralInCondition:
12
+ Enabled: false
13
+
14
+ # TODO: Resolve, then increase severity
15
+ Metrics/AbcSize:
16
+ Severity: refactor
17
+
18
+ # TODO: Resolve, then increase severity
19
+ Metrics/CyclomaticComplexity:
20
+ Severity: refactor
21
+
22
+ Metrics/LineLength:
23
+ Max: 100 # TODO: Reduce to 80
24
+
25
+ # TODO: Resolve, then increase severity
26
+ Metrics/MethodLength:
27
+ Severity: refactor
28
+
29
+ # TODO: Resolve, then increase severity
30
+ Metrics/PerceivedComplexity:
31
+ Severity: refactor
32
+
33
+ # Besides being racist, this also prevents the use of mathematical
34
+ # symbols like π. We're using utf-8 for a reason, c'mon.
35
+ Style/AsciiComments:
36
+ Enabled: false
37
+
38
+ # Block style should express the presence or absence of
39
+ # side-effects, not the length of the block.
40
+ Style/Blocks:
41
+ Enabled: false
42
+
43
+ # An empty else clause is a good place to put comments explaining
44
+ # a no-op.
45
+ Style/EmptyElse:
46
+ Enabled: false
47
+
48
+ # We can't say, in all cases that a guard clause is more
49
+ # readable. It should be left to the discretion of the
50
+ # programmer.
51
+ Style/GuardClause:
52
+ Enabled: false
53
+
54
+ # > Favor modifier if usage when having a single-line body.
55
+ # Yes, but there are still times, even with very short lines,
56
+ # where a multi-line conditional is more readable. Should
57
+ # be left to the discretion of the programmer.
58
+ Style/IfUnlessModifier:
59
+ Enabled: false
60
+
61
+ # Normally I'd agree, but `loop` is nearly 3x slower, so we can't
62
+ # use it in this performance-sensitive application.
63
+ # (https://www.ruby-forum.com/topic/179264)
64
+ Style/InfiniteLoop:
65
+ Enabled: false
66
+
67
+ # > Align the operands of a condition in an unless statement
68
+ # > spanning multiple lines.
69
+ # This kind of style recommendation leads to too much mind-numbing
70
+ # text shuffling. It's not worth the "whitespace maintenance".
71
+ Style/MultilineOperationIndentation:
72
+ Enabled: false
73
+
74
+ # > Use next to skip iteration.
75
+ # I agree, but this cop produces false positives.
76
+ Style/Next:
77
+ Enabled: false
78
+
79
+ # Normally, I'd agree, but `nil?` is actually a tiny bit slower,
80
+ # and that matters when implementing algorithms.
81
+ Style/NilComparison:
82
+ Enabled: false
83
+
84
+ # String literal quoting has no impact on performance or
85
+ # legibility.
86
+ Style/StringLiterals:
87
+ Enabled: false
88
+
89
+ # Percent-literal delimiters should express the content
90
+ # of the literal, for example using square braces in `%w[]` to
91
+ # indicate an array.
92
+ Style/PercentLiteralDelimiters:
93
+ Enabled: false
94
+
95
+ # > The RedundantReturn cop doesn't allow you to specify a return
96
+ # > statement as the last line. But if the point is to return
97
+ # > several values, I think return a, b, reads better than [a, b]
98
+ # > https://github.com/bbatsov/rubocop/issues/528
99
+ Style/RedundantReturn:
100
+ AllowMultipleReturnValues: true
101
+
102
+ # Use space inside range literals.
103
+ # Bad: `(a..b - 1)`
104
+ # Good: `(a .. b - 1)`
105
+ # All other binary operators in the language (`+`, `<<`) have
106
+ # spaces around them, so `..` and `...` should too.
107
+ Style/SpaceInsideRangeLiteral:
108
+ Enabled: false
109
+
110
+ # Disagree. Indentation of loops is an important visual clue.
111
+ Style/WhileUntilModifier:
112
+ Enabled: false
@@ -0,0 +1 @@
1
+ 2.2.0
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3-p551"
4
+ - "2.0.0-p598"
5
+ - "2.1.5"
6
+ - "2.2.0"
7
+ script: bundle exec rspec spec
8
+ notifications:
9
+ email: false
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in graph_matching.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Jared Beck
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,205 @@
1
+ GraphMatching
2
+ =============
3
+
4
+ Efficient algorithms for **maximum cardinality** and
5
+ **maximum weighted** [matchings][6] in undirected [graphs][7].
6
+ Uses the [Ruby Graph Library (RGL)][4].
7
+
8
+ [![Build Status][20]][23]
9
+ [![Code Climate][22]][21]
10
+
11
+ Algorithms
12
+ ----------
13
+
14
+ This library implements the four algorithms described by Galil (1986).
15
+
16
+ ### 1. Maximum Cardinality Matching in Bipartite Graphs
17
+
18
+ Uses the [Augmenting Path][5] algorithm, which performs in O(e * v)
19
+ where e is the number of edges, and v, the number of vertexes ([benchmark][14]).
20
+
21
+ ```ruby
22
+ require 'graph_matching'
23
+ g = GraphMatching::Graph::Bigraph[1,3, 1,4, 2,3]
24
+ m = g.maximum_cardinality_matching
25
+ m.edges
26
+ #=> [[4, 1], [3, 2]]
27
+ ```
28
+
29
+ ![MCM is O(e * v)][17]
30
+
31
+ See [Benchmarking MCM in Complete Bigraphs][14]
32
+
33
+ TO DO: This algorithm is inefficient compared to the [Hopcroft-Karp algorithm][13]
34
+ which performs in O(e * sqrt(v)) in the worst case.
35
+
36
+ ### 2. Maximum Cardinality Matching in General Graphs
37
+
38
+ Uses Gabow (1976) which performs in O(n^3).
39
+
40
+ ```ruby
41
+ require 'graph_matching'
42
+ g = GraphMatching::Graph::Graph[1,2, 1,3, 1,4, 2,3, 2,4, 3,4]
43
+ m = g.maximum_cardinality_matching
44
+ m.edges
45
+ #=> [[2, 1], [4, 3]]
46
+ ```
47
+
48
+ ![MCM is O(v ^ 3)][18]
49
+
50
+ See [Benchmarking MCM in Complete Graphs][15]
51
+
52
+ Gabow (1976) is not the fastest algorithm, but it is "one exponent
53
+ faster" than the original, [Edmonds' blossom algorithm][9], which
54
+ performs in O(n^4).
55
+
56
+ Faster algorithms include Even-Kariv (1975) and Micali-Vazirani (1980).
57
+ Galil (1986) describes the latter as "a simpler approach".
58
+
59
+ ### 3. Maximum Weighted Matching in Bipartite Graphs
60
+
61
+ Uses the [Augmenting Path][5] algorithm from Maximum Cardinality
62
+ Matching, with the "scaling" approach described by Gabow (1983)
63
+ and Galil (1986), which performs in O(n ^ (3/4) m log N).
64
+
65
+ ```ruby
66
+ require 'graph_matching'
67
+ g = GraphMatching::Graph::WeightedGraph[
68
+ [1, 2, 10],
69
+ [1, 3, 11]
70
+ ]
71
+ m = g.maximum_weighted_matching
72
+ m.edges
73
+ #=> [[3, 1]]
74
+ m.weight(g)
75
+ #=> 11
76
+ ```
77
+
78
+ ![MWM is O(n ^ (3/4) m log N)][19]
79
+
80
+ See [Benchmarking MWM in Complete Bigraphs][16]
81
+
82
+ ### 4. Maximum Weighted Matching in General Graphs
83
+
84
+ A direct port of [Van Rantwijk's][11] implementation in python,
85
+ while referring to Gabow (1985) and Galil (1986) for the big
86
+ picture.
87
+
88
+ Unlike the other algorithms above,
89
+ `WeightedGraph#maximum_weighted_matching` takes an argument,
90
+ `max_cardinality`. If true, only maximum cardinality matchings
91
+ will be considered.
92
+
93
+ ```ruby
94
+ require 'graph_matching'
95
+ g = GraphMatching::Graph::WeightedGraph[
96
+ [1, 2, 10],
97
+ [1, 3, 11]
98
+ ]
99
+ m = g.maximum_weighted_matching(false)
100
+ m.edges
101
+ #=> [[3, 1]]
102
+ m.weight(g)
103
+ #=> 11
104
+ ```
105
+
106
+ The algorithm performs in O(mn log n) as described by
107
+ Galil (1986) p. 34.
108
+
109
+ ![MWM is O(mn log n)][26]
110
+
111
+ See [Benchmarking MWM in Complete Graphs][25]
112
+
113
+ Limitations
114
+ -----------
115
+
116
+ All vertexes in a `Graph` must be consecutive positive nonzero
117
+ integers. This simplifies many algorithms. For your convenience,
118
+ a module (`GraphMatching::IntegerVertexes`) is provided to convert
119
+ the vertexes of any `RGL::MutableGraph` to integers.
120
+
121
+ ```ruby
122
+ require 'graph_matching'
123
+ require 'graph_matching/integer_vertexes'
124
+ g1 = RGL::AdjacencyGraph['a', 'b']
125
+ g2, legend = GraphMatching::IntegerVertexes.to_integers(g1)
126
+ g2.vertices
127
+ #=> [1, 2]
128
+ legend
129
+ #=> {1=>"a", 2=>"b"}
130
+ ```
131
+
132
+ Troubleshooting
133
+ ---------------
134
+
135
+ * If you have [graphviz][24] installed, calling `#print` on
136
+ any `GraphMatching::Graph` will write a `png` to `/tmp` and
137
+ `open` it.
138
+
139
+ Glossary
140
+ --------
141
+
142
+ - [Bipartite Graph][3] (bigraph)
143
+ - [Graph][7]
144
+ - [Matching][6]
145
+
146
+ References
147
+ ----------
148
+
149
+ - Edmonds, J. (1965). Paths, trees, and flowers. *Canadian Journal
150
+ of Mathematics*.
151
+ - Even, S. and Kariv, O. (1975). An O(n^2.5) Algorithm for Maximum
152
+ Matching in General Graphs. *Proceedings of the 16th Annual IEEE
153
+ Symposium on Foundations of Computer Science*. IEEE, New York, pp. 100-112
154
+ - Kusner, M. [Edmonds's Blossom Algorithm (pdf)][12]
155
+ - Gabow, H. J. (1973). Implementation of algorithms for maximum
156
+ matching on nonbipartite graphs, Stanford Ph.D thesis.
157
+ - Gabow, H. N. (1976). An Efficient Implementation of Edmonds'
158
+ Algorithm for Maximum Matching on Graphs. *Journal of the Association
159
+ for Computing Machinery*, Vol. 23, No. 2, pp. 221-234
160
+ - Gabow, H. N. (1983). Scaling algorithms for network problems.
161
+ *Proceedings of the 24th Annual IEEE Symposium on Foundations of
162
+ Computer Science*. IEEE, New York, pp. 248-257
163
+ - Gabow, H. N. (1985). A scaling algorithm for weighted matching on
164
+ general graphs. *Proceedings of the 26th Annual IEEE Symposium on
165
+ Foundations of Computer Science*. IEEE, New York, pp. 90-100
166
+ - Galil, Z. (1986). Efficient algorithms for finding maximum
167
+ matching in graphs. *ACM Computing Surveys*. Vol. 18, No. 1, pp. 23-38
168
+ - Micali, S., and Vazirani, V. (1980). An O(e * sqrt(v)) Algorithm for
169
+ finding maximal matching in general graphs. *Proceedings of the 21st
170
+ Annual IEEE Symposium on Foundations of Computer Science*.
171
+ IEEE, New York, pp. 17-27
172
+ - Van Rantwijk, J. (2013) [Maximum Weighted Matching][11]
173
+ - [Stolee, D.][8]
174
+ - [The Augmenting Path Algorithm for Bipartite Matching][1]
175
+ - [The Augmenting Path Algorithm (Example)][2]
176
+ - West, D. B. (2001). *Introduction to graph theory*. Prentice Hall. p. 142
177
+ - Zwick, U. (2013). [Lecture notes on: Maximum matching in bipartite
178
+ and non-bipartite graphs (pdf)][10]
179
+
180
+ [1]: http://www.youtube.com/watch?v=ory4WMX0rDU "The Augmenting Path Algorithm for Bipartite Matching"
181
+ [2]: http://www.youtube.com/watch?v=C9c8zEZXboA "The Augmenting Path Algorithm (Example)"
182
+ [3]: http://en.wikipedia.org/wiki/Bipartite_graph
183
+ [4]: http://rgl.rubyforge.org/rgl/index.html
184
+ [5]: http://en.wikipedia.org/wiki/Matching_%28graph_theory%29#In_unweighted_bipartite_graphs
185
+ [6]: http://en.wikipedia.org/wiki/Matching_%28graph_theory%29
186
+ [7]: http://en.wikipedia.org/wiki/Graph_theory
187
+ [8]: http://www.math.uiuc.edu/~stolee/
188
+ [9]: http://en.wikipedia.org/wiki/Blossom_algorithm
189
+ [10]: http://www.cs.tau.ac.il/~zwick/grad-algo-13/match.pdf
190
+ [11]: http://jorisvr.nl/maximummatching.html
191
+ [12]: http://matthewkusner.com/MatthewKusner_BlossomAlgorithmReport.pdf
192
+ [13]: http://en.wikipedia.org/wiki/Hopcroft%E2%80%93Karp_algorithm
193
+ [14]: https://github.com/jaredbeck/graph_matching/wiki/Benchmarking-MCM-in-Complete-Bigraphs
194
+ [15]: https://github.com/jaredbeck/graph_matching/wiki/Benchmarking-MCM-in-Complete-Graphs
195
+ [16]: https://github.com/jaredbeck/graph_matching/wiki/Benchmarking-MWM-in-Complete-Bigraphs
196
+ [17]: https://github.com/jaredbeck/graph_matching/blob/master/benchmark/mcm_bipartite/complete_bigraphs/plot.png
197
+ [18]: https://github.com/jaredbeck/graph_matching/blob/master/benchmark/mcm_general/complete_graphs/plot.png
198
+ [19]: https://github.com/jaredbeck/graph_matching/blob/master/benchmark/mwm_bipartite/complete_bigraphs/plot.png
199
+ [20]: https://travis-ci.org/jaredbeck/graph_matching.svg?branch=master
200
+ [21]: https://codeclimate.com/github/jaredbeck/graph_matching
201
+ [22]: https://codeclimate.com/github/jaredbeck/graph_matching/badges/gpa.svg
202
+ [23]: https://travis-ci.org/jaredbeck/graph_matching/builds
203
+ [24]: http://www.graphviz.org/
204
+ [25]: https://github.com/jaredbeck/graph_matching/wiki/Benchmarking-MWM-in-Complete-Graphs
205
+ [26]: https://github.com/jaredbeck/graph_matching/blob/master/benchmark/mwm_general/complete_graphs/plot.png
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require 'rubocop/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new
7
+
8
+ # TODO: add rubocop as a prerequisite once it's passing.
9
+ task :default => [:spec]
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ # No shebang here. Usage:
4
+ # BM_DIR='benchmark/mcm_bipartite/complete_bigraphs'
5
+ # ruby -I lib "$BM_DIR/benchmark.rb" > "$BM_DIR/time.data"
6
+
7
+ require 'benchmark'
8
+ require 'graph_matching'
9
+
10
+ MIN_SIZE = 2
11
+ MAX_SIZE = 500
12
+
13
+ $stdout.sync = true
14
+
15
+ def complete_bigraph(n)
16
+ g = GraphMatching::Graph::Bigraph.new
17
+ max_u = (n.to_f / 2).ceil
18
+ min_v = max_u + 1
19
+ 1.upto(max_u) do |i|
20
+ min_v.upto(n) do |j|
21
+ g.add_edge(i, j)
22
+ end
23
+ end
24
+ g
25
+ end
26
+
27
+ MIN_SIZE.upto(MAX_SIZE) do |v|
28
+ print "%5d\t" % [v]
29
+ g = complete_bigraph(v)
30
+ GC.disable
31
+ puts Benchmark.realtime { g.maximum_cardinality_matching }
32
+ GC.enable
33
+ end
@@ -0,0 +1,19 @@
1
+ data_dir = "~/git/jaredbeck/graph_matching/benchmark/mcm_bipartite/complete_bigraphs"
2
+
3
+ set title "MCM in Complete Bigraph"
4
+ set key left box
5
+ set term png size 800, 500
6
+ set output data_dir."/plot_compare.png"
7
+
8
+ set linetype 1 pointtype 7 linecolor rgb "#FF0000"
9
+ set linetype 2 pointtype 7 linecolor rgb "#00B800"
10
+
11
+ set xlabel 'Number of Vertexes (n)' textcolor rgb "black"
12
+ set ytics autofreq textcolor rgb "black"
13
+ set ylabel 'Time (s)' textcolor rgb "black"
14
+
15
+ plot \
16
+ data_dir."/time.data" \
17
+ using 1:2 title "Before" lt 1 axes x1y1, \
18
+ data_dir."/time2.data" \
19
+ using 1:2 title "After" lt 2 axes x1y1