我正在编写矩阵链乘法代码。 在这第一个我正在从用户输入矩阵及其尺寸的输入 然后计算其顺序乘积,然后计算矩阵链顺序 之后,基于矩阵链顺序将矩阵相乘 但是在改变矩阵尺寸时会发生跟随误差。 对于前: 完成乘法和程序成功运行 2矩阵10 * 13 13 * 10 3阶矩阵2 * 3 3 * 2 2 * 2 3个矩阵10 * 13 13 * 10 10 * 13 7个矩阵,每个顺序为12 * 12
矩阵无法通过MCM订单完成产品的最后一步 5个矩阵12 * 4 4 * 16 16 * 9 9 * 12 12 * 15 6个矩阵的顺序为19 * 19和第7个矩阵19 * 20 15个矩阵12 * 12
顺序没有完成 6个矩阵3 * 3 3 * 4 4 * 11 11 * 13 13 * 7 7 * 12
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<time.h>
int n,count;
int **a;
double ***b,***bz;
struct stack
{
int *s;
int top;
};
struct stack st,ss;
void push(struct stack *stk,int item)
{
if(stk->top==(3*n-2)-1)
printf("stack overflow");
stk->top++;
stk->s[stk->top]=item;
}
int pop(struct stack *stk)
{
stk->top--;
return(stk->s[(stk->top)+1]);
}
void init_stack(struct stack *stk)
{
stk->top=-1;
stk->s=(int *) malloc((3*n-2)*sizeof(int));
}
void print_opt_parens(int **s,int i,int j);
void matrix_chain_order(int p[],int length)
{
int n=length-1;
int i,j,k,l,q,**mal,**sal;
mal=(int **) malloc((n)*sizeof(int *));
sal=(int **) malloc((n)*sizeof(int *));
for(i=0;i<=n;i++)
mal[i]=(int *) malloc((n)*sizeof(int));
for(i=0;i<=n;i++)
sal[i]=(int *) malloc(n*sizeof(int));
for(i=0;i<=n;i++)
mal[i][i]=0;
for(l=2;l<=n;l++)
{
for(i=1;i<=n-l+1;i++)
{
j=i+l-1;
mal[i][j]=9999999;
for(k=i;k<=j-1;k++)
{
q=mal[i][k]+mal[k+1][j]+p[i-1]*p[k]*p[j];
if(q < mal[i][j])
{
mal[i][j]=q;
sal[i][j]=k;
}
}
}
}
printf("\n Optimal Number of Operations = %d",mal[1][n]);
printf("\nprinting optimal parenthesis : \n");
print_opt_parens(sal,1,n);
return;
}
void mul(int x,int y);
void print_opt_parens(int **s,int i,int j)
{ int x,y,zz;
if(i==j){
printf(" A%d ",i);
push(&st,i);
}
else
{
printf(" ( ");
push(&st,-1);
print_opt_parens(s,i,s[i][j]);
print_opt_parens(s,s[i][j]+1,j);
printf(" ) ");
x=pop(&st);
y=pop(&st);
mul(x,y);
zz=pop(&st);
if(x<0&&y<0)
push(&st,(x+y));
else if(x>0&&y>0)
push(&st,-(x+y));
else
push(&st,(x*y));
}
}
void init_b(double ***b)
{
int i,j,k;
bz=(double ***) malloc((2*n)*sizeof(double **));
for(i=0;i<n;i++)
bz[i]=(double **) malloc(n*sizeof(double *));
for(i=0;i<n;i++)
for(j=0;j<n;j++)
bz[i][j]=(double *) malloc(n*sizeof(double));
for(i=0;i<n;i++)
for(j=0;j<n;j++)
for(k=0;k<n;k++)
bz[i][j]k]=0.0;
count=-1;
}
void mul(int x,int y)
{
FILE *fp4,*fp5,*fp6;
double **z,**tx,**ty;
int m,l,i,j,k,mm,ll,kk,nn;
if(x<0)
{
mm=pop(&ss);
nn=pop(&ss);
tx=(double **) malloc(nn*sizeof(double));
for(i=0;i<nn;i++)
tx[i]=(double *) malloc(mm*sizeof(double));
for(i=0;i<nn;i++)
for(j=0;j<mm;j++){
tx[i][j]=bz[count][i][j];
}
count--;
}
else
{
mm=a[0][x-1];
nn=a[1][x-1];
tx=(double **) malloc(mm*sizeof(double));
for(i=0;i<mm;i++)
tx[i]=(double *) malloc(nn*sizeof(double));
for(i=0;i<mm;i++)
for(j=0;j<nn;j++){
tx[i][j]=b[x-1][i][j];
}
}
if(y<0)
{
kk=pop(&ss);
ll=pop(&ss);
ty=(double **) malloc(kk*sizeof(double));
for(i=0;i<kk;i++)
ty[i]=(double *) malloc(ll*sizeof(double));
for(i=0;i<kk;i++)
for(j=0;j<ll;j++){
ty[i][j]=bz[count][i][j];
}
count--;
}
else
{
kk=a[0][y-1];
ll=a[1][y-1];
ty=(double **) malloc(kk*sizeof(double));
for(i=0;i<kk;i++)
ty[i]=(double *) malloc(ll*sizeof(double));
for(i=0;i<kk;i++)
for(j=0;j<ll;j++){
ty[i][j]=b[y-1][i][j];
}
}
count++;
bz[count]=(double **) realloc(bz[count],mm*sizeof(double *));
for(i=0;i<mm;i++)
bz[count][i]=(double *) realloc(bz[count][i],ll*sizeof(double));
for(i=0;i<kk;i++)
{
for(j=0;j<nn;j++)
{
bz[count][i][j]=0;
for(k=0;k<mm;k++)
{
bz[count][i][j]+=ty[i][k]*tx[k][j];
}
}
}
fp6=fopen("g.txt","w+");
for(i=0;i<kk;i++)
{
for(j=0;j<nn;j++)
{
fprintf(fp6,"%lf\t",bz[0][i][j]);
}
fprintf(fp6,"\n");
}
push(&ss,nn);
push(&ss,kk);
}
int main()
{
FILE *fp1,*fp2,*fp3;
int i,j,k,l,m,p,q;
double **c,**t;
int *pa;
time_t ts;
srand(time(&ts));
// getting no of matrcies
printf("\n Enter the Number or matrices :");
scanf("%d",&n);
// allocation of space to store matrices of varying rows and columns
a=(int **) malloc(2*sizeof(int));
init_b(bz);
init_stack(&st);
init_stack(&ss);
for(i=0;i<2;i++)
a[i]=(int *) malloc(n*sizeof(int));
printf("\n Enter the rows and columns \n");
for(j=0;j<n;j++)
for(i=0;i<2;i++)
scanf("%d",&a[i][j]);
// verifying the multiplicability of the matrices
for(i=0;i<n-1;i++)
if(a[1][i]!=a[0][i+1])
{
printf("The matrices %d and %d cannot be multiplied",i,i+1);
getch();
exit(0);
}
// actual matrix allocation
b=(double ***) malloc(n*sizeof(double **));
for(i=0;i<n;i++)
b[i]=(double **) malloc(a[0][i]*sizeof(double *));
for(i=0;i<n;i<i++)
for(j=0;j<a[0][i];j++)
b[i][j]=(double *) malloc(a[1][i]*sizeof(double));
// data entry
for(i=0;i<n;i++)
for(j=0;j<a[0][i];j++)
for(k=0;k<a[1][i];k++)
b[i][j][k]=(double)rand()/(double)RAND_MAX;
//file opening
fp1=fopen("b.txt","w");
fp2=fopen("c.txt","w");
//print data
for(i=0;i<n;i++)
{
for(j=0;j<a[0][i];j++)
{
for(k=0;k<a[1][i];k++){
if(fp1!=NULL)
fprintf(fp1,"%lf\t",b[i][j][k]);
printf("%lf\t",b[i][j][k]);
}
printf("\n");
fprintf(fp1,"\n");
}
printf("\n");
fprintf(fp1,"\n");
}
// allocating space for temp, and result variable
c=(double **) malloc(a[0][0]*sizeof(double));
for(i=0;i<a[0][0];i++)
c[i]=(double *) malloc(a[1][1]*sizeof(double));
t=(double **) malloc(a[0][0]*sizeof(double));
for(i=0;i<a[0][0];i++)
t[i]=(double *) malloc(a[1][0]*sizeof(double));
// assigning initial value of t
for(i=0;i<a[0][0];i++)
for(j=0;j<a[1][0];j++)
t[i][j]=(double)b[0][i][j];
// sequential matrix multiplication
for(i=1;i<n;i++)
{
c=(double **) realloc(c,a[0][0]*sizeof(double));
for(m=0;m<a[0][0];m++)
{
c[m]=(double *) realloc(c[m],a[1][i]*sizeof(double));}
for(j=0;j<a[0][0];j++)
{
for(k=0;k<a[1][i];k++)
{
c[j][k]=0.0;
for(l=0;l<a[0][i];l++)
{
c[j][k]+=(double)t[j][l]*(double)b[i][l][k];
}
}
}
t=(double **) realloc(t, a[0][0]*sizeof(double));
for(m=0;m<a[0][i-1];m++)
t[m]=(double *) realloc(t[m],a[1][i]*sizeof(double));
for(m=0;m<a[0][0];m++)
for(p=0;p<a[1][i];p++)
t[m][p]=c[m][p];
}
free(c);
free(t);
// print the result
for(i=0;i<a[0][0];i++)
{
for(j=0;j<a[1][n-1];j++){
if(fp2!=NULL)
fprintf(fp2,"%lf\t",c[i][j]);
printf("%lf\t",c[i][j]);
}
printf("\n");
fprintf(fp2,"\n");
}
// extract the no of rows and columns
pa=(int *) malloc((n+1)*sizeof(int));
pa[0]=a[0][0];
for(i=1;i<n+1;i++)
pa[i]=a[1][i-1];
//Matrix Chain OPerations and Order
matrix_chain_order(pa,n+1);
fclose(fp1);
fclose(fp2);
getch();
return 0;
}