美文网首页
稀疏矩阵

稀疏矩阵

作者: 落幕12 | 来源:发表于2019-03-30 15:39 被阅读0次

一、实验目的

二、实验内容

1. 阅读、理解、调试程序3_1.c,掌握稀疏矩阵的压缩存储算法。

2. 阅读、理解、调试程序3_2.c,理解稀疏矩阵的压缩存储(三元组存储)后的乘法算法。

3.用三元组顺序表存储稀疏矩阵,实现上三角阵的压缩存储。

一.实验目的

1. 掌握特殊矩阵的压缩存储方法。

2.掌握稀疏矩阵的三元组压缩存储方法。

3.掌握稀疏矩阵三元组存储结构的矩阵转置、加法、乘法算法。

二.实验要求与内容

1. 参照课本P68-P74,完成稀疏矩阵三元组压缩存储结构后的转置运算、加法、乘法运算。

2. 完成三带状矩阵的压缩存储,并实现加法运算(乘法运算选做)。

3.(选做)完成下面矩阵压缩存储后的运算:C=A+B,其中,A为下三角矩阵,B为三带状矩阵。

注:以上三题测试矩阵应不少于6×6阶

三.实验步骤

1.数据结构

定义一个三元矩阵,例如a[10][2];a[0][0]储存该矩阵的行数,a[0][1]储存该矩阵的列数,a[0][2]储存该矩阵非0元素的个数。a[i][0]储存非0元素的行,a[i][1]储存非0元素的列。

2.算法设计

矩阵的加法考虑两个矩阵的行数列数是否相同,在同一位置都有值,两个矩阵其中之一在该位置有值。两个矩阵在该位置都没有值的情况不考虑。矩阵的乘法需要矩阵A的列数是否与矩阵B的行数相同,矩阵相乘后的矩阵C在第i行第j列的值是A矩阵的第i行乘以矩阵B的第j行。

三带状矩阵主要考虑压缩,b[s]=1+2*(i-1)+(j-1);

三带状矩阵主要考虑相乘是的合法性,即行数与列数的差值只能为1或者是0;

3.程序

矩阵的加法: for(int i=1;i<=a[0][0];i++)

        {

 for(int j=1;j<=a[0][1];j++)

            {

 if(i==a[s][0] && j==a[s][1] && i==c[t][0] && j==c[t][1])

                {

 d[f][0]=i;

 d[f][1]=j;

 d[f][2]=a[s][2]+c[t][2];

                    f++;

                    t++;

                    s++;

                }

 else if(i==a[s][0] && j==a[s][1])

                {

 d[f][0]=i;

 d[f][1]=j;

 d[f][2]=a[s][2];

                    f++;

                    s++;

                }

 else if(i==c[t][0] && j==c[t][1])

                {

 d[f][0]=i;

 d[f][1]=j;

 d[f][2]=c[t][2];

                    f++;

                    t++;

                }

           }

}

矩阵的乘法:

for(i=1;i<=a[0][0];i++)//第i行

 for(j=1;j<=c[0][1];j++)//第j列

            //矩阵相乘矩阵 a 的第i行*(矩阵c的第1列,第2列,,,,第c[0][1]列;

        {

            sum=0;

 for(int k=1;k<=a[0][2];k++)//开始遍历a;

            {

 if(a[k][0]==i)//找到三元矩阵a中的第i行元素

                {

 for(int l=1;l<=c[0][2];l++)//开始遍历b

                    {

 if(c[l][1]==j && a[k][1]==c[l][0])

 {//找到三元矩阵c中的第j列元素,并且如果要乘积不为0;必须所找到的a的列值等于c的行值;

                            sum=sum+a[k][2]*c[l][2];//累加

 break;

                        }

                    }

                }

            }

 if(sum!=0)

        {

            s++;

 d[s][0]=i;

 d[s][1]=j;

 d[s][2]=sum;

        }

        }

三带状矩阵的加法

  //先将两个矩阵分别压缩存储在两个数组中,再相加

 for(int i=1;i<=m;i++)

    {

 for(int j=1;j<=m;j++)

        {

 cin>>d;

 if(d!=0)

                b[1+2*(i-1)+(j-1)]=d;

        }

    }

 for(int i=1;i<=3*n-3;i++)

            s[i]+=b[i];

三带状矩阵的乘法

 for(i=1;i<=n;i++)//行

        {

 for(j=i-1;j<=i+1;j++)//列

            {

               sum=0;

 if(s[1+2*(i-1)+(j-1)]!=0)

               {

                   y=j;//y是要乘的带状矩阵的列

 if(i==1)//k代表了从第i行的第几个元素开始做乘法,k之前的值都为0,没有必要做乘法

                       k=1;

 else

                       k=i-1;

 for(int w=k;w<=min(i+1,n);w++)//w代表了从第k开始做乘法,,到第i+1结束n-1,当在第n行的时候,k最多取到n

                   {

 if(b[1+2*(w-1)+(y-1)]!=0 && (abs(y-w)==1|| abs(y-w)==0))//判断要乘的那个数是合法的,,即行数与列数相差1或者是0

                    sum=sum+s[1+2*(i-1)+(w-1)]*b[1+2*(w-1)+(y-1)];//需要累加起来

                  }

               }

 if(sum!=0)

                {

                    h[1+2*(i-1)+(j-1)]=sum;

                }

            }

        }

三带状矩阵和下三角矩阵相加:

 for(int i=1;i<=s;i++)

    {

 for(int j=1;j<=s;j++)

        {

 if( i-j==1 || i==j)//当三带状矩阵和小三角矩阵都有值的时候

 cout<<a[i*(i-1)/2+j]+b[1+2*(i-1)+(j-1)]<<" ";

 else if(i

 cout<<b[1+2*(i-1)+(j-1)]<<" ";

 else if(i>j)//当只有三带状矩阵有值的时候

 cout<<a[i*(i-1)/2+j]<<" ";

 else

 cout<<"0 ";

        }

 cout<<endl;

    }

4.程序调试

 

四.结果与体会

稀疏矩阵的三元压缩矩阵乘法需要一定的逻辑性。三带状矩阵的乘法需要考虑到相乘的范围。三带状矩阵与下三角矩阵相加时需要注意各自行列的特点。

五.源程序

1.稀疏矩阵三元组压缩存储结构后的转置运算、加法、乘法运算。

#include<stdio.h>

#include<iostream>

using namespace std;

int a[20][3];

int b[20][3];

int c[20][3];

int d[20][3];

int main()

{

 int n,m,k;

 cout<<"请输入第一个稀疏矩阵的行列数以及非零个数"<<endl;

 cin>>n>>m>>k;

 a[0][0]=n;//行

 a[0][1]=m;//列

 a[0][2]=k;//个数

 cout<<"请输入非零元数的行列坐标及值"<<endl;

 for(int i=1;i<=k;i++)

    {

 cin>>a[i][0]>>a[i][1]>>a[i][2];

    }

   //输出稀疏矩阵

 cout<<"稀疏矩阵如下所示"<<endl;

 int s=1;

 for(int i=1;i<=a[0][0];i++)

    {

 for(int j=1;j<=a[0][1];j++)

        {

 int m=0;

 if(a[s][0]==i && a[s][1]==j)

            {

                m=1;

 cout<<a[s][2]<<" ";

                s++;

            }

 if(m==0)

 cout<<"0 ";

        }

 cout<<endl;

    }

    //矩阵的转置

 b[0][0]=a[0][1];

 b[0][1]=a[0][0];

 b[0][2]=a[0][2];

     s=1;

 for(int i=1;i<=a[0][1];i++)

    {

 for(int j=1;j<=a[0][0];j++)

        {

 if(a[j][1]==i)

            {

 b[s][0]=a[j][1];

 b[s][1]=a[j][0];

 b[s][2]=a[j][2];

                s++;

            }

        }

    }

 cout<<"转置后的稀疏矩阵"<<endl;

     s=1;

 for(int i=1;i<=b[0][0];i++)

     {

 for(int j=1;j<=b[0][1];j++)

     {

 int m=0;

 if(b[s][0]==i && b[s][1]==j)

     {

     m=1;

 cout<<b[s][2]<<" ";

     s++;

     }

 if(m==0)

 cout<<"0 ";

     }

 cout<<endl;

     }

    //稀疏矩阵的加法

 cout<<"请输入第二个稀疏矩阵的行列数以及非零个数"<<endl;

 cin>>n>>m>>k;

 c[0][0]=n;//行

 c[0][1]=m;//列

 c[0][2]=k;//个数

    //cout<<"请输入非零元数的行列坐标及值";

 for(int i=1;i<=k;i++)

    {

 cin>>c[i][0]>>c[i][1]>>c[i][2];

    }

    //第二个矩阵

 cout<<"第二个稀疏矩阵"<<endl;

    s=1;

 for(int i=1;i<=c[0][0];i++)

    {

 for(int j=1;j<=c[0][1];j++)

        {

 int m=0;

 if(c[s][0]==i && c[s][1]==j)

            {

                m=1;

 cout<<c[s][2]<<" ";

                s++;

            }

 if(m==0)

 cout<<"0 ";

        }

 cout<<endl;

    }

 cout<<endl;

    s=1;int t=1;int f=1;

 if(a[0][0]==c[0][0] && a[0][1]==c[0][1])//要进行矩阵的加法运算,两个矩阵的行数和列数必须相等

    {

 d[0][0]=a[0][0];

 d[0][1]=a[0][1];

 for(int i=1;i<=a[0][0];i++)

        {

 for(int j=1;j<=a[0][1];j++)

            {

 if(i==a[s][0] && j==a[s][1] && i==c[t][0] && j==c[t][1])

                {

 d[f][0]=i;

 d[f][1]=j;

 d[f][2]=a[s][2]+c[t][2];

                    f++;

                    t++;

                    s++;

                }

 else if(i==a[s][0] && j==a[s][1])

                {

 d[f][0]=i;

 d[f][1]=j;

 d[f][2]=a[s][2];

                    f++;

                    s++;

                }

 else if(i==c[t][0] && j==c[t][1])

                {

 d[f][0]=i;

 d[f][1]=j;

 d[f][2]=c[t][2];

                    f++;

                    t++;

                }

            }

        }

 d[0][2]=f-1;

    }

 else

 cout<<"不能进行矩阵的加法运算"<<endl;

 if(f!=1)

    {

 cout<<"相加后的矩阵"<<endl;

    s=1;

 for(int i=1;i<=d[0][0];i++)

    {

 for(int j=1;j<=d[0][1];j++)

        {

 int m=0;

 if(d[s][0]==i && d[s][1]==j)

            {

                m=1;

 cout<<d[s][2]<<" ";

                s++;

            }

 if(m==0)

 cout<<"0 ";

        }

 cout<<endl;

    }

    }

    //矩阵乘法;

 if(a[0][1]==c[0][0])

    {

 cout<<"第一个矩阵和第二个矩阵的相乘结果是"<<endl;

    s=0;

 int i,j,sum=0;

 for(i=1;i<=a[0][0];i++)//第i行

 for(j=1;j<=c[0][1];j++)//第j列

            //矩阵相乘矩阵 a 的第i行*(矩阵c的第1列,第2列,,,,第c[0][1]列;

        {

            sum=0;

 for(int k=1;k<=a[0][2];k++)//开始遍历a

 if(a[k][0]==i)//找到三元矩阵a中的第i行元素

 for(int l=1;l<=c[0][2];l++)//开始遍历b

                    {

 if(c[l][1]==j && a[k][1]==c[l][0])

 {//找到三元矩阵c中的第j列元素,并且如果要乘积不为0;必须所找到的a的列值等于c的行值;

                            sum=sum+a[k][2]*c[l][2];//累加

 break;

                        }

            }

 if(sum!=0)

        {

            s++;

 d[s][0]=i;

 d[s][1]=j;

 d[s][2]=sum;

        }

        }

 d[0][0]=a[0][0];

 d[0][1]=c[0][1];

 d[0][2]=s;

    s=1;

 for(int i=1;i<=d[0][0];i++)

    {

 for(int j=1;j<=d[0][1];j++)

        {

 int m=0;

 if(d[s][0]==i && d[s][1]==j)

            {

                m=1;

 cout<<d[s][2]<<" ";

                s++;

            }

 if(m==0)

 cout<<"0 ";

        }

 cout<<endl;

    }

    }

 else

 cout<<"这两个矩阵不能相乘"<<endl;

    return 0;

}

2.三带状矩阵的加法和乘法

#include<iostream>

#include<cmath>

using namespace std;

int main()

{

 int s[50]={0};

 int b[50]={0};

 int h[50]={0};

 int n,m;

 int y,k,sum=0,i,j;

 cout<<"请输入三带矩阵的阶数";

 cin>>n;

 int d;

 for(i=1;i<=n;i++)

    {

 for(j=1;j<=n;j++)

        {

 cin>>d;

 if(d!=0)

                s[1+2*(i-1)+(j-1)]=d;

        }

    }

 cout<<"请输入要加的三带矩阵的阶数";

 cin>>m;

 if(m==n)

    {

 for(i=1;i<=m;i++)

    {

 for(int j=1;j<=m;j++)

        {

 cin>>d;

 if(d!=0)

                b[1+2*(i-1)+(j-1)]=d;

        }

    }

 cout<<"这两个三带状矩阵相乘后结果是:"<<endl;

 for(i=1;i<=n;i++)//行

        {

 for(j=i-1;j<=i+1;j++)//列

            {

               sum=0;

 if(s[1+2*(i-1)+(j-1)]!=0)

               {

                   y=j;//y是要乘的带状矩阵的列

 if(i==1)//k代表了从第i行的第几个元素开始做乘法,k之前的值都为0,没有必要做乘法

                       k=1;

 else

                       k=i-1;

 for(int w=k;w<=min(i+1,n);w++)//w代表了从第k开始做乘法,,到第i+1结束n-1,当在最后一行的时候,k最多取到n

                   {

 if(b[1+2*(w-1)+(y-1)]!=0 && (abs(y-w)==1|| abs(y-w)==0))//判断要乘的那个数是合法的,,即行数与列数相差1或者是0

                    sum=sum+s[1+2*(i-1)+(w-1)]*b[1+2*(w-1)+(y-1)];//需要累加起来

                  }

               }

 if(sum!=0)

                {

                    h[1+2*(i-1)+(j-1)]=sum;

                }

            }

        }

 for(i=1;i<=n;i++)

    {

 for(j=1;j<=n;j++)

        {

 if(s[1+2*(i-1)+(j-1)]!=0 && (abs(j-i)==1|| abs(j-i)==0))

 cout<<h[1+2*(i-1)+(j-1)]<<" ";

 else cout<<" ";

        }

 cout<<endl;

    }

 cout<<"这两个三带状矩阵相加后的结果是:"<<endl;

 for( i=1;i<=3*n-2;i++)

    {

      s[i]+=b[i];

    }

 for(i=1;i<=n;i++)

        {

 for(j=1;j<=n;j++)

            {

 if(s[1+2*(i-1)+(j-1)]!=0 && (abs(j-i)==1|| abs(j-i)==0))

 cout<<s[1+2*(i-1)+(j-1)]<<" ";

 else cout<<" ";

            }

 cout<<endl;

        }

    }

 else

 cout<<"不能进行运算"<<endl;

    return 0;

}

三带状矩阵和下三角矩阵相加

#include<iostream>

#include<stdio.h>

using namespace std;

int main()

{

 int a[50];

 cout<<"请输入下三角矩阵的阶数";

 int n;

 cin>>n;

 int s=(n*(n+1))/2;

 printf("请输入%d个值",s);

 for(int i=1;i<=s;i++)

 cin>>a[i];

 for(int i=1;i<=n;i++)

    {

 for(int j=1;j<=n;j++)

        {

 if(i>=j)

 cout<<a[i*(i-1)/2+j]<<" ";

 else

 cout<<"0 ";

        }

 cout<<endl;

    }

 cout<<"请输入要加的三带矩阵的阶数";

 int m,d;

 int b[20];

 cin>>m;

 for(int i=1;i<=m;i++)

        {

 for(int j=1;j<=m;j++)

            {

 cin>>d;

 if(d!=0)

                    b[1+2*(i-1)+(j-1)]=d;

            }

        }

    s =max(m,n);

 cout<<"两个相加后的结果是"<<endl;

 for(int i=1;i<=s;i++)

    {

 for(int j=1;j<=s;j++)

        {

 if( i-j==1 || i==j)//当三带状矩阵和小三角矩阵都有值的时候

 cout<<a[i*(i-1)/2+j]+b[1+2*(i-1)+(j-1)]<<" ";

 else if(i

 cout<<b[1+2*(i-1)+(j-1)]<<" ";

 else if(i>j)//当只有三带状矩阵有值的时候

 cout<<a[i*(i-1)/2+j]<<" ";

 else

 cout<<"0 ";

        }

 cout<<endl;

    }

    return 0;

}

相关文章

  • 稀疏矩阵

    对于经过ReLU之后的网络,通常存在很多的0。这时如果用稀疏矩阵来表示,则会节省存储空间,或者带来计算上的便利。稀...

  • 稀疏矩阵

    什么是稀疏矩阵矩阵中有很多零,其中非零元素只是占了一小部分,大部分都是零,这种就叫稀疏矩阵。稀疏矩阵概念没有严格的...

  • 稀疏矩阵

    一、实验目的 二、实验内容 1. 阅读、理解、调试程序3_1.c,掌握稀疏矩阵的压缩存储算法。 2. 阅读、理解、...

  • 稀疏矩阵

    #include #include #define ok 1 #define error 0 #define MA...

  • 稀疏矩阵

    在矩阵中,如果数值为0的元素数目远远多于非0元素的数目,并且非0元素分布无规律时,则称该矩阵为稀疏矩阵(spars...

  • 稀疏矩阵

    1.什么是稀疏矩阵?2.什么时候使用稀疏矩阵? 稀疏矩阵就是就是在一个矩阵的的阵列中大多数都是默认数据0为什么使用...

  • 构建邻接矩阵

    构建邻接矩阵 net = spconvert(linklist);%把外部数据转换为稀疏矩阵 稀疏矩阵 对于矩阵 ...

  • 机器学习中的稀疏矩阵

    什么是稀疏矩阵? 大多数元素都是0的矩阵称为稀疏矩阵,否则称为稠密矩阵。规模巨大的稀疏矩阵在应用机器学习中很常见,...

  • MATLAB稀疏矩阵

    7稀疏矩阵 稀疏矩阵是一种特殊类型的矩阵,即矩阵中包括较多的零元素。对于稀疏矩阵的这种特性,在MATLAB中可以只...

  • 稀疏矩阵及其压缩格式

    一般情况下,稀疏矩阵指的是元素大部分是0的矩阵(有些资料定义非零元素不超过5%的矩阵,为稀疏矩阵), 矩阵的稀疏性...

网友评论

      本文标题:稀疏矩阵

      本文链接:https://www.haomeiwen.com/subject/gzxsbqtx.html