Java Program to Implement the Edmond’s Algorithm for Maximum Cardinality Matching

This is a java program to implement Edmond’s Algorithm for maximum cardinality matching. In graph theory, a branch of mathematics, Edmonds’ algorithm or Chu–Liu/Edmonds’ algorithm is an algorithm for finding a maximum or minimum optimum branchings. This is similar to the minimum spanning tree problem which concerns undirected graphs. However, when nodes are connected by weighted edges that are directed, a minimum spanning tree algorithm cannot be used.

Here is the source code of the Java Program to Implement the Edmond’s Algorithm for Maximum Cardinality Matching. The Java program is successfully compiled and run on a Windows system. The program output is also shown below.

package com.maixuanviet.graph;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
 
public class EdmondsMaximumCardinalityMatching
{
    static int lca(int[] match, int[] base, int[] p, int a, int b)
    {
        boolean[] used = new boolean[match.length];
        while (true)
        {
            a = base[a];
            used[a] = true;
            if (match[a] == -1)
                break;
            a = p[match[a]];
        }
        while (true)
        {
            b = base[b];
            if (used[b])
                return b;
            b = p[match[b]];
        }
    }
 
    static void markPath(int[] match, int[] base, boolean[] blossom, int[] p,
            int v, int b, int children)
    {
        for (; base[v] != b; v = p[match[v]])
        {
            blossom[base[v]] = blossom[base[match[v]]] = true;
            p[v] = children;
            children = match[v];
        }
    }
 
    static int findPath(List<Integer>[] graph, int[] match, int[] p, int root)
    {
        int n = graph.length;
        boolean[] used = new boolean[n];
        Arrays.fill(p, -1);
        int[] base = new int[n];
        for (int i = 0; i < n; ++i)
            base[i] = i;
        used[root] = true;
        int qh = 0;
        int qt = 0;
        int[] q = new int[n];
        q[qt++] = root;
        while (qh < qt)
        {
            int v = q[qh++];
            for (int to : graph[v])
            {
                if (base[v] == base[to] || match[v] == to)
                    continue;
                if (to == root || match[to] != -1 && p[match[to]] != -1)
                {
                    int curbase = lca(match, base, p, v, to);
                    boolean[] blossom = new boolean[n];
                    markPath(match, base, blossom, p, v, curbase, to);
                    markPath(match, base, blossom, p, to, curbase, v);
                    for (int i = 0; i < n; ++i)
                        if (blossom[base[i]])
                        {
                            base[i] = curbase;
                            if (!used[i])
                            {
                                used[i] = true;
                                q[qt++] = i;
                            }
                        }
                }
                else if (p[to] == -1)
                {
                    p[to] = v;
                    if (match[to] == -1)
                        return to;
                    to = match[to];
                    used[to] = true;
                    q[qt++] = to;
                }
            }
        }
        return -1;
    }
 
    public static int maxMatching(List<Integer>[] graph)
    {
        int n = graph.length;
        int[] match = new int[n];
        Arrays.fill(match, -1);
        int[] p = new int[n];
        for (int i = 0; i < n; ++i)
        {
            if (match[i] == -1)
            {
                int v = findPath(graph, match, p, i);
                while (v != -1)
                {
                    int pv = p[v];
                    int ppv = match[pv];
                    match[v] = pv;
                    match[pv] = v;
                    v = ppv;
                }
            }
        }
        int matches = 0;
        for (int i = 0; i < n; ++i)
            if (match[i] != -1)
                ++matches;
        return matches / 2;
    }
 
    @SuppressWarnings("unchecked")
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the number of vertices: ");
        int v = sc.nextInt();
        System.out.println("Enter the number of edges: ");
        int e = sc.nextInt();
        List<Integer>[] g = new List[v];
        for (int i = 0; i < v; i++)
        {
            g[i] = new ArrayList<Integer>();
        }
        System.out.println("Enter all the edges: <from> <to>");
        for (int i = 0; i < e; i++)
        {
            g[sc.nextInt()].add(sc.nextInt());
        }
        System.out.println("Maximum matching for the given graph is: "
                + maxMatching(g));
        sc.close();
    }
}

Output:

$ javac EdmondsMaximumCardinalityMatching.java
$ java EdmondsMaximumCardinalityMatching
 
Enter the number of vertices: 
6
Enter the number of edges: 
7
Enter all the edges: <from> <to>
0 1
1 2
1 3
3 4
4 5
5 3
5 2
Maximum matching for the given graph is: 3

Related posts:

Java Program to Implement Binary Search Tree
Java Program to Generate All Possible Combinations of a Given List of Numbers
Spring Autowiring of Generic Types
Java Program to Implement Segment Tree
Handle EML file with JavaMail
Java Program to Generate All Subsets of a Given Set in the Gray Code Order
Java Program to Find the Number of Ways to Write a Number as the Sum of Numbers Smaller than Itself
Java Program to Find the Mode in a Data Set
Java Program to Implement Selection Sort
HttpClient Connection Management
Java Program to Implement Best-First Search
Using JWT with Spring Security OAuth (legacy stack)
Java Program to Implement HashTable API
Java Program to Evaluate an Expression using Stacks
Case-Insensitive String Matching in Java
Spring Security 5 for Reactive Applications
Get and Post Lists of Objects with RestTemplate
Instance Profile Credentials using Spring Cloud
Java Program to Permute All Letters of an Input String
Java Program to Find a Good Feedback Edge Set in a Graph
Spring Data JPA Delete and Relationships
Life Cycle of a Thread in Java
Giới thiệu Swagger – Công cụ document cho RESTfull APIs
Java Program to Solve Set Cover Problem assuming at max 2 Elements in a Subset
Java Program to do a Depth First Search/Traversal on a graph non-recursively
Java Program to Implement Meldable Heap
How to Delay Code Execution in Java
Java NIO2 Path API
Sort a HashMap in Java
Java Program to Create a Random Linear Extension for a DAG
Java Program to Find Shortest Path Between All Vertices Using Floyd-Warshall’s Algorithm
Intro to the Jackson ObjectMapper