graph_matching 0.0.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 +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
|