graph_matching 0.1.0 → 0.1.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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/graph_matching.gemspec +13 -11
  4. data/lib/graph_matching/version.rb +1 -1
  5. metadata +2 -77
  6. data/benchmark/mcm_bipartite/complete_bigraphs/benchmark.rb +0 -33
  7. data/benchmark/mcm_bipartite/complete_bigraphs/compare.gnuplot +0 -19
  8. data/benchmark/mcm_bipartite/complete_bigraphs/edges_times_vertexes.data +0 -500
  9. data/benchmark/mcm_bipartite/complete_bigraphs/plot.gnuplot +0 -21
  10. data/benchmark/mcm_bipartite/complete_bigraphs/plot.png +0 -0
  11. data/benchmark/mcm_bipartite/complete_bigraphs/time.data +0 -499
  12. data/benchmark/mcm_general/complete_graphs/benchmark.rb +0 -30
  13. data/benchmark/mcm_general/complete_graphs/plot.gnuplot +0 -19
  14. data/benchmark/mcm_general/complete_graphs/plot.png +0 -0
  15. data/benchmark/mcm_general/complete_graphs/time.data +0 -499
  16. data/benchmark/mcm_general/complete_graphs/v_cubed.data +0 -500
  17. data/benchmark/mwm_bipartite/complete_bigraphs/benchmark.rb +0 -43
  18. data/benchmark/mwm_bipartite/complete_bigraphs/nmN.data +0 -499
  19. data/benchmark/mwm_bipartite/complete_bigraphs/nmN.xlsx +0 -0
  20. data/benchmark/mwm_bipartite/complete_bigraphs/plot.gnuplot +0 -22
  21. data/benchmark/mwm_bipartite/complete_bigraphs/plot.png +0 -0
  22. data/benchmark/mwm_bipartite/complete_bigraphs/time.data +0 -299
  23. data/benchmark/mwm_bipartite/misc/calc_d2/benchmark.rb +0 -25
  24. data/benchmark/mwm_general/complete_graphs/benchmark.rb +0 -32
  25. data/benchmark/mwm_general/complete_graphs/compare.gnuplot +0 -19
  26. data/benchmark/mwm_general/complete_graphs/mn_log_n.data +0 -299
  27. data/benchmark/mwm_general/complete_graphs/mn_log_n.xlsx +0 -0
  28. data/benchmark/mwm_general/complete_graphs/plot.gnuplot +0 -22
  29. data/benchmark/mwm_general/complete_graphs/plot.png +0 -0
  30. data/benchmark/mwm_general/complete_graphs/time.data +0 -299
  31. data/benchmark/mwm_general/incomplete_graphs/benchmark.rb +0 -38
  32. data/benchmark/mwm_general/incomplete_graphs/plot.gnuplot +0 -22
  33. data/benchmark/mwm_general/incomplete_graphs/plot.png +0 -0
  34. data/benchmark/mwm_general/incomplete_graphs/time_10_pct.data +0 -299
  35. data/benchmark/mwm_general/incomplete_graphs/time_20_pct.data +0 -299
  36. data/benchmark/mwm_general/incomplete_graphs/time_30_pct.data +0 -299
  37. data/profile/mcm_bipartite/compare.sh +0 -15
  38. data/profile/mcm_bipartite/publish.sh +0 -12
  39. data/profile/mwm_general/compare.sh +0 -15
  40. data/profile/mwm_general/profile.rb +0 -28
  41. data/profile/mwm_general/publish.sh +0 -12
  42. data/research/1965_edmonds.pdf +0 -0
  43. data/research/1975_even_kariv.pdf +0 -0
  44. data/research/1976_gabow.pdf +0 -0
  45. data/research/1980_micali_vazirani.pdf +0 -0
  46. data/research/1985_gabow.pdf +0 -0
  47. data/research/2002_tarjan.pdf +0 -0
  48. data/research/2013_zwick.pdf +0 -0
  49. data/research/examples/unweighted_general/1.txt +0 -86
  50. data/research/goodwin.pdf +0 -0
  51. data/research/kavathekar-scribe.pdf +0 -0
  52. data/research/kusner.pdf +0 -0
  53. data/research/van_rantwijk/mwm_example.py +0 -19
  54. data/research/van_rantwijk/mwmatching.py +0 -945
  55. data/spec/graph_matching/algorithm/matching_algorithm_spec.rb +0 -14
  56. data/spec/graph_matching/algorithm/mcm_bipartite_spec.rb +0 -98
  57. data/spec/graph_matching/algorithm/mcm_general_spec.rb +0 -159
  58. data/spec/graph_matching/algorithm/mwm_bipartite_spec.rb +0 -82
  59. data/spec/graph_matching/algorithm/mwm_general_spec.rb +0 -442
  60. data/spec/graph_matching/graph/bigraph_spec.rb +0 -73
  61. data/spec/graph_matching/graph/graph_spec.rb +0 -53
  62. data/spec/graph_matching/graph/weighted_spec.rb +0 -29
  63. data/spec/graph_matching/integer_vertexes_spec.rb +0 -21
  64. data/spec/graph_matching/matching_spec.rb +0 -89
  65. data/spec/graph_matching/visualize_spec.rb +0 -38
  66. data/spec/graph_matching_spec.rb +0 -9
  67. data/spec/spec_helper.rb +0 -26
@@ -1,14 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe GraphMatching::Algorithm::MatchingAlgorithm do
6
- let(:algorithm) { described_class.new(double) }
7
-
8
- describe '#assert' do
9
- it 'returns an Assertion' do
10
- expect(algorithm.assert('banana')).to \
11
- be_a(GraphMatching::Assertion)
12
- end
13
- end
14
- end
@@ -1,98 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe GraphMatching::Algorithm::MCMBipartite do
6
- let(:g) { GraphMatching::Graph::Bigraph.new }
7
-
8
- describe '.new' do
9
- it 'requires a Bigraph' do
10
- expect { described_class.new('banana') }.to raise_error(TypeError)
11
- end
12
- end
13
-
14
- describe '#augment' do
15
- it 'augments the matching' do
16
- mcm = described_class.new(g)
17
- m = [nil, nil, 3, 2]
18
- m = mcm.send(:augment, m, [1, 2, 3, 4])
19
- expect(m).to eq([nil, 2, 1, 4, 3])
20
- m = mcm.send(:augment, m, [1, 2, 4, 5, 6, 7])
21
- expect(m).to eq([nil, 2, 1, nil, 5, 4, 7, 6])
22
- end
23
- end
24
-
25
- describe '#match' do
26
- context 'empty graph' do
27
- it 'returns empty set' do
28
- m = described_class.new(g).match
29
- expect(m).to be_empty
30
- end
31
- end
32
-
33
- context 'single vertex' do
34
- it 'returns empty set' do
35
- g.add_vertex(0)
36
- expect(described_class.new(g).match).to be_empty
37
- end
38
- end
39
-
40
- context 'single edge' do
41
- it 'returns set with one edge' do
42
- e = [1, 2]
43
- g.add_edge(*e)
44
- m = described_class.new(g).match
45
- expect(m.size).to eq(1)
46
- expect(m.edge?(e)).to eq(true)
47
- end
48
- end
49
-
50
- context 'complete bigraph with four vertexes' do
51
- let(:edges) { [[1, 3], [1, 4], [2, 3], [2, 4]] }
52
-
53
- it 'returns one of the two correct results' do
54
- edges.each { |e| g.add_edge(*e) }
55
- m = described_class.new(g).match
56
- expect(m.size).to eq(2)
57
- outcomes = [
58
- RGL::AdjacencyGraph[1, 3, 2, 4],
59
- RGL::AdjacencyGraph[1, 4, 2, 3]
60
- ]
61
- reconstructed = RGL::AdjacencyGraph.new
62
- m.to_a.each { |edge| reconstructed.add_edge(*edge) }
63
- expect(outcomes).to include(reconstructed)
64
- end
65
- end
66
-
67
- # The following example is by Derrick Stolee
68
- # http://www.youtube.com/watch?v=C9c8zEZXboA
69
- context 'incomplete bigraph with twelve vertexes' do
70
- let(:edges) {
71
- [
72
- [1, 8],
73
- [2, 9], [2, 10],
74
- [3, 7], [3, 9], [3, 12],
75
- [4, 8], [4, 10],
76
- [5, 10], [5, 11],
77
- [6, 11]
78
- ]
79
- }
80
-
81
- it 'returns one of the five correct results' do
82
- edges.each { |e| g.add_edge(*e) }
83
- m = described_class.new(g).match
84
- expect(m.size).to eq(5)
85
- outcomes = [
86
- RGL::AdjacencyGraph[1, 8, 2, 9, 3, 7, 5, 10, 6, 11],
87
- RGL::AdjacencyGraph[1, 8, 2, 9, 3, 7, 4, 10, 5, 11],
88
- RGL::AdjacencyGraph[1, 8, 2, 9, 3, 7, 4, 10, 6, 11],
89
- RGL::AdjacencyGraph[1, 8, 2, 9, 3, 12, 4, 10, 5, 11],
90
- RGL::AdjacencyGraph[2, 9, 3, 7, 4, 8, 5, 10, 6, 11]
91
- ]
92
- reconstructed = RGL::AdjacencyGraph.new
93
- m.to_a.each { |edge| reconstructed.add_edge(*edge) }
94
- expect(outcomes).to include(reconstructed)
95
- end
96
- end
97
- end
98
- end
@@ -1,159 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe GraphMatching::Algorithm::MCMGeneral do
6
- let(:graph_class) { GraphMatching::Graph::Graph }
7
- let(:g) { graph_class.new }
8
-
9
- describe '.new' do
10
- it 'requires a Graph' do
11
- expect { described_class.new('banana') }.to raise_error(TypeError)
12
- end
13
- end
14
-
15
- describe '#match' do
16
- def complete_graph(n)
17
- g = graph_class.new
18
- 1.upto(n - 1) do |i|
19
- (i + 1).upto(n) do |j|
20
- g.add_edge(i, j)
21
- end
22
- end
23
- g
24
- end
25
-
26
- context 'empty graph' do
27
- it 'returns empty set' do
28
- expect(described_class.new(g).match).to be_empty
29
- end
30
- end
31
-
32
- context 'single vertex' do
33
- it 'returns empty set' do
34
- g.add_vertex(1)
35
- expect(described_class.new(g).match).to be_empty
36
- end
37
- end
38
-
39
- context 'two vertexes' do
40
- let(:g) { graph_class[1, 2] }
41
-
42
- it 'returns one edge' do
43
- m = described_class.new(g).match
44
- expect(m.size).to eq(1)
45
- expect(m).to match_edges [[1, 2]]
46
- end
47
- end
48
-
49
- context 'complete graph with four vertexes' do
50
- it 'returns two disjoint edges' do
51
- g = graph_class[
52
- 1, 2,
53
- 1, 3,
54
- 1, 4,
55
- 2, 3,
56
- 2, 4,
57
- 3, 4
58
- ]
59
- m = described_class.new(g).match
60
- expect(m.size).to eq(2)
61
- expect(m.vertexes).to match_array([1, 2, 3, 4])
62
- end
63
- end
64
-
65
- context 'graph with stem (123) and blossom (456)' do
66
- it 'returns an expected result' do
67
- g = graph_class[
68
- 1, 2,
69
- 2, 3,
70
- 3, 4,
71
- 4, 5,
72
- 5, 6,
73
- 6, 4
74
- ]
75
- m = described_class.new(g).match
76
- expect(m.size).to eq(3)
77
- expect(m).to match_edges [[1, 2], [3, 4], [5, 6]]
78
- end
79
- end
80
-
81
- # TODO: Other algorithms (e.g. both MWM) support disconnected
82
- # graphs. MCM General should too.
83
- context 'disconnected graph' do
84
- it 'raises a DisconnectedGraph error' do
85
- 2.times { g.add_vertex(double) }
86
- expect { described_class.new(g).match }.to \
87
- raise_error(GraphMatching::DisconnectedGraph)
88
- end
89
- end
90
-
91
- it 'simple example: graph with blossom (234)' do
92
- g = graph_class[
93
- 1, 2,
94
- 2, 3,
95
- 2, 4,
96
- 3, 4,
97
- 4, 5,
98
- 5, 6
99
- ]
100
- m = described_class.new(g).match
101
- expect(m.size).to eq(3)
102
- expect(m).to match_edges [[1, 2], [3, 4], [5, 6]]
103
- end
104
-
105
- it 'example from West\'s Introduction to Graph Theory, p. 143' do
106
- g = graph_class[
107
- 1, 2,
108
- 1, 8,
109
- 2, 3,
110
- 3, 4,
111
- 3, 7,
112
- 4, 5,
113
- 4, 7,
114
- 5, 6,
115
- 7, 9,
116
- 8, 9,
117
- 10, 8
118
- ]
119
- m = described_class.new(g).match
120
- expect(m.size).to eq(5)
121
- expect(m).to match_edges [[1, 2], [3, 4], [5, 6], [7, 9], [8, 10]]
122
- end
123
-
124
- it 'example from Gabow (1976)' do
125
- g = graph_class[
126
- 1, 2,
127
- 2, 3,
128
- 1, 3,
129
- 1, 10,
130
- 3, 9,
131
- 3, 4,
132
- 4, 7,
133
- 4, 8,
134
- 7, 8,
135
- 9, 5,
136
- 5, 6,
137
- 6, 7
138
- ]
139
- m = described_class.new(g).match
140
- expect(m).to match_edges [[10, 1], [2, 3], [4, 8], [7, 6], [5, 9]]
141
- end
142
-
143
- it 'various complete graphs' do
144
- [
145
- [1, 0], # size of graph, expected size of matching
146
- [2, 1],
147
- [3, 1],
148
- [4, 2],
149
- [5, 2],
150
- [6, 3],
151
- [20, 10]
152
- ].each do |test|
153
- g = complete_graph(test[0])
154
- m = described_class.new(g).match
155
- expect(m.size).to eq(test[1])
156
- end
157
- end
158
- end
159
- end
@@ -1,82 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe GraphMatching::Algorithm::MWMBipartite do
6
- let(:graph_class) { GraphMatching::Graph::WeightedBigraph }
7
-
8
- describe '.new' do
9
- it 'requires a WeightedBigraph' do
10
- expect { described_class.new('banana') }.to raise_error(TypeError)
11
- end
12
- end
13
-
14
- describe '#match' do
15
- context 'empty graph' do
16
- it 'returns the expected matching' do
17
- g = graph_class.new
18
- m = described_class.new(g).match
19
- expect(m.size).to eq(0)
20
- expect(m.weight(g)).to eq(0)
21
- end
22
- end
23
-
24
- context 'trivial bigraph with two vertexes' do
25
- it 'returns the expected matching' do
26
- g = graph_class[[1, 2, 7]]
27
- m = described_class.new(g).match
28
- expect(m.size).to eq(1)
29
- expect(m).to match_edges [[1, 2]]
30
- expect(m.weight(g)).to eq(7)
31
- end
32
- end
33
-
34
- context 'complete bigraph with three vertexes' do
35
- it 'returns the expected matching' do
36
- g = graph_class[
37
- [1, 2, 1],
38
- [1, 3, 2]
39
- ]
40
- m = described_class.new(g).match
41
- expect(m).to match_edges [[1, 3]]
42
- expect(m.weight(g)).to eq(2)
43
- end
44
-
45
- it 'supports negative weights' do
46
- g = graph_class[
47
- [1, 2, -1],
48
- [1, 3, -3]
49
- ]
50
- m = described_class.new(g).match
51
- expect(m).to match_edges [[1, 2]]
52
- expect(m.weight(g)).to eq(-1)
53
- end
54
- end
55
-
56
- context 'bigraph with two connected components' do
57
- it 'returns one of two expected matchings' do
58
- g = graph_class[
59
- [1, 5, 3],
60
- [2, 4, 2],
61
- [2, 6, 2],
62
- [3, 5, 3]
63
- ]
64
- m = described_class.new(g).match
65
- expect(m.size).to eq(2)
66
- expect(m.weight(g)).to eq(5)
67
- end
68
-
69
- it 'returns the expected matching' do
70
- g = graph_class[
71
- [1, 5, 4],
72
- [2, 4, 2],
73
- [2, 6, 1],
74
- [3, 5, 3]
75
- ]
76
- m = described_class.new(g).match
77
- expect(m).to match_edges [[1, 5], [2, 4]]
78
- expect(m.weight(g)).to eq(6)
79
- end
80
- end
81
- end
82
- end
@@ -1,442 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- RSpec.describe GraphMatching::Algorithm::MWMGeneral do
6
- let(:graph_class) { GraphMatching::Graph::WeightedGraph }
7
-
8
- describe '.new' do
9
- it 'requires a WeightedGraph' do
10
- expect { described_class.new('banana') }.to raise_error(TypeError)
11
- end
12
- end
13
-
14
- describe '#blossom_leaves' do
15
- context 'five vertexes, one blossom' do
16
- it 'returns array of leaves' do
17
- g = graph_class[
18
- [0, 1, 0],
19
- [1, 2, 0],
20
- [1, 3, 0],
21
- [2, 3, 0],
22
- [3, 4, 0]
23
- ]
24
- a = described_class.new(g)
25
- a.instance_variable_set(
26
- :@blossom_children,
27
- [
28
- nil,
29
- nil,
30
- nil,
31
- nil,
32
- nil,
33
- [2, 3, 4]
34
- ]
35
- )
36
- expect(a.send(:blossom_leaves, 0)).to eq([0])
37
- expect(a.send(:blossom_leaves, 4)).to eq([4])
38
- expect(a.send(:blossom_leaves, 5)).to eq([2, 3, 4])
39
- end
40
- end
41
- end
42
-
43
- describe '#match' do
44
- context 'empty graph' do
45
- it 'returns empty matching' do
46
- g = graph_class.new
47
- m = described_class.new(g).match(true)
48
- expect(m).to be_empty
49
- end
50
- end
51
-
52
- context 'single vertex' do
53
- it 'returns empty matching' do
54
- g = graph_class.new
55
- g.add_vertex(0)
56
- m = described_class.new(g).match(true)
57
- expect(m).to be_empty
58
- end
59
- end
60
-
61
- context 'two vertexes, but no edge' do
62
- it 'returns empty matching' do
63
- g = graph_class.new
64
- g.add_vertex(0)
65
- g.add_vertex(1)
66
- m = described_class.new(g).match(true)
67
- expect(m).to be_empty
68
- end
69
- end
70
-
71
- context 'two vertexes' do
72
- it 'returns matching of size 1' do
73
- g = graph_class[[0, 1, 7]]
74
- m = described_class.new(g).match(true)
75
- expect(m).to match_edges [[0, 1]]
76
- expect(m.weight(g)).to eq(7)
77
- end
78
- end
79
-
80
- context 'three vertexes' do
81
- it 'matches the edge with greater weight' do
82
- g = graph_class[
83
- [0, 1, 1],
84
- [1, 2, 2],
85
- [2, 0, 3]
86
- ]
87
- m = described_class.new(g).match(true)
88
- expect(m).to match_edges [[0, 2]]
89
- expect(m.weight(g)).to eq(3)
90
- end
91
- end
92
-
93
- context 'greatest weight edge cannot be used in complete matching' do
94
- it 'returns the complete matching with max. weight' do
95
- # In the following graph, edge 1=3 has the greatest weight,
96
- # but that edge cannot be used in a complete matching.
97
- g = graph_class[
98
- [0, 1, 2],
99
- [1, 2, 0],
100
- [1, 3, 6],
101
- [2, 3, 4],
102
- [3, 4, 2]
103
- ]
104
- m = described_class.new(g).match(true)
105
- expect(m).to match_edges [[0, 1], [2, 3]]
106
- expect(m.weight(g)).to eq(6)
107
- end
108
- end
109
-
110
- it 'passes Van Rantwijk test 12' do
111
- g = graph_class[[1, 2, 10], [2, 3, 11]]
112
- m = described_class.new(g).match(false)
113
- expect(m).to match_edges [[2, 3]]
114
- expect(m.weight(g)).to eq(11)
115
- end
116
-
117
- it 'passes Van Rantwijk test 13' do
118
- g = graph_class[
119
- [1, 2, 5],
120
- [2, 3, 11],
121
- [3, 4, 5]
122
- ]
123
- m = described_class.new(g).match(false)
124
- expect(m).to match_edges [[2, 3]]
125
- expect(m.weight(g)).to eq(11)
126
- end
127
-
128
- it 'passes Van Rantwijk test 14: max. cardinality' do
129
- g = graph_class[
130
- [1, 2, 5],
131
- [2, 3, 11],
132
- [3, 4, 5]
133
- ]
134
- m = described_class.new(g).match(true)
135
- expect(m).to match_edges [[1, 2], [3, 4]]
136
- expect(m.weight(g)).to eq(10)
137
- end
138
-
139
- it 'passes Van Rantwijk test 15: floating-point weights' do
140
- g = graph_class[
141
- [1, 2, Math::PI],
142
- [2, 3, Math.exp(1)],
143
- [1, 3, 3.0],
144
- [1, 4, Math.sqrt(2.0)]
145
- ]
146
- m = described_class.new(g).match(false)
147
- expect(m).to match_edges [[1, 4], [2, 3]]
148
- expect(m.weight(g)).to be_within(0.00001).of(Math.sqrt(2.0) + Math.exp(1))
149
- end
150
-
151
- it 'passes Van Rantwijk test 16: negative weights' do
152
- g = graph_class[
153
- [1, 2, 2],
154
- [1, 3, -2],
155
- [2, 3, 1],
156
- [2, 4, -1],
157
- [3, 4, -6]
158
- ]
159
- m = described_class.new(g).match(false)
160
- expect(m).to match_edges [[1, 2]]
161
- expect(m.weight(g)).to eq(2)
162
- m = described_class.new(g).match(true)
163
- expect(m).to match_edges [[1, 3], [2, 4]]
164
- expect(m.weight(g)).to eq(-3)
165
- end
166
-
167
- context 'Van Rantwijk test 20: Uses S-blossom for augmentation' do
168
- it 'passes test 20-A' do
169
- g = graph_class[
170
- [1, 2, 8],
171
- [1, 3, 9],
172
- [2, 3, 10],
173
- [3, 4, 7]
174
- ]
175
- m = described_class.new(g).match(false)
176
- expect(m).to match_edges [[1, 2], [3, 4]]
177
- expect(m.weight(g)).to eq(15)
178
- end
179
-
180
- it 'passes test 20-B' do
181
- g = graph_class[
182
- [1, 2, 8],
183
- [1, 3, 9],
184
- [2, 3, 10],
185
- [3, 4, 7],
186
- [1, 6, 5],
187
- [4, 5, 6]
188
- ]
189
- m = described_class.new(g).match(false)
190
- expect(m).to match_edges [[1, 6], [2, 3], [4, 5]]
191
- expect(m.weight(g)).to eq(21)
192
- end
193
- end
194
-
195
- # Van Rantwijk test 21
196
- context 'create S-blossom, relabel as T-blossom, use for augmentation' do
197
- it 'passes test 21-A' do
198
- g = graph_class[
199
- [1, 2, 9],
200
- [1, 3, 8],
201
- [2, 3, 10],
202
- [1, 4, 5],
203
- [4, 5, 4],
204
- [1, 6, 3]
205
- ]
206
- m = described_class.new(g).match(false)
207
- expect(m).to match_edges [[1, 6], [2, 3], [4, 5]]
208
- end
209
-
210
- it 'passes test 21-B' do
211
- g = graph_class[
212
- [1, 2, 9],
213
- [1, 3, 8],
214
- [2, 3, 10],
215
- [1, 4, 5],
216
- [4, 5, 3],
217
- [1, 6, 4]
218
- ]
219
- m = described_class.new(g).match(false)
220
- expect(m).to match_edges [[1, 6], [2, 3], [4, 5]]
221
- end
222
-
223
- it 'passes test 21-C' do
224
- g = graph_class[
225
- [1, 2, 9],
226
- [1, 3, 8],
227
- [2, 3, 10],
228
- [1, 4, 5],
229
- [4, 5, 3],
230
- [3, 6, 4]
231
- ]
232
- m = described_class.new(g).match(false)
233
- expect(m).to match_edges [[1, 2], [3, 6], [4, 5]]
234
- end
235
- end
236
-
237
- context 'Van Rantwijk test 22' do
238
- it 'creates nested S-blossom, uses for augmentation' do
239
- g = graph_class[
240
- [1, 2, 9],
241
- [1, 3, 9],
242
- [2, 3, 10],
243
- [2, 4, 8],
244
- [3, 5, 8],
245
- [4, 5, 10],
246
- [5, 6, 6]
247
- ]
248
- m = described_class.new(g).match(false)
249
- expect(m).to match_edges [[1, 3], [2, 4], [5, 6]]
250
- end
251
- end
252
-
253
- context 'Van Rantwijk test 23' do
254
- it 'create S-blossom, relabel as S, include in nested S-blossom' do
255
- g = graph_class[
256
- [1, 2, 10],
257
- [1, 7, 10],
258
- [2, 3, 12],
259
- [3, 4, 20],
260
- [3, 5, 20],
261
- [4, 5, 25],
262
- [5, 6, 10],
263
- [6, 7, 10],
264
- [7, 8, 8]
265
- ]
266
- m = described_class.new(g).match(false)
267
- expect(m).to match_edges [[1, 2], [3, 4], [5, 6], [7, 8]]
268
- end
269
- end
270
-
271
- context 'Van Rantwijk test 24' do
272
- it 'create nested S-blossom, augment, expand recursively' do
273
- g = graph_class[
274
- [1, 2, 8],
275
- [1, 3, 8],
276
- [2, 3, 10],
277
- [2, 4, 12],
278
- [3, 5, 12],
279
- [4, 5, 14],
280
- [4, 6, 12],
281
- [5, 7, 12],
282
- [6, 7, 14],
283
- [7, 8, 12]
284
- ]
285
- m = described_class.new(g).match(false)
286
- expect(m).to match_edges [[1, 2], [3, 5], [4, 6], [7, 8]]
287
- end
288
- end
289
-
290
- context 'Van Rantwijk test 25' do
291
- it 'create S-blossom, relabel as T, expand' do
292
- g = graph_class[
293
- [1, 2, 23],
294
- [1, 5, 22],
295
- [1, 6, 15],
296
- [2, 3, 25],
297
- [3, 4, 22],
298
- [4, 5, 25],
299
- [4, 8, 14],
300
- [5, 7, 13]
301
- ]
302
- m = described_class.new(g).match(false)
303
- expect(m).to match_edges [[1, 6], [2, 3], [4, 8], [5, 7]]
304
- end
305
- end
306
-
307
- context 'Van Rantwijk test 26' do
308
- it 'create nested S-blossom, relabel as T, expand' do
309
- g = graph_class[
310
- [1, 2, 19],
311
- [1, 3, 20],
312
- [1, 8, 8],
313
- [2, 3, 25],
314
- [2, 4, 18],
315
- [3, 5, 18],
316
- [4, 5, 13],
317
- [4, 7, 7],
318
- [5, 6, 7]
319
- ]
320
- m = described_class.new(g).match(false)
321
- expect(m).to match_edges [[1, 8], [2, 3], [4, 7], [5, 6]]
322
- end
323
- end
324
-
325
- context 'Van Rantwijk test 30' do
326
- it 'create blossom, relabel as T in more than one way, expand, augment' do
327
- g = graph_class[
328
- [1, 2, 45],
329
- [1, 5, 45],
330
- [2, 3, 50],
331
- [3, 4, 45],
332
- [4, 5, 50],
333
- [1, 6, 30],
334
- [3, 9, 35],
335
- [4, 8, 35],
336
- [5, 7, 26],
337
- [9, 10, 5]
338
- ]
339
- m = described_class.new(g).match(false)
340
- expect(m).to match_edges [[1, 6], [2, 3], [4, 8], [5, 7], [9, 10]]
341
- end
342
- end
343
-
344
- context 'Van Rantwijk test 31' do
345
- it 'similar to test 30, but slightly different' do
346
- g = graph_class[
347
- [1, 2, 45],
348
- [1, 5, 45],
349
- [2, 3, 50],
350
- [3, 4, 45],
351
- [4, 5, 50],
352
- [1, 6, 30],
353
- [3, 9, 35],
354
- [4, 8, 26], # differs from test 30
355
- [5, 7, 40], # differs from test 30
356
- [9, 10, 5]
357
- ]
358
- m = described_class.new(g).match(false)
359
- expect(m).to match_edges [[1, 6], [2, 3], [4, 8], [5, 7], [9, 10]]
360
- end
361
- end
362
-
363
- context 'Van Rantwijk test 32' do
364
- # create blossom, relabel as T, expand such that a new
365
- # least-slack S-to-free edge is produced, augment
366
- it 'see comment' do
367
- g = graph_class[
368
- [1, 2, 45],
369
- [1, 5, 45],
370
- [2, 3, 50],
371
- [3, 4, 45],
372
- [4, 5, 50],
373
- [1, 6, 30],
374
- [3, 9, 35],
375
- [4, 8, 28],
376
- [5, 7, 26],
377
- [9, 10, 5]
378
- ]
379
- m = described_class.new(g).match(false)
380
- expect(m).to match_edges [[1, 6], [2, 3], [4, 8], [5, 7], [9, 10]]
381
- end
382
- end
383
-
384
- context 'Van Rantwijk test 33' do
385
- # create nested blossom, relabel as T in more than one way,
386
- # expand outer blossom such that inner blossom ends up on
387
- # an augmenting path
388
- it 'see comment' do
389
- g = graph_class[
390
- [1, 2, 45],
391
- [1, 7, 45],
392
- [2, 3, 50],
393
- [3, 4, 45],
394
- [4, 5, 95],
395
- [4, 6, 94],
396
- [5, 6, 94],
397
- [6, 7, 50],
398
- [1, 8, 30],
399
- [3, 11, 35],
400
- [5, 9, 36],
401
- [7, 10, 26],
402
- [11, 12, 5]
403
- ]
404
- m = described_class.new(g).match(false)
405
- expect(m).to match_edges [
406
- [1, 8],
407
- [2, 3],
408
- [4, 6],
409
- [5, 9],
410
- [7, 10],
411
- [11, 12]
412
- ]
413
- end
414
- end
415
-
416
- context 'Van Rantwijk test 34: nest, relabel, expand' do
417
- it 'create nested S-blossom, relabel as S, expand recursively' do
418
- g = graph_class[
419
- [1, 2, 40],
420
- [1, 3, 40],
421
- [2, 3, 60],
422
- [2, 4, 55],
423
- [3, 5, 55],
424
- [4, 5, 50],
425
- [1, 8, 15],
426
- [5, 7, 30],
427
- [7, 6, 10],
428
- [8, 10, 10],
429
- [4, 9, 30]
430
- ]
431
- m = described_class.new(g).match(false)
432
- expect(m).to match_edges [
433
- [1, 2],
434
- [3, 5],
435
- [4, 9],
436
- [6, 7],
437
- [8, 10]
438
- ]
439
- end
440
- end
441
- end
442
- end