我正在为类编写工作,我必须读取邻接矩阵并在Java中输出二分匹配。我已经有两种方法可以完成这项工作,并且我已经设法让它适用于一个用例,但是我在使用其他两个用途时遇到了一些麻烦。我将在下面粘贴我的源代码。在程序开始时有3个测试用例,每个测试用例的结果都显示在最后。
我需要将矩阵实现为2D字符数组。我遇到的问题似乎与它的回溯部分有关。第二个测试用例返回正确的结果。如果有人能帮我理解我做错了什么,我会非常感激。我找到匹配的过程是:
遍历矩阵,显示匹配
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
预期结果:
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
答案 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;
}
目前,您的代码只会尝试为每个元素找到第一个可能的匹配项。
要进行适当的回溯,你需要从循环内部调用递归函数,然后如果找不到完全匹配,你需要测试下一个位置。