Skip to content

Commit bfdd3e9

Browse files
committed
fixing test issues
1 parent 329d470 commit bfdd3e9

File tree

3 files changed

+67
-63
lines changed

3 files changed

+67
-63
lines changed

src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
2-
3-
package com.thealgorithms.dynamicprogramming;
4-
5-
import java.util.Arrays;
6-
7-
81
/**
92
* @author Md Asif Joardar
103
*
@@ -21,6 +14,10 @@
2114
* The time complexity of the solution is O(n × sum) and requires O(n × sum) space
2215
*/
2316

17+
package com.thealgorithms.dynamicprogramming;
18+
19+
import java.util.Arrays;
20+
2421
public final class PartitionProblem {
2522
private PartitionProblem() {
2623
}
Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,46 @@
11
package com.thealgorithms.graph;
22

3-
import java.util.*;
3+
import java.util.ArrayDeque;
4+
import java.util.Arrays;
5+
import java.util.List;
6+
import java.util.Queue;
47

58
/**
6-
* @author Panteleimon Tzecheridis
9+
* Hopcroft–Karp algorithm for maximum bipartite matching.
710
*
8-
* Implementation of the Hopcroft–Karp algorithm for finding the maximum matching in a bipartite graph.
11+
* Left part: vertices [0..nLeft-1], Right part: [0..nRight-1].
12+
* Adjacency list: for each left vertex u, list right vertices v it connects to.
913
*
10-
* The bipartite graph is assumed to have:
11-
* - Left part: vertices [0..nLeft-1]
12-
* - Right part: vertices [0..nRight-1]
14+
* Time complexity: O(E * sqrt(V)).
1315
*
14-
* Adjacency list format: For each left vertex, list the right vertices it is connected to.
15-
* Example:
16-
* adj[0] = [0, 1] // left vertex 0 connects to right vertices 0 and 1
17-
*
18-
* Time complexity: O(E * sqrt(V))
19-
*
20-
* @see <a href="https://en.wikipedia.org/wiki/Hopcroft%E2%80%93Karp_algorithm">Wikipedia: Hopcroft–Karp algorithm</a>
16+
* @see <a href="https://en.wikipedia.org/wiki/Hopcroft%E2%80%93Karp_algorithm">
17+
* Wikipedia: Hopcroft–Karp algorithm</a>
18+
* @author ptzecher
2119
*/
2220
public class HopcroftKarp {
2321

24-
private int nLeft, nRight;
25-
private List<List<Integer>> adj;
26-
private int[] pairU, pairV, dist;
22+
private final int nLeft;
23+
private final int nRight;
24+
private final List<List<Integer>> adj;
25+
26+
private final int[] pairU;
27+
private final int[] pairV;
28+
private final int[] dist;
2729

2830
public HopcroftKarp(int nLeft, int nRight, List<List<Integer>> adj) {
2931
this.nLeft = nLeft;
3032
this.nRight = nRight;
3133
this.adj = adj;
34+
3235
this.pairU = new int[nLeft];
3336
this.pairV = new int[nRight];
3437
this.dist = new int[nLeft];
38+
3539
Arrays.fill(pairU, -1);
3640
Arrays.fill(pairV, -1);
3741
}
3842

39-
/**
40-
* Returns the size of the maximum matching.
41-
*/
43+
/** Returns the size of the maximum matching. */
4244
public int maxMatching() {
4345
int matching = 0;
4446
while (bfs()) {
@@ -55,33 +57,35 @@ public int maxMatching() {
5557
private boolean bfs() {
5658
Queue<Integer> queue = new ArrayDeque<>();
5759
Arrays.fill(dist, -1);
60+
5861
for (int u = 0; u < nLeft; u++) {
5962
if (pairU[u] == -1) {
6063
dist[u] = 0;
6164
queue.add(u);
6265
}
6366
}
67+
6468
boolean foundAugPath = false;
6569
while (!queue.isEmpty()) {
6670
int u = queue.poll();
6771
for (int v : adj.get(u)) {
68-
int u2 = pairV[v];
69-
if (u2 == -1) {
72+
int matchedLeft = pairV[v];
73+
if (matchedLeft == -1) {
7074
foundAugPath = true;
71-
} else if (dist[u2] == -1) {
72-
dist[u2] = dist[u] + 1;
73-
queue.add(u2);
75+
} else if (dist[matchedLeft] == -1) {
76+
dist[matchedLeft] = dist[u] + 1;
77+
queue.add(matchedLeft);
7478
}
7579
}
7680
}
7781
return foundAugPath;
7882
}
7983

80-
// DFS to find augmenting paths
84+
// DFS to find augmenting paths within the BFS layering
8185
private boolean dfs(int u) {
8286
for (int v : adj.get(u)) {
83-
int u2 = pairV[v];
84-
if (u2 == -1 || (dist[u2] == dist[u] + 1 && dfs(u2))) {
87+
int matchedLeft = pairV[v];
88+
if (matchedLeft == -1 || (dist[matchedLeft] == dist[u] + 1 && dfs(matchedLeft))) {
8589
pairU[u] = v;
8690
pairV[v] = u;
8791
return true;
@@ -98,5 +102,4 @@ public int[] getLeftMatches() {
98102
public int[] getRightMatches() {
99103
return pairV.clone();
100104
}
101-
102-
}
105+
}
Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
package com.thealgorithms.graph;
22

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;
45

56
import java.util.ArrayList;
67
import java.util.Arrays;
78
import java.util.List;
89
import org.junit.jupiter.api.DisplayName;
910
import org.junit.jupiter.api.Test;
1011

12+
/**
13+
* Unit tests for Hopcroft–Karp algorithm.
14+
*
15+
* @author ptzecher
16+
*/
1117
class HopcroftKarpTest {
1218

1319
private static List<List<Integer>> adj(int nLeft) {
1420
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+
}
1624
return g;
1725
}
1826

@@ -32,10 +40,10 @@ void singleEdge() {
3240
HopcroftKarp hk = new HopcroftKarp(1, 1, g);
3341
assertEquals(1, hk.maxMatching());
3442

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]);
3947
}
4048

4149
@Test
@@ -50,18 +58,19 @@ void disjointEdges() {
5058
HopcroftKarp hk = new HopcroftKarp(3, 3, g);
5159
assertEquals(3, hk.maxMatching());
5260

53-
int[] L = hk.getLeftMatches();
54-
int[] R = hk.getRightMatches();
61+
int[] leftMatch = hk.getLeftMatches();
62+
int[] rightMatch = hk.getRightMatches();
5563
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]);
5866
}
5967
}
6068

6169
@Test
6270
@DisplayName("Complete bipartite K(3,4) matches min(3,4)=3")
6371
void completeK34() {
64-
int nLeft = 3, nRight = 4;
72+
int nLeft = 3;
73+
int nRight = 4; // split declarations
6574
List<List<Integer>> g = adj(nLeft);
6675
for (int u = 0; u < nLeft; u++) {
6776
g.get(u).addAll(Arrays.asList(0, 1, 2, 3));
@@ -70,10 +79,10 @@ void completeK34() {
7079
assertEquals(3, hk.maxMatching());
7180

7281
// sanity: no two left vertices share the same matched right vertex
73-
int[] L = hk.getLeftMatches();
82+
int[] leftMatch = hk.getLeftMatches();
7483
boolean[] used = new boolean[nRight];
7584
for (int u = 0; u < nLeft; u++) {
76-
int v = L[u];
85+
int v = leftMatch[u];
7786
if (v != -1) {
7887
assertFalse(used[v]);
7988
used[v] = true;
@@ -82,10 +91,10 @@ void completeK34() {
8291
}
8392

8493
@Test
85-
@DisplayName("Non-square, sparse graph")
94+
@DisplayName("Rectangular, sparse graph")
8695
void rectangularSparse() {
8796
// 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)
8998
List<List<Integer>> g = adj(5);
9099
g.get(0).add(0);
91100
g.get(1).add(1);
@@ -96,27 +105,22 @@ void rectangularSparse() {
96105
HopcroftKarp hk = new HopcroftKarp(5, 2, g);
97106
assertEquals(2, hk.maxMatching());
98107

99-
int[] L = hk.getLeftMatches();
100-
int[] R = hk.getRightMatches();
108+
int[] leftMatch = hk.getLeftMatches();
109+
int[] rightMatch = hk.getRightMatches();
101110

102-
// Check consistency: if L[u]=v then R[v]=u
111+
// Check consistency: if leftMatch[u]=v then rightMatch[v]=u
103112
for (int u = 0; u < 5; u++) {
104-
int v = L[u];
113+
int v = leftMatch[u];
105114
if (v != -1) {
106-
assertEquals(u, R[v]);
115+
assertEquals(u, rightMatch[v]);
107116
}
108117
}
109118
}
110119

111120
@Test
112-
@DisplayName("Layering advantage case (chains of short augmenting paths)")
121+
@DisplayName("Layering advantage case (short augmenting paths)")
113122
void layeringAdvantage() {
114123
// 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
120124
List<List<Integer>> g = adj(4);
121125
g.get(0).addAll(Arrays.asList(0, 1));
122126
g.get(1).addAll(Arrays.asList(1, 2));
@@ -126,4 +130,4 @@ void layeringAdvantage() {
126130
HopcroftKarp hk = new HopcroftKarp(4, 4, g);
127131
assertEquals(4, hk.maxMatching()); // perfect matching exists
128132
}
129-
}
133+
}

0 commit comments

Comments
 (0)