我如何完成BiPartite匹配计划?

时间:2015-02-17 16:49:06

标签: java algorithm recursion adjacency-matrix bipartite

我正在为类编写工作,我必须读取邻接矩阵并在Java中输出二分匹配。我已经有两种方法可以完成这项工作,并且我已经设法让它适用于一个用例,但是我在使用其他两个用途时遇到了一些麻烦。我将在下面粘贴我的源代码。在程序开始时有3个测试用例,每个测试用例的结果都显示在最后。

我需要将矩阵实现为2D字符数组。我遇到的问题似乎与它的回溯部分有关。第二个测试用例返回正确的结果。如果有人能帮我理解我做错了什么,我会非常感激。我找到匹配的过程是:

  1. 从最后一行开始
  2. 遍历每一栏
  3. 如果列标记为Y并且当前未采用该列(标记为“T”),则将该列标记为“T”。
  4. 递归调用下一行的方法
  5. 遍历矩阵,显示匹配

    public class BiPartiteMatch
    {
    // **************** main  ****************
    public static void main(String[] args)
    {
        System.out.println("Case 1: No matching exists. \n");
    
        //                     a    b    c    d    e    No matching A, C, E
        //                    -----------------------   will only take a & d 
        char [][]M = { /*E*/ {'y', 'n', 'n', 'y', 'n'},
                       /*D*/ {'n', 'y', 'n', 'y', 'n'},
                       /*C*/ {'y', 'n', 'n', 'y', 'n'},
                       /*B*/ {'y', 'n', 'y', 'y', 'y'},
                       /*A*/ {'y', 'n', 'n', 'y', 'n'} };
    
    
        System.out.println("Case 2: Matching with no backtracking needed. \n"); 
    
        //                     a    b    c    d    e    Matching with no 
        //                    -----------------------   backtracking needed
        char [][]M = { /*E*/ {'y', 'n', 'n', 'y', 'y'},
                       /*D*/ {'n', 'y', 'n', 'y', 'n'},
                       /*C*/ {'n', 'y', 'y', 'n', 'n'},
                       /*B*/ {'y', 'n', 'y', 'n', 'n'},
                       /*A*/ {'n', 'y', 'n', 'n', 'y'} };
    
    
        System.out.println("Case 3: Matching with backtracking. \n");
    
        //                     a    b    c    d    e    Matching with 
        //                    -----------------------   backtracking
        char [][]M = { /*E*/ {'n', 'y', 'n', 'n', 'y'},
                       /*D*/ {'y', 'n', 'y', 'n', 'n'},
                       /*C*/ {'n', 'y', 'y', 'n', 'n'},
                       /*B*/ {'n', 'y', 'n', 'y', 'n'},
                       /*A*/ {'y', 'n', 'n', 'y', 'y'} };
    
    
     if (findMatch(M, M.length-1)) // Find matches starting with the last row
         displayMatches(M); 
     else
         System.out.println("There is no matching.");         
    
    }// end main
    
    
    
    // **************** recursive findMatch  ****************
    public static boolean findMatch(char [][]M, int myRow)
    {           
            if(myRow < 0)
                return false;            
    
            for(int c = 0; c < M.length; c++)
            {
                if(M[myRow][c] == 'y' && !isTaken(M, myRow, c))
                {
                    M[myRow][c] = 't';
                    break;
                }
            }
    
            findMatch(M, myRow-1);
    
            return true;
    
    }// end findMatch      
    
    
    // **************** isTaken  ******************
    // *******is this column already taken? ********
    public static boolean isTaken(char [][]M, int row_Im_In, int col_Im_In)
    {
            for(int r = row_Im_In+1; r < M.length; r++)
            {
                if(M[r][col_Im_In] == 't')
                    return true;
            }
    
            return false;
    
    }// end isTaken
    
    
    // **************** displayMatches  ****************
    public static void displayMatches(char [][]M)
    {
        final char []MatchFrom = {'E', 'D', 'C', 'B', 'A'};
        final char []MatchTo   = {'a', 'b', 'c', 'd', 'e'};
    
                for(int r = M.length-1; r > -1; r--)
                {
                    for(int c = 0; c < M.length; c++)
                    {
                        if(M[r][c] == 't')
                        {
                            System.out.println(MatchFrom[r] + " matches to " + MatchTo[c]);
                        }
                    }
                }
    
    
    }// end displayMatches
    
    }// end class declaration
    
  6. 预期结果:

    Case 1: No mathing exists. 
    
    There is no matching.
    
    
    Case 2: Matching with no backtracking needed. 
    
    A matches to b
    B matches to a
    C matches to c
    D matches to d
    E matches to e
    
    
    Case 3: Matching with backtracking. 
    
    A matches to a
    B matches to d
    C matches to b
    D matches to c
    E matches to e
    

1 个答案:

答案 0 :(得分:1)

您需要使用以下内容替换findMatch:

public static boolean findMatch(char [][]M, int myRow)
{           
        if(myRow < 0)
            return true;            

        for(int c = 0; c < M.length; c++)
        {
            if(M[myRow][c] == 'y' && !isTaken(M, myRow, c))
            {
                M[myRow][c] = 't';
                if (findMatch(M, myRow-1))
                    return true;
                M[myRow][c] = 'y';
            }
        }
        return false;

}

目前,您的代码只会尝试为每个元素找到第一个可能的匹配项。

要进行适当的回溯,你需要从循环内部调用递归函数,然后如果找不到完全匹配,你需要测试下一个位置。