Java实现Markov Matrix校验方法报错:合规矩阵被误判
问题分析与修复
你的代码里isMarkovMatrix方法存在几个关键错误,导致无法正确判断正Markov矩阵:
遍历逻辑完全搞反
正Markov矩阵要求每列元素之和为1,但你现在是按行遍历累加,计算的是每行的和,完全不符合要求。sum的判断时机错误
你在累加每个元素后就检查sum != 1,这显然不对——只有当整列的所有元素都加完,sum才应该等于1,中途的sum值肯定不是1,这直接导致answer被设为false。元素合法性判断有误
正Markov矩阵要求每个元素严格大于0,你现在只判断了m[row][column] < 0,但如果元素等于0,也不符合正Markov矩阵的要求。浮点数精度问题
直接用sum == 1判断会因为double的精度误差导致误判,比如实际和是0.9999999999999999或者1.0000000000000002,这时候应该用误差范围来判断。
另外,main方法里的kbd.nextLine()可能会导致输入异常:nextDouble()不会消耗换行符,当输入完一行数字后按回车,这行代码会读取空的换行,若用户连续输入所有数字,会导致后续输入被吃掉,建议移除。
修复后的代码
import java.util.Scanner; public class MarkovMatrixChecker { public static void main(String[] args) { Scanner kbd = new Scanner(System.in); double[][] matrix = new double[3][3]; System.out.println("Enter a 3-by-3 matrix row by row: "); for(int row = 0; row < 3; row++){ for(int column = 0; column < 3; column++){ matrix[row][column] = kbd.nextDouble(); } } if(isMarkovMatrix(matrix)){ System.out.println("It is a Markov Matrix."); } else { System.out.println("It is not a Markov Matrix"); } kbd.close(); } public static boolean isMarkovMatrix(double[][] m){ // 先检查所有元素是否为正 for(int row = 0; row < m.length; row++){ for(int column = 0; column < m[row].length; column++){ if(m[row][column] <= 0){ return false; } } } // 检查每列的和是否为1(允许极小精度误差) for(int column = 0; column < m[0].length; column++){ double sum = 0.0; for(int row = 0; row < m.length; row++){ sum += m[row][column]; } // 用1e-9作为误差阈值,避免浮点数精度问题 if(Math.abs(sum - 1.0) > 1e-9){ return false; } } return true; } }
关键改进点
- 调整遍历顺序:外层循环遍历列,内层循环遍历行,计算每列的和。
- 提前返回:一旦发现不符合条件的元素或列和,直接返回false,无需继续遍历。
- 处理浮点数精度:用
Math.abs(sum - 1) > 1e-9替代直接相等判断,避免精度误差导致的误判。 - 修复输入逻辑:移除
kbd.nextLine(),避免输入异常。
内容的提问来源于stack exchange,提问作者Comp.Sci.Anon
相关产品推荐
相关产品推荐

