初衷
上离散数学课时,老师说这门课和数据结构,算法有很大的联系,建议我们用代码去实现一些定理来简化计算。如利用R的n次幂R^n的定义求R的各次幂,用关系矩阵来表示。作为一个编程爱好者,用代码去实现和简化数学问题,无疑是一件非常有趣的事情。况且矩阵在人口流动问题方面运用矩阵高次幂来预测未来的人口数,人口的发展趋势,以及在经济生活、密码学等方面都有非常巧妙的运用。所以多写写代码对将来的学习还是有好处的。
需求
Java一维数组实现求R^2的关系矩阵M^2。
分析:
- 学会用Java一维数组实现MxP的矩阵A与PxN的矩阵B的乘法运算
- 在1的基础上用Java一维数组实现求R^2的关系矩阵M^2,只是在矩阵相乘相加时有小小的差别
那我们来看看这两步是如何实现的吧!
实现
1、Java一维数组实现MxP的矩阵A与PxN的矩阵B的乘法运算
不多说了,代码我都做了注释,直接上代码吧!相信你一定能够看得懂
class Matrix {
/**
* A为MxP的矩阵,B为PxN的矩阵,A与B的乘积得到MxN的矩阵C
* 两个矩阵能够做乘法,需满足matrixA列和matrixB的行相等,在用一维数组实现矩阵相乘的过程中, 按照习惯,我们喜欢输入行值
* 所以输入一个行值ARowM以确定矩阵A是ARowM行matrixA.length/ARowM列的矩阵,另一个则是
* matrixA.length/ARowM行 matrixB.length/(matrixA.length/ARowM)列的矩阵
* 两矩阵相乘得到的便是ARowM行matrixB.length/(matrixA.length/ARowM)列的矩阵
* @param matrixA 矩阵A
* @param matrixB 矩阵B
* @param ARowM
* @return matrixC:矩阵A与B相乘得到的矩阵C
*/
public double[] matrixMutip(double matrixA[], double matrixB[], int ARowM) {
//判断输入的行数是否能够将数组拆分(符合矩阵相乘的)矩阵
if(matrixA.length%ARowM!=0||matrixB.length%(matrixA.length/ARowM)!=0){
System.out.println("输入的行数无法将数组拆分为符合矩阵相乘的矩阵");
return null;
}
int AColP = matrixA.length / ARowM;// A的列
int BRowP = AColP;// A的列等于B的行
int BColN = matrixB.length / (matrixA.length / ARowM);// B的列
double[] matrixC = new double[ARowM * BColN];
for (int i = 0; i < ARowM; i++) { // 控制C的行,也就是A的行:得到所有行中C的所有列元素
for (int j = 0; j < BColN; j++) { // 控制C的列,也就是B的列:得到一行中C的所有列元素
double temp = 0;// temp用来临时存储矩阵相乘时:A行元素对应相乘B列元素相加得到的结果
for (int k = 0; k < BRowP; k++) {
//计算A行元素对应相乘B列元素相加得到的结果,即得到C的列元素(单个列元素)
temp += matrixA[k + i * AColP] * matrixB[k * BColN + j];
}
matrixC[j * ARowM + i] = temp;
System.out.print(matrixC[j * ARowM + i] + "\t");
}
System.out.println();
}
return matrixC;
}
}
测试代码:
public class Test {
public static void main(String[] args) {
new Matrix().matrixMutip(new double[] { 0, 1, 0, 0, 1, 0, 1, 0, 0,1,0,1 }, new double[] { 0, 1, 0, 0, 1, 0 }, 4);
}
}
测试结果:
为了方便大家更好的理解,我特意给大家画了张图
如果你看不懂上图,可能你的线性代数关于矩阵方面的内容就要加强了。
2、在1的基础上用Java一维数组实现求R^2的关系矩阵M^2
通过1,想必你已经会求矩阵的乘法了。那么如何来实现我们今天的目的呢?先别着急,2个矩阵M之积与普通矩阵乘法还是有些许差别的,差别是,其中的相加为逻辑加,即:1+1=1,1+0=1,0+1=1,0+0=0,(逻辑或)。那么说到这里,你一定已经知道下一步该怎么做了。没错,就是下面的
class Matrix {
/**
* 得到R^2的关系矩阵M^2
* @param matrixdes
* @return matrix:R^2的关系矩阵M^2
*/
public int[] relationalMatrixMultip(int matrixdes[]) {
if (Math.sqrt(matrixdes.length) != (int) Math.sqrt(matrixdes.length)) {
System.out.println("该一维数组不能拆分为方阵");
return null;
}
int matrix[] = new int[matrixdes.length];
int rowOrCol = (int) Math.sqrt(matrixdes.length);
for (int i = 0; i < rowOrCol; i++) {
// 控制行
for (int j = 0; j < rowOrCol; j++) {
// 控制列
int temp = 0;
for (int k = 0; k < rowOrCol; k++) {
// 计算行列相乘相加(逻辑加)的结果,只要第一次出现1,逻辑加(或)的结果就为1,跳出最近的for
if (matrixdes[k + i * rowOrCol] * matrixdes[k * rowOrCol + j] == 1) {
temp = 1;
break;
} else {
temp = 0;
}
}
matrix[i * rowOrCol + j] = temp;
System.out.print(matrix[i * rowOrCol + j] + "\t");
}
System.out.println();
}
return matrix;
}
}
补充分析:
1、由于关系矩阵由0,1两个数码组成,结果亦是如此,所以用传入的数组和返回的结果用int类型的一维数组来存储
2、由于关系矩阵为n阶方阵,关系矩阵为n阶方阵,即一维数组的个数为n^2个,所以第一步先将数组拆分为n行n列的矩阵,这里用rowOrCol变量来表示行或者列
3、接下来的运算过程几乎和1中所讲的过程差不多,只是在第三个for循环做了逻辑加运算,然而在这里有一个小小的技巧,利用逻辑或的运算法则的特点,我们在这里并没有必要真正的做逻辑或运算,只需要判断行列相乘结果第一次出现1就ok了,这样可以减少计算机的运算次数,提高效率。
测试代码:
public class Test {
public static void main(String[] args) {
new Matrix().relationalMatrixMultip(new int[] { 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0 });
}
}
测试结果:
总结:
ok,以上就是实现过程了。在两次实现中,方法都有返回计算的结果和打印输出,打印输出是为了结果更加清晰,而返回结果是因为我们可以利用返回的结果,达到计算n阶矩阵相乘或者计算R^n的目的。
在实现完之后,我看了其他博主写的,发现思路基本差不多。其他博主大多用的二维数组来实现两个矩阵相乘,并未提及到关系矩阵的求法。但实际上,两者求法在本质上没有太大的区别。不管是利用一维数组还是二维数组实现,我们只需要明白数学含义上的矩阵乘法法则,用循环控制和操作数组下标来加以实现就行了。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huerbo2/article/details/79943227