矩阵相乘与沃舍尔算法
矩阵相乘
按照教科书的题目设计的程序,给定测试用例如下
(a,c),(b,d),(c,a),(d,b),(e,d)#
bc be ce da eb ec#
ab ac ae ba bc ca cb da ed#
ae ba bd cd da dc ea eb ec ee#
结果放在尾部
#include<stdio.h>
#define SIZE 5
/*输入矩阵*/
void inputMatrix(int matrix[][SIZE]);
/*打印矩阵*/
void printfMatrix(int matrix[][SIZE]);
/*沃舍尔算法,搞错了,是复杂度高的矩阵相乘算法*/
void wosher(int matrix[][SIZE]);
/*两个矩阵求布尔积,该问题都是n*n矩阵,即方阵,并把布尔积保留在result矩阵之中*/
void multiplyMatrix(int tem_matrix[][SIZE],int matrix[][SIZE],int result_matrix[][SIZE]);
/*将后一个矩阵的内容同等赋值给第一个矩阵*/
void copyMatrix(int matrix1[][SIZE],int matrix2[][SIZE]);
/*两个数组去或运算,结果保留在tem数组中*/
void disjunctionMatrix(int matrix1[][SIZE],int matrix2[][SIZE]);
/*真正的Warshall算法*/
void warshall(int matrix[][SIZE]);
int main()
{
int matrix[SIZE][SIZE] = {0};
inputMatrix(matrix);
printf("W0\n");
printfMatrix(matrix);
//wosher(matrix);//矩阵相乘算法
warshall(matrix);//warshall算法
return 0;
}
/*输入矩阵*/
void inputMatrix(int matrix[][SIZE])
{
char str;
char x,y; //记录字符
int flag = 0; //表示当前记录几个字符
scanf("%c",&str);
while(str != '#')
{
if(str >= 'a' && str <= 'e')
{
if(flag == 0)
{
flag = 1;
x = str;
}
else if(flag == 1)
{
y = str;
flag = 2;
}
}
if(flag == 2)
{
matrix[x - 'a'][y - 'a'] = 1;
flag = 0; //将flag置零,重新计数
}
scanf("%c",&str);
}
}
/*打印矩阵*/
void printfMatrix(int matrix[][SIZE])
{
int i,j;
for(i = 0;i < SIZE;i++)
{
for(j = 0;j < SIZE;j++)
printf("%d ",matrix[i][j]);
printf("\n");
}
}
/*沃舍尔算法,搞错了,是复杂度高的矩阵相乘算法*/
void wosher(int matrix[][SIZE])
{
int i;
int tem_matrix[SIZE][SIZE];
int result_matrix[SIZE][SIZE];
copyMatrix(tem_matrix,matrix); //复制原数组到临时数组
for(i = 0; i< SIZE;i++)
{
multiplyMatrix(tem_matrix,matrix,result_matrix); //进行布尔积运算,结果保留在临时数组之中
disjunctionMatrix(tem_matrix,result_matrix);
printf("\nW%d\n",i + 1);
printfMatrix(tem_matrix);
}
}
/*两个矩阵求布尔积,该问题都是n*n矩阵,即方阵,并把布尔积保留在前一个矩阵之中*/
void multiplyMatrix(int tem_matrix[][SIZE],int matrix[][SIZE],int result_matrix[][SIZE])
{
//int result_matrix[SIZE][SIZE] = {0};
int i,j,k;
for(i = 0;i < SIZE;i++)
{
for(j = 0;j < SIZE;j++)
{
result_matrix[i][j] = 0; //初始化为0
for(k = 0;k < SIZE;k++)
{
result_matrix[i][j] += tem_matrix[i][k] * matrix[k][j];
}
if(result_matrix[i][j] > 0) result_matrix[i][j] = 1; //大于等于2的赋值为1
}
}
//copyMatrix(tem_matrix,result_matrix);
}
/*将后一个矩阵的内容同等赋值给第一个矩阵*/
void copyMatrix(int matrix1[][SIZE],int matrix2[][SIZE])
{
int i,j;
for(i = 0;i < SIZE;i++)
for(j = 0;j < SIZE;j++)
matrix1[i][j] = matrix2[i][j];
}
/*两个数组去或运算,结果保留在tem数组中*/
void disjunctionMatrix(int matrix1[][SIZE],int matrix2[][SIZE])
{
int i,j;
for(i = 0;i < SIZE;i++)
{
for(j = 0;j < SIZE;j++)
{
matrix1[i][j] = (matrix1[i][j] || matrix2[i][j]);
}
}
}
/*真正的Warshall算法*/
void warshall(int matrix[][SIZE])
{
int i,j,k;
for(i = 0;i < SIZE;i++)//列
{
for(j = 0;j < SIZE;j++)//行
{
if(matrix[j][i] == 1) //一列一列找,先列后行,ji + ik -->jk
{
for(k = 0;k < SIZE;k++) //遍历第i行
{
matrix[j][k] = matrix[j][k] + matrix[i][k];
if(matrix[j][k] > 0) matrix[j][k] = 1; //防止大于等于1的数字出现
}
}
/*if及里面的语句可以换成如下的语句*/
// for(k = 0;k < SIZE;k++)
// {
// matrix[j][k] = matrix[j][k] | (matrix[j][i] & matrix[i][k]);//通过matrix[j][i] 与 matrix[i][k]找到matrix[j][k]的逻辑值
// }
}
/*以第一个节点为中间点的路径已经寻找完毕*/
printf("\nW%d\n",i + 1);
printfMatrix(matrix);
}
}