graph_matching 0.1.0 → 0.1.1

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