矩阵乘法


资源限制
时间限制:1.0s   内存限制:512.0MB
问题描述
  给定一个N阶矩阵A,输出A的M次幂(M是非负整数)
  例如:
  A =
  1 2
  3 4
  A的2次幂
  7 10
  15 22
输入格式
  第一行是一个正整数N、M(1<=N<=30, 0<=M<=5),表示矩阵A的阶数和要求的幂数
  接下来N行,每行N个绝对值不超过10的非负整数,描述矩阵A的值
输出格式
  输出共N行,每行N个整数,表示A的M次幂所对应的矩阵。相邻的数之间用一个空格隔开
样例输入
2 2
1 2
3 4
样例输出
7 10
15 22

首先了解矩阵相乘

矩阵是数的排列

矩阵
矩阵
(这矩阵有2行和3列)

把矩阵与一个数相乘是容易的:

矩阵乘以常数

计算是这样的:
2×4=8 2×0=0
2×1=2 2×-9=-18

我们叫这个数 ("2")为标量,所以这乘法被称为"标量乘法".

矩阵与矩阵相乘

但若要把矩阵与矩阵相乘,我们要计算行与列的"点积"……这是什么意思?我们来看个例子:

求 第一行 和 第一列 的答案:

矩阵乘法点积

"点积" 是把 对称的元素相乘,然后把结果加起来:

(1, 2, 3) • (7, 9, 11) = 1×7 + 2×9 + 3×11 = 58

我们把第一个元素相配(1 和 7),然后相乘。第二个元素(2 和 9) 和第三个元素(3 和 11)也一样,然后把结果加起来。

想多看一个例子?这是第一行与第二列

矩阵乘法下一项

(1, 2, 3) • (8, 10, 12) = 1×8 + 2×10 + 3×12 = 64

第二行 和 第一列也同样做:

(4, 5, 6) • (7, 9, 11) = 4×7 + 5×9 + 6×11 = 139

第二行 和 第二列

(4, 5, 6) • (8, 10, 12) = 4×8 + 5×10 + 6×12 = 154

我们得到:

矩阵乘法完成

做好了

转载自:https://www.shuxuele.com/algebra/matrix-multiplying.html


因为矩阵相乘是矩阵a的第一行的每个数去乘以矩阵b的第一列的每个数,然后乘以第二列的每个数,当列循环完再循环行

就可以暂时写成两个for循环

//行

for(int i = 0;i < n;i++){
//列
for(int j = 0; j < n;j++){
}
}
但是矩阵a是第一行的每个数去乘以矩阵b的第一列每个数,矩阵a的行不变,但是矩阵a的列是变化的,同时矩阵b的列不变,行是在变化的,由因为需要一行循环完才重新开始乘以第一列,所以需要再加一个for循环,就写成
for(int i = 0;i < n;i++){
//列
for(int j = 0; j < n;j++){
//控制第二个维度位置
for(int k = 0;k < n; k++){
res[i][j] += arr[i][k] * new_arr[k][j];
}

}
}

完整代码
public class matrix {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
//初始数组
int[][] arr = new int[n][n];
//结果数组
int[][] new_arr = new int[n][n];
//输入矩阵
for(int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
arr[i][j] = sc.nextInt();
new_arr[i][j] = arr[i][j];
}
}
if (m == 0){
for(int i = 0;i<n;i++){
for (int j = 0;j < n;j++){
if (i == j) System.out.print(1+" ");
else System.out.print(0+" ");
}
System.out.println();
}
}else {
for (int i = 1;i < m;i++){
new_arr = fun(arr,new_arr,n);

}
for(int i = 0;i<n;i++){
for (int j = 0;j<n;j++){
System.out.print(new_arr[i][j]+" ");
}
System.out.println();
}
}

}
public static int[][] fun(int[][] arr, int[][] new_arr, int n){
int[][] res = new int[n][n];
//控制行,每次行循环完,列就查询从0开始
for(int i = 0;i < n;i++){
//列
for(int j = 0; j < n;j++){
//控制第二个维度位置
for(int k = 0;k < n; k++){
res[i][j] += arr[i][k] * new_arr[k][j];
}

}
}
return res;
}
}

 

参考自:https://blog.csdn.net/weixin_43956642/article/details/105651110

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM