您的位置:首页 > 其它

动态规划(矩阵连乘)

2017-10-09 23:15 155 查看
定义:给定n个矩阵{A1,A2,…,An},其中,Ai与Ai+1是可乘的,i=1,2,….n-1。由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有不同的计算次序。矩阵A和B可乘的条件是矩阵A的列数等于矩阵B的行数。若A是一个p×q矩阵,B是一个q×r矩阵,则其乘积C=AB是一个p×r矩阵。在上述计算C的标准算法中,主要计算量在3重循环,总共需要p×q×r次数乘。

例如:两个矩阵相乘计算:



举例说明:



首先定义一个数组A[MAX][MAX]用来存储一个矩阵的数值。
再定义一个数组B[MAX][MAX]用来存储另一个矩阵的数值。
最后再定义一个数组C[MAX][MAX]用来存储两个矩阵相乘的结果。

有图片可知:
A[0][0]XB[0][0]+A[0][1]XB[1][0]=C[0][0]
A[0][0]XB[0][1]+A[0][1]XB[1][1]=C[0][1]
A[0][0]XB[0][2]+A[0][1]XB[1][2]=C[0][2]
A[1][0]XB[0][0]+A[1][1]XB[1][0]=C[0][0]
A[1][0]XB[0][1]+A[1][1]XB[1][1]=C[0][1]
A[1][0]XB[0][2]+A[1][1]XB[1][2]=C[0][2]
前面提到这个代码需要三重循环:
第一重是矩阵相乘中的A的数据,因为A数组是一行一行与B数组相乘的,所以判断条件是A的行数
第二重是矩阵相乘中的B的数据,因为B数组是一列一列与A数组相乘的,所以判断条件是B的列数
第三重是根据列出的数据得出的规律,由上图可以看出结果是由两部分相加得到的。因此可一在第三重循环前解决前一部分的问题,在第三重循环里面解决第二部分的问题。


#include<stdio.h>
#include<stdlib.h>
#define MAX 100
void MatrixMultiply(int a[][MAX], int b[][MAX], int c[][MAX], int ra, int ca, int rb, int cb)
{
int i, j, k;
int sum = 0;
if (ca != rb)   //如果a的列数不等于b的行数就不能相乘
{
printf("ERROR!");
}
for (i = 0; i < ra; i++) //a是一行一行与b相乘的
{
for (j = 0; j < cb; j++)//b是一行一行与a相乘的
{
sum = a[i][0] * b[0][j];
for (k = 1; k < ca; k++)
{
sum += a[i][k] * b[k][j];//前面的解决的是第一部分的a的列数为0的,b的行数为0的
}   //这行代码解决的是后一部分a的列数大于0的,b的行数大于0的
c[i][j] = sum;
}

}
}

int main(void)
{
int i, j;
int a[MAX][MAX];
int b[MAX][MAX];
int c[MAX][MAX];
int ra, ca;
puts("请输入矩阵A的行与列:");
scanf("%d%d", &ra, &ca);
int rb, cb;
puts("请输入矩阵B的行与列:");
scanf("%d%d", &rb, &cb);
puts("请输入矩阵A的具体数据:");
for (i = 0; i < ra; i++)
{
for (j = 0; j < ca; j++)
{
scanf("%d", &a[i][j]);
}
}
puts("请输入矩阵B的具体数据;");
for (i = 0; i < rb; i++)
{
for (j = 0; j < cb; j++)
{
scanf("%d", &b[i][j]);
}
}
MatrixMultiply(a, b, c, ra, ca, rb, cb);
printf("矩阵相乘的结果:\n");
for (i = 0; i < ra; i++)
{
for (j = 0; j < cb; j++)
{
printf("%d ", c[i][j]);
}
printf("\n");
}
printf("\n");
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: