/** * Int matrix. For efficiency we do not define ObjectMatrix. One can revise it * to obtain DoubleMatrix. * * @author ShiHuai Wen shihuaiwen@outlook.com. */ publicclassIntMatrix { /** * The data. */ int[][] data;
/** ********************* * The first constructor. * * @param paraRows The number of rows. * @param paraColumns The number of columns. ********************* */ publicIntMatrix(int paraRows, int paraColumns) { data = newint[paraRows][paraColumns]; }// Of the first constructor
/** ********************* * The second constructor. Construct a copy of the given matrix. * * @param paraMatrix The given matrix. ********************* */ publicIntMatrix(int[][] paraMatrix) { data = newint[paraMatrix.length][paraMatrix[0].length];
// Copy elements. for (inti=0; i < data.length; i++) { for (intj=0; j < data[0].length; j++) { data[i][j] = paraMatrix[i][j]; } // Of for j } // Of for i }// Of the second constructor
/** ********************* * The third constructor. Construct a copy of the given matrix. * * @param paraMatrix The given matrix. ********************* */ publicIntMatrix(IntMatrix paraMatrix) { this(paraMatrix.getData()); }// Of the third constructor
/** ********************* * Get identity matrix. The values at the diagonal are all 1. * * @param paraRows The given rows. ********************* */ publicstatic IntMatrix getIdentityMatrix(int paraRows) { IntMatrixresultMatrix=newIntMatrix(paraRows, paraRows); for (inti=0; i < paraRows; i++) { // According to access control, resultMatrix.data can be visited // directly. resultMatrix.data[i][i] = 1; } // Of for i return resultMatrix; }// Of getIdentityMatrix
/** ********************* * Overrides the method claimed in Object, the superclass of any class. ********************* */ public String toString() { return Arrays.deepToString(data); }// Of toString
/** ********************* * Get my data. Warning, the reference to the data instead of a copy of the data * is returned. * * @return The data matrix. ********************* */ publicint[][] getData() { return data; }// Of getData
/** ********************* * Getter. * * @return The number of rows. ********************* */ publicintgetRows() { return data.length; }// Of getRows
/** ********************* * Getter. * * @return The number of columns. ********************* */ publicintgetColumns() { return data[0].length; }// Of getColumns
/** ********************* * Set one the value of one element. * * @param paraRow The row of the element. * @param paraColumn The column of the element. * @param paraValue The new value. ********************* */ publicvoidsetValue(int paraRow, int paraColumn, int paraValue) { data[paraRow][paraColumn] = paraValue; }// Of setValue
/** ********************* * Get the value of one element. * * @param paraRow The row of the element. * @param paraColumn The column of the element. ********************* */ publicintgetValue(int paraRow, int paraColumn) { return data[paraRow][paraColumn]; }// Of getValue
/** ********************* * Add another matrix to me. * * @param paraMatrix The other matrix. ********************* */ publicvoidadd(IntMatrix paraMatrix)throws Exception { // Step 1. Get the data of the given matrix. int[][] tempData = paraMatrix.getData();
// Step 2. Size check. if (data.length != tempData.length) { thrownewException( "Cannot add matrices. Rows not match: " + data.length + " vs. " + tempData.length + "."); } // Of if if (data[0].length != tempData[0].length) { thrownewException( "Cannot add matrices. Rows not match: " + data[0].length + " vs. " + tempData[0].length + "."); } // Of if
// Step 3. Add to me. for (inti=0; i < data.length; i++) { for (intj=0; j < data[0].length; j++) { data[i][j] += tempData[i][j]; } // Of for j } // Of for i }// Of add
/** ********************* * Add two existing matrices. * * @param paraMatrix1 The first matrix. * @param paraMatrix2 The second matrix. * @return A new matrix. ********************* */ publicstatic IntMatrix add(IntMatrix paraMatrix1, IntMatrix paraMatrix2)throws Exception { // Step 1. Clone the first matrix. IntMatrixresultMatrix=newIntMatrix(paraMatrix1);
// Step 2. Add the second one. resultMatrix.add(paraMatrix2);
return resultMatrix; }// Of add
/** ********************* * Multiply two existing matrices. * * @param paraMatrix1 The first matrix. * @param paraMatrix2 The second matrix. * @return A new matrix. ********************* */ publicstatic IntMatrix multiply(IntMatrix paraMatrix1, IntMatrix paraMatrix2)throws Exception { // Step 1. Check size. int[][] tempData1 = paraMatrix1.getData(); int[][] tempData2 = paraMatrix2.getData(); if (tempData1[0].length != tempData2.length) { thrownewException("Cannot multiply matrices: " + tempData1[0].length + " vs. " + tempData2.length + "."); } // Of if
// Step 3. Multiply. for (inti=0; i < tempData1.length; i++) { for (intj=0; j < tempData2[0].length; j++) { for (intk=0; k < tempData1[0].length; k++) { resultData[i][j] += tempData1[i][k] * tempData2[k][j]; } // Of for k } // Of for j } // Of for i
// Step 4. Construct the matrix object. IntMatrixresultMatrix=newIntMatrix(resultData);
return resultMatrix; }// Of multiply
/** ********************* * The entrance of the program. * * @param args Not used now. ********************* */ publicstaticvoidmain(String args[]) { IntMatrixtempMatrix1=newIntMatrix(3, 3); tempMatrix1.setValue(0, 1, 1); tempMatrix1.setValue(1, 0, 1); tempMatrix1.setValue(1, 2, 1); tempMatrix1.setValue(2, 1, 1); System.out.println("The original matrix is: " + tempMatrix1);
/** * Directed graph. Note that undirected graphs are a special case of directed * graphs. * * @author ShiHuai Wen shihuaiwen@outlook.com. */ publicclassGraph { /** * The connectivity matrix. */ IntMatrix connectivityMatrix;
/** ********************* * The first constructor. * * @param paraNumNodes The number of nodes in the graph. ********************* */ publicGraph(int paraNumNodes) { connectivityMatrix = newIntMatrix(paraNumNodes, paraNumNodes); }// Of the first constructor
/** ********************* * The second constructor. * * @param paraMatrix The data matrix. ********************* */ publicGraph(int[][] paraMatrix) { connectivityMatrix = newIntMatrix(paraMatrix); }// Of the second constructor
/** ********************* * Overrides the method claimed in Object, the superclass of any class. ********************* */ public String toString() { StringresultString="This is the connectivity matrix of the graph.\r\n" + connectivityMatrix; return resultString; }// Of toString
/** ********************* * Get the connectivity of the graph. * * @throws Exception for internal error. ********************* */ publicbooleangetConnectivity()throws Exception { // Step 1. Initialize accumulated matrix: M_a = I. IntMatrixtempConnectivityMatrix= IntMatrix.getIdentityMatrix(connectivityMatrix.getData().length);
// Step 3. Determine the actual connectivity. for (inti=0; i < connectivityMatrix.getData().length - 1; i++) { // M_a = M_a + M^k tempConnectivityMatrix.add(tempMultipliedMatrix);
// M^k tempMultipliedMatrix = IntMatrix.multiply(tempMultipliedMatrix, connectivityMatrix); } // Of for i
// Step 4. Check the connectivity. System.out.println("The connectivity matrix is: " + tempConnectivityMatrix); int[][] tempData = tempConnectivityMatrix.getData(); for (inti=0; i < tempData.length; i++) { for (intj=0; j < tempData.length; j++) { if (tempData[i][j] == 0) { System.out.println("Node " + i + " cannot reach " + j); returnfalse; } // Of if } // Of for j } // Of for i
returntrue; }// Of getConnectivity
/** ********************* * Unit test for getConnectivity. ********************* */ publicstaticvoidgetConnectivityTest() { // Test an undirected graph. int[][] tempMatrix = { { 0, 1, 0 }, { 1, 0, 1 }, { 0, 1, 0 } }; GraphtempGraph2=newGraph(tempMatrix); System.out.println(tempGraph2);
System.out.println("Is the graph connected? " + tempConnected); }// Of getConnectivityTest
/** ********************* * The entrance of the program. * * @param args Not used now. ********************* */ publicstaticvoidmain(String args[]) { System.out.println("Hello!"); GraphtempGraph=newGraph(3); System.out.println(tempGraph);