graph_matching 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.rubocop.yml +112 -0
- data/.ruby-version +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +205 -0
- data/Rakefile +9 -0
- data/benchmark/mcm_bipartite/complete_bigraphs/benchmark.rb +33 -0
- data/benchmark/mcm_bipartite/complete_bigraphs/compare.gnuplot +19 -0
- data/benchmark/mcm_bipartite/complete_bigraphs/edges_times_vertexes.data +500 -0
- data/benchmark/mcm_bipartite/complete_bigraphs/plot.gnuplot +21 -0
- data/benchmark/mcm_bipartite/complete_bigraphs/plot.png +0 -0
- data/benchmark/mcm_bipartite/complete_bigraphs/time.data +499 -0
- data/benchmark/mcm_general/complete_graphs/benchmark.rb +30 -0
- data/benchmark/mcm_general/complete_graphs/plot.gnuplot +19 -0
- data/benchmark/mcm_general/complete_graphs/plot.png +0 -0
- data/benchmark/mcm_general/complete_graphs/time.data +499 -0
- data/benchmark/mcm_general/complete_graphs/v_cubed.data +500 -0
- data/benchmark/mwm_bipartite/complete_bigraphs/benchmark.rb +43 -0
- data/benchmark/mwm_bipartite/complete_bigraphs/nmN.data +499 -0
- data/benchmark/mwm_bipartite/complete_bigraphs/nmN.xlsx +0 -0
- data/benchmark/mwm_bipartite/complete_bigraphs/plot.gnuplot +22 -0
- data/benchmark/mwm_bipartite/complete_bigraphs/plot.png +0 -0
- data/benchmark/mwm_bipartite/complete_bigraphs/time.data +299 -0
- data/benchmark/mwm_bipartite/misc/calc_d2/benchmark.rb +29 -0
- data/benchmark/mwm_general/complete_graphs/benchmark.rb +32 -0
- data/benchmark/mwm_general/complete_graphs/compare.gnuplot +19 -0
- data/benchmark/mwm_general/complete_graphs/mn_log_n.data +299 -0
- data/benchmark/mwm_general/complete_graphs/mn_log_n.xlsx +0 -0
- data/benchmark/mwm_general/complete_graphs/plot.gnuplot +22 -0
- data/benchmark/mwm_general/complete_graphs/plot.png +0 -0
- data/benchmark/mwm_general/complete_graphs/time.data +299 -0
- data/benchmark/mwm_general/incomplete_graphs/benchmark.rb +39 -0
- data/benchmark/mwm_general/incomplete_graphs/plot.gnuplot +22 -0
- data/benchmark/mwm_general/incomplete_graphs/plot.png +0 -0
- data/benchmark/mwm_general/incomplete_graphs/time_10_pct.data +299 -0
- data/benchmark/mwm_general/incomplete_graphs/time_20_pct.data +299 -0
- data/benchmark/mwm_general/incomplete_graphs/time_30_pct.data +299 -0
- data/graph_matching.gemspec +35 -0
- data/lib/graph_matching.rb +15 -0
- data/lib/graph_matching/algorithm/matching_algorithm.rb +23 -0
- data/lib/graph_matching/algorithm/mcm_bipartite.rb +118 -0
- data/lib/graph_matching/algorithm/mcm_general.rb +289 -0
- data/lib/graph_matching/algorithm/mwm_bipartite.rb +147 -0
- data/lib/graph_matching/algorithm/mwm_general.rb +1086 -0
- data/lib/graph_matching/algorithm/mwmg_delta_assertions.rb +94 -0
- data/lib/graph_matching/assertion.rb +41 -0
- data/lib/graph_matching/core_ext/set.rb +36 -0
- data/lib/graph_matching/directed_edge_set.rb +31 -0
- data/lib/graph_matching/errors.rb +23 -0
- data/lib/graph_matching/graph/bigraph.rb +37 -0
- data/lib/graph_matching/graph/graph.rb +63 -0
- data/lib/graph_matching/graph/weighted.rb +112 -0
- data/lib/graph_matching/graph/weighted_bigraph.rb +17 -0
- data/lib/graph_matching/graph/weighted_graph.rb +17 -0
- data/lib/graph_matching/integer_vertexes.rb +29 -0
- data/lib/graph_matching/matching.rb +120 -0
- data/lib/graph_matching/ordered_set.rb +59 -0
- data/lib/graph_matching/version.rb +6 -0
- data/lib/graph_matching/visualize.rb +93 -0
- data/profile/mcm_bipartite/compare.sh +15 -0
- data/profile/mcm_bipartite/publish.sh +12 -0
- data/profile/mwm_general/compare.sh +15 -0
- data/profile/mwm_general/profile.rb +28 -0
- data/profile/mwm_general/publish.sh +12 -0
- data/research/1965_edmonds.pdf +0 -0
- data/research/1975_even_kariv.pdf +0 -0
- data/research/1976_gabow.pdf +0 -0
- data/research/1980_micali_vazirani.pdf +0 -0
- data/research/1985_gabow.pdf +0 -0
- data/research/2002_tarjan.pdf +0 -0
- data/research/2013_zwick.pdf +0 -0
- data/research/examples/unweighted_general/1.txt +86 -0
- data/research/goodwin.pdf +0 -0
- data/research/kavathekar-scribe.pdf +0 -0
- data/research/kusner.pdf +0 -0
- data/research/van_rantwijk/mwm_example.py +19 -0
- data/research/van_rantwijk/mwmatching.py +945 -0
- data/spec/graph_matching/algorithm/matching_algorithm_spec.rb +14 -0
- data/spec/graph_matching/algorithm/mcm_bipartite_spec.rb +98 -0
- data/spec/graph_matching/algorithm/mcm_general_spec.rb +159 -0
- data/spec/graph_matching/algorithm/mwm_bipartite_spec.rb +82 -0
- data/spec/graph_matching/algorithm/mwm_general_spec.rb +439 -0
- data/spec/graph_matching/graph/bigraph_spec.rb +73 -0
- data/spec/graph_matching/graph/graph_spec.rb +53 -0
- data/spec/graph_matching/graph/weighted_spec.rb +29 -0
- data/spec/graph_matching/integer_vertexes_spec.rb +21 -0
- data/spec/graph_matching/matching_spec.rb +89 -0
- data/spec/graph_matching/visualize_spec.rb +38 -0
- data/spec/graph_matching_spec.rb +9 -0
- data/spec/spec_helper.rb +26 -0
- metadata +263 -0
checksums.yaml
ADDED
@@ -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
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -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
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.0
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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
|
data/Rakefile
ADDED
@@ -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
|