/** * Unit tests the {@code BipartiteX} data type. * * @param args the command-line arguments */ public static void main(String[] args) { int V1 = Integer.parseInt(args[0]); int V2 = Integer.parseInt(args[1]); int E = Integer.parseInt(args[2]); int F = Integer.parseInt(args[3]); // create random bipartite graph with V1 vertices on left side, // V2 vertices on right side, and E edges; then add F random edges Graph G = GraphGenerator.bipartite(V1, V2, E); for (int i = 0; i < F; i++) { int v = StdRandom.uniform(V1 + V2); int w = StdRandom.uniform(V1 + V2); G.addEdge(v, w); } StdOut.println(G); BipartiteX b = new BipartiteX(G); if (b.isBipartite()) { StdOut.println("Graph is bipartite"); for (int v = 0; v < G.V(); v++) { StdOut.println(v + ": " + b.color(v)); } } else { StdOut.print("Graph has an odd-length cycle: "); for (int x : b.oddCycle()) { StdOut.print(x + " "); } StdOut.println(); } }
private int[] edgeTo; // edgeTo[v] = last edge on alternating path to v /** * Determines a maximum matching (and a minimum vertex cover) * in a bipartite graph. * * @param G the bipartite graph * @throws IllegalArgumentException if {@code G} is not bipartite */ public BipartiteMatching(Graph G) { bipartition = new BipartiteX(G); if (!bipartition.isBipartite()) { throw new IllegalArgumentException("graph is not bipartite"); } this.V = G.V(); // initialize empty matching mate = new int[V]; for (int v = 0; v < V; v++) mate[v] = UNMATCHED; // alternating path algorithm while (hasAugmentingPath(G)) { // find one endpoint t in alternating path int t = -1; for (int v = 0; v < G.V(); v++) { if (!isMatched(v) && edgeTo[v] != -1) { t = v; break; } } // update the matching according to alternating path in edgeTo[] array for (int v = t; v != -1; v = edgeTo[edgeTo[v]]) { int w = edgeTo[v]; mate[v] = w; mate[w] = v; } cardinality++; } // find min vertex cover from marked[] array inMinVertexCover = new boolean[V]; for (int v = 0; v < V; v++) { if (bipartition.color(v) && !marked[v]) inMinVertexCover[v] = true; if (!bipartition.color(v) && marked[v]) inMinVertexCover[v] = true; } assert certifySolution(G); }