1
1
package com .thealgorithms .graph ;
2
2
3
- import static org .junit .jupiter .api .Assertions .*;
3
+ import static org .junit .jupiter .api .Assertions .assertEquals ;
4
+ import static org .junit .jupiter .api .Assertions .assertFalse ;
4
5
5
6
import java .util .ArrayList ;
6
7
import java .util .Arrays ;
7
8
import java .util .List ;
8
9
import org .junit .jupiter .api .DisplayName ;
9
10
import org .junit .jupiter .api .Test ;
10
11
12
+ /**
13
+ * Unit tests for Hopcroft–Karp algorithm.
14
+ *
15
+ * @author ptzecher
16
+ */
11
17
class HopcroftKarpTest {
12
18
13
19
private static List <List <Integer >> adj (int nLeft ) {
14
20
List <List <Integer >> g = new ArrayList <>(nLeft );
15
- for (int i = 0 ; i < nLeft ; i ++) g .add (new ArrayList <>());
21
+ for (int i = 0 ; i < nLeft ; i ++) { // braces required by Checkstyle
22
+ g .add (new ArrayList <>());
23
+ }
16
24
return g ;
17
25
}
18
26
@@ -32,10 +40,10 @@ void singleEdge() {
32
40
HopcroftKarp hk = new HopcroftKarp (1 , 1 , g );
33
41
assertEquals (1 , hk .maxMatching ());
34
42
35
- int [] L = hk .getLeftMatches ();
36
- int [] R = hk .getRightMatches ();
37
- assertEquals (0 , L [0 ]);
38
- assertEquals (0 , R [0 ]);
43
+ int [] leftMatch = hk .getLeftMatches ();
44
+ int [] rightMatch = hk .getRightMatches ();
45
+ assertEquals (0 , leftMatch [0 ]);
46
+ assertEquals (0 , rightMatch [0 ]);
39
47
}
40
48
41
49
@ Test
@@ -50,18 +58,19 @@ void disjointEdges() {
50
58
HopcroftKarp hk = new HopcroftKarp (3 , 3 , g );
51
59
assertEquals (3 , hk .maxMatching ());
52
60
53
- int [] L = hk .getLeftMatches ();
54
- int [] R = hk .getRightMatches ();
61
+ int [] leftMatch = hk .getLeftMatches ();
62
+ int [] rightMatch = hk .getRightMatches ();
55
63
for (int i = 0 ; i < 3 ; i ++) {
56
- assertEquals (i , L [i ]);
57
- assertEquals (i , R [i ]);
64
+ assertEquals (i , leftMatch [i ]);
65
+ assertEquals (i , rightMatch [i ]);
58
66
}
59
67
}
60
68
61
69
@ Test
62
70
@ DisplayName ("Complete bipartite K(3,4) matches min(3,4)=3" )
63
71
void completeK34 () {
64
- int nLeft = 3 , nRight = 4 ;
72
+ int nLeft = 3 ;
73
+ int nRight = 4 ; // split declarations
65
74
List <List <Integer >> g = adj (nLeft );
66
75
for (int u = 0 ; u < nLeft ; u ++) {
67
76
g .get (u ).addAll (Arrays .asList (0 , 1 , 2 , 3 ));
@@ -70,10 +79,10 @@ void completeK34() {
70
79
assertEquals (3 , hk .maxMatching ());
71
80
72
81
// sanity: no two left vertices share the same matched right vertex
73
- int [] L = hk .getLeftMatches ();
82
+ int [] leftMatch = hk .getLeftMatches ();
74
83
boolean [] used = new boolean [nRight ];
75
84
for (int u = 0 ; u < nLeft ; u ++) {
76
- int v = L [u ];
85
+ int v = leftMatch [u ];
77
86
if (v != -1 ) {
78
87
assertFalse (used [v ]);
79
88
used [v ] = true ;
@@ -82,10 +91,10 @@ void completeK34() {
82
91
}
83
92
84
93
@ Test
85
- @ DisplayName ("Non-square , sparse graph" )
94
+ @ DisplayName ("Rectangular , sparse graph" )
86
95
void rectangularSparse () {
87
96
// Left: 5, Right: 2
88
- // edges: L0-R0, L1-R1, L2-R0, L3-R1 (max matching = 2)
97
+ // edges: L0-R0, L1-R1, L2-R0, L3-R1 (max matching = 2)
89
98
List <List <Integer >> g = adj (5 );
90
99
g .get (0 ).add (0 );
91
100
g .get (1 ).add (1 );
@@ -96,27 +105,22 @@ void rectangularSparse() {
96
105
HopcroftKarp hk = new HopcroftKarp (5 , 2 , g );
97
106
assertEquals (2 , hk .maxMatching ());
98
107
99
- int [] L = hk .getLeftMatches ();
100
- int [] R = hk .getRightMatches ();
108
+ int [] leftMatch = hk .getLeftMatches ();
109
+ int [] rightMatch = hk .getRightMatches ();
101
110
102
- // Check consistency: if L [u]=v then R [v]=u
111
+ // Check consistency: if leftMatch [u]=v then rightMatch [v]=u
103
112
for (int u = 0 ; u < 5 ; u ++) {
104
- int v = L [u ];
113
+ int v = leftMatch [u ];
105
114
if (v != -1 ) {
106
- assertEquals (u , R [v ]);
115
+ assertEquals (u , rightMatch [v ]);
107
116
}
108
117
}
109
118
}
110
119
111
120
@ Test
112
- @ DisplayName ("Layering advantage case (chains of short augmenting paths)" )
121
+ @ DisplayName ("Layering advantage case (short augmenting paths)" )
113
122
void layeringAdvantage () {
114
123
// Left 4, Right 4
115
- // Build a structure that benefits from BFS layering
116
- // L0: R0, R1
117
- // L1: R1, R2
118
- // L2: R2, R3
119
- // L3: R0, R3
120
124
List <List <Integer >> g = adj (4 );
121
125
g .get (0 ).addAll (Arrays .asList (0 , 1 ));
122
126
g .get (1 ).addAll (Arrays .asList (1 , 2 ));
@@ -126,4 +130,4 @@ void layeringAdvantage() {
126
130
HopcroftKarp hk = new HopcroftKarp (4 , 4 , g );
127
131
assertEquals (4 , hk .maxMatching ()); // perfect matching exists
128
132
}
129
- }
133
+ }
0 commit comments