稀疏矩阵应用.

稀疏矩阵应用.
稀疏矩阵应用.

稀疏矩阵应用

●课题简介

1.1课题及要求

稀疏矩阵应用(限1 人完成)

设计要求:实现三元组,十字链表下的稀疏矩阵的加、转、乘的实现。

(1)稀疏矩阵的存储

(2)稀疏矩阵加法

(3)矩阵乘法

(4)矩阵转置

1.2课程任务分析

本课程设计主要实现在三元组存储结构与十字链表存储结构下输入稀疏矩阵,并对稀疏矩阵进行转置,相加,相乘操作,最后输出运算后的结果。稀疏矩阵采用三元组和十字链表表示,并在两种不同的存储结构下,求两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C;求出A的转置矩阵D,输出D;求两个稀疏矩阵A和B的相乘矩阵E,并输出E。

1.3课程的意义

其意义是让我们在学习完C、数据结构等课程基础上,掌握多维数组的逻辑结构和存储结构、掌握稀疏矩阵的压缩存储及转置,相加,相乘等基本操作,并用不同的方法输出结果,进一步掌握设计、实现较大系统的完整过程,包括系统分析、编码设计、系统集成、以及调试分析,熟练掌握数据结构的选择、设计、实现以及操作方法,为进一步的应用开发打好基础。

●程序分析

2.1设计函数建立稀疏矩阵及初始化值和输出稀疏矩阵的值

本模块要求设计函数建立稀疏矩阵并初始化,包括在三元组结构下和十字链表结构下。首先要定义两种不同的结构体类型,在创建稀疏矩阵时,需要设计两个不同的函数分别在三元组和十字链表下创建稀疏矩阵,在输入出现错误时,能够对错误进行判别处理,初始化稀疏矩阵都为空值,特别注意在十字链表下,对变量进行动态的地址分配。在设计输出稀疏矩阵的值的函数时,也要针对两种不同的情况,分别编制函数,才能准确的输出稀疏矩阵。在对稀疏矩阵进行初始化及输出值时,均只输出非零元素的值和它所在的所在行及所在列。

2.2构造函数进行稀疏矩阵的转置并输出结果

本模块要求设计函数进行稀疏矩阵的转置并输出转置后的结果,由于对稀疏函数的转置只对一个矩阵进行操作,所以实现起来难度不是很大,函数也比较容易编写。在编写函数时,要先定义一个相应的结构体变量用于存放转置后的矩阵,最后把此矩阵输出。

2.3构造函数进行两个稀疏矩阵相加及相乘并输出最终的稀疏矩阵

本模块要求设计相加和相乘函数对两个矩阵进行运算,并输出最终的稀疏矩阵,在进行运算前,要对两个矩阵进行检查,看是不是相同类型的矩阵,因为两个矩阵相加要求两个矩阵一定是同一类型的矩阵,定义相应的矩阵类型用于存放两个矩阵相加相乘后的结果矩阵,这个结果矩阵的行数列数需要综合多方面情况来确定。这四个函数也是整个程序的难点,需要灵活运用数组及指针的特点。

2.4退出系统

本模块要求设置选项能随时结束程序的运行,本程序中采用exit(0)函数。程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入演示程序中需要的相关信息及命令。

概要设计

3.1主界面设计

为了实现在两种存储结构下对稀疏矩阵的多种算法功能的管理,首先设计一含有多个菜单项的主控菜单子程序以链接系统的各项子功能,方便用户交互式使用本系统。

本系统主控菜单运行界面如图1所示。

图1主界面图

3.2存储结构设计

本系统采用三元组结构和十字链表结构存储稀疏矩阵的具体信息。其中:在三元组中,所有元素的信息用数组表示,每个数组元素中包含有行下标(i),列下标(j)和对应的数值(e),它们是整型数据,全部的信息用在十字链表中,全部结点的信息用结构体(TSMatrix)包含,包括用数组(Triple data[MAXSIZE])和总共的行数(mu),列数(nu)以及非零元素的个数(tu)。在十字链表下,头结点为指针数组的十字链表存储;每个结点里面包含行下标(i),列下标(j)和对应的数值(e),它们是整型数据,还有两个指针(right)、(down),属于OLNode结构体。全部的信息用结构体(crosslist)包含,包括指针数组(OLink* rhead和*chead)和总共的行数(mu),列数(nu)以及非零元素的个数(tu)。

三元组结构体定义:

typedef struct{

int i,j;

int e;

}Triple;

typedef struct{

Triple data[MAXSIZE];

int rpos[MAXSIZE + 1];

int nu,mu,tu;

}TSMatrix;

十字链表结构体定义:

typedef struct OLNode{

int i,j;

int e;

struct OLNode *right,*down;

}OLNode,*OLink;

typedef struct {

int mu,nu,tu;

OLink *rhead,*chead;

}CrossList;

3.3系统功能设计

本系统除了要完成分别在三元组存储结构以及在十字链表下实现稀疏矩阵的初始化功能外还设置了4个子功能菜单。稀疏矩阵的建立及初始化在三元组存储结构下,由函数void CreateSMatrix(TSMatrix&M)实现,在十字链表存储结构下,由函数void CreateSMatix_OL(CrossList&M)依据读入的行数和列数以及非零元素的个数,分别设定每个非零元素的信息。4个子功能的设计描述如下。

(1)稀疏矩阵的转置:

此功能在三元组存储结构下,由函数void TransposeSMatrix(TSMatrix M,TSMatrix &T)实现,在十字链表存储结构下,由函数void TurnSMatrix_OL(CrossList &M)实现。当用户选择该功能,系统提示用户初始化一个矩阵,然后进行转置,最终输出结果。

(2)稀疏矩阵的加法:

此功能在三元组存储结构下,由函数void AddTMatix(TSMatrix M,TSMatrix T,TSMatrix &S)实现,在十字链表存储结构下,由函数int SMatrix_ADD(CrossList *A,CrossList *B)实现。当用户选择该功能,系统即提示用户初始化要进行加法的两个矩阵的信息。然后进行加法,最后输出结果。

(3)稀疏矩阵的乘法:

此功能在三元组存储结构下,由函数int MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)实现。在十字链表存储结构下,由函数int MultSMatrix_OL(CrossList M, CrossList N, CrossList

&Q)实现。当用户选择该功能,系统提示输入要进行相乘的两个矩阵的详细信息。然后进行相乘,最后得到结果。

(4)退出:

即退出稀疏矩阵的应用系统,由exit(0)函数实现。当用户选择该功能,则退出该稀疏矩阵的应用系统。

调试分析

4.1系统运行主界面

系统运行主界面如图2所示:

图2 主界面图

4.2 各子功能测试运行结果

(以三元组为例)

(1)稀疏矩阵的创建及初始化:

在主菜单下,用户输入1回车,是用三元组创建稀疏矩阵,根据屏幕提示初始化一个稀疏矩阵,按enter键,运行结果如图3所示。

图3 三元组创建并初始化矩阵

(2)稀疏矩阵的转置:

用三元组创建稀疏矩阵后,用户输入1回车,便显示该矩阵的转置矩阵,运行结果如图4所示。

图4 三元组稀疏矩阵转置结果示意图

(3)稀疏矩阵的相加:

用三元组创建并初始化一个稀疏矩阵后,输入2回车,按屏幕提示输入第二个同类型的稀疏矩阵,按enter键,运行结果如图5所示。

图5 三元组稀疏矩阵相加结果示意图

(4)稀疏矩阵的相乘:

用三元组创建并初始化一个稀疏矩阵后,输入3回车,按屏幕提示输入第二个同类型的稀疏矩阵,按enter键,运行结果如图6所示。

图6三元组稀疏矩阵相乘结果示意图

(5)退出:

在主菜单下,用户输入3回车,或者在下级菜单中输入4回车,退出程序。运行结果如图7,图8。

图7 主菜单退出程序图

图8 下级菜单退出程序图

总结

由于本程序要求用两种办法对稀疏矩阵进行运算,特别是用十字链表这种形式来对稀疏矩

阵进行运算,是实现起来有很多困难,主要包括:

1、书上这种方面的东西不多,资料少,可以参考的东西不是很多;

2、用十字链表进行运算比较复杂,难度较大,需要对指针掌握较好;

3、在书写课程设计报告时,没有具体的模板,感觉无从下手。

针对上述困难,我通过网络,图书馆找资料,借鉴别人的以往的优秀的课程设计报告,和同学们一起讨论,逐步地解决自己的问题。

通过此次课程设计,使我对本学期学的《数据结构》有了更深的了解,也使自己的所学更加牢固,并能够把更方面的知识综合起来运用。

附录:程序源代码

#include

#include

#define MAXSIZE 100

int num[100];

typedef struct OLNode{

int i,j;

int e;

struct OLNode *right,*down;

}OLNode,*OLink;

typedef struct {

int mu,nu,tu;

OLink *rhead,*chead;

}CrossList; //十字链表结构体定义

typedef struct{

int i,j;

int e;

}Triple;

typedef struct{

Triple data[MAXSIZE];

int rpos[MAXSIZE + 1];

int nu,mu,tu;

}TSMatrix; //三元组结构体定义;

int CreateSMatix_OL(CrossList &M){

int i,j,e;

OLink q;

OLink p;

printf("请输入稀疏矩阵的行数,列数,非零元素的个数:"); //矩阵行数,列数下标均从开始;

scanf("%d%d%d",&M.mu,&M.nu,&M.tu);

M.rhead=(OLink *)malloc((M.mu+1)*sizeof(OLNode));//分配内存空间

M.chead=(OLink *)malloc((M.nu+1)*sizeof(OLNode));//分配内存空间

for( i=1;i<=M.mu;i++)M.rhead[i]=NULL;//把矩阵每个元素置空值

for( i=1;i<=M.nu;i++)M.chead[i]=NULL;

printf("请输入稀疏矩阵,如果行为0,则退出\n");

scanf("%d%d%d",&i,&j,&e);

while(i!=0){

p=(OLink)malloc(sizeof(OLNode));

p->i=i;p->j=j;p->e=e;

if(M.rhead[i]==NULL||M.rhead[i]->j>j){p->right=M.rhead[i];M.rhead[i]=p;}

else{

q=M.rhead[i];

while(q->right&&q->right->jright;

p->right=q->right;

q->right=p;}

if(M.chead[j]==NULL||M.chead[j]->i>i){p->down=M.chead[j];M.chead[j]=p;}

else{

q=M.chead[j];

while(q->down&&q->down->idown;

p->down=q->down;

q->down=p;

}

scanf("%d%d%d",&i,&j,&e);

}

return 1;

}//创建十字链表

void CreateSMatrix(TSMatrix &M){

//采用三元组顺序表存储表示,创建稀疏矩阵M

printf("请输入稀疏矩阵的行数、列数和非零元个数:");

scanf("%d%d%d",&M.mu,&M.nu,&M.tu);

if((M.mu<=0)||(M.nu<=0)||(M.tu<=0)||(M.tu>M.mu*M.nu))

//判断行值、列值、元素个数是否合法

printf("输入有误!");

for(int i=1;i<=M.tu;i++){//输入稀疏矩阵元素

printf("请输入元素坐标(所在行,所在列)及大小:");

scanf("%d%d%d",&M.data[i].i,&M.data[i].j,&M.data[i].e);

if((M.data[i].i<=0)||(M.data[i].j<=0)){

printf("输入错误,请重新输入");

scanf("%d%d%d",&M.data[i].i,&M.data[i].j,&M.data[i].e);

}//if

}//for i

int num[100];

if(M.tu)

{int i;

for(i = 1; i <= M.mu; i++) num[i] = 0;//初始化

for(int t = 1; t <= M.tu; t++) ++num[M.data[t].i];//求M中每一行含非零元素个数

//求rpos

M.rpos[1] = 1;

for(i = 2; i <= M.mu; i++) M.rpos[i] = M.rpos[i-1] + num[i-1];

}

}//创建三元组

void TransposeSMatrix(TSMatrix M,TSMatrix &T){

T.nu=M.mu;//T矩阵存放转置后的矩阵

T.mu=M.nu;

T.tu=M.tu;

int q=1;

for(int col=1;col<=M.nu;col++)//通过循环,把非零元素的行数与列数进行交换,实现转置

for(int p=1;p<=M.tu;p++)

if(M.data[p].j==col){

T.data[q].i=M.data[p].j;

T.data[q].j=M.data[p].i;

T.data[q].e=M.data[p].e;

q++;

}

}//三元组转置

int Compare(int a1,int b1,int a2,int b2){

if(a1>a2)return 1;

else if(a1

else if(b1>b2)return 1;

if(b1

else return 0;

}

void AddTMatix(TSMatrix M,TSMatrix T,TSMatrix &S){//矩阵S存放相加后的矩阵

S.mu=M.mu>T.mu?M.mu:T.mu;//对S矩阵的行数赋值

S.nu=M.nu>T.nu?M.nu:T.nu;//对S矩阵的列数赋值

S.tu=0;

int ce;

int q=1;int mcount=1,tcount=1;

while(mcount<=M.tu&&tcount<=T.tu){

switch(Compare(M.data[mcount].i,M.data[mcount].j,T.data[tcount].i,T.data[tcount].j)) //用switch分支语句,用compare函数对需要相加的两个矩阵的某元素行数列数进行比较{case -1: S.data[q].e=M.data[mcount].e;//当M.data[mcount].i

M.data[mcount].j

S.data[q].i=M.data[mcount].i;

S.data[q].j=M.data[mcount].j;//把第一个矩阵的行数i,列数j赋值给S矩阵的行数i,列数j

q++;

mcount++;

break;

case 1: S.data[q].e=T.data[tcount].e;//当M.data[mcount].i>T.data[tcount].i或

M.data[mcount].j>T.data[tcount].j

S.data[q].i=T.data[tcount].i;

S.data[q].j=T.data[tcount].j;//把第二个矩阵的行数i,列数j赋值给S矩阵的行数i,列数j

q++;

tcount++;

break;

case 0: ce=M.data[mcount].e+T.data[tcount].e;//其他情况下把两个矩阵的值相加

if(ce){ S.data[q].e=ce;

S.data[q].i=M.data[mcount].i;

S.data[q].j=M.data[mcount].j;

q++;

mcount++;

tcount++;}

else {mcount++;

break;

}}

while(mcount<=M.tu){

S.data[q].e=M.data[mcount].e;

S.data[q].i=M.data[mcount].i;

S.data[q].j=M.data[mcount].j;

q++;

mcount++; }//在case=-1的情况下对S矩阵的非零值,行数,列数进行赋值

while(tcount<=M.tu){

S.data[q].e=T.data[tcount].e;

S.data[q].i=T.data[tcount].i;

S.data[q].j=T.data[tcount].j;

q++;

tcount++;

}//在case=1的情况下对S矩阵的非零值,行数,列数进行赋值

S.tu=q-1;

}//三元组相加

int MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)

{ int arow, brow, ccol, i, t, ctemp[100], p, q, tp;//定义相乘函数中所需要用到的变量if(M.nu != N.mu) return 0;//如果第一个矩阵的行数不等于第二个矩阵的列数,则退出

Q.mu = M.mu, Q.nu = N.nu, Q.tu = 0;//三元组结构类型Q存放相乘后的结果

if(M.tu * N.tu != 0)//如果两个矩阵元素相乘不为零,则进行运算

{for(arow = 1; arow <= M.mu; ++arow)//最外侧循环以矩阵行数作为循环变量

{ for(i = 0; i <= N.nu; ++i) ctemp[i] = 0;

Q.rpos[arow] = Q.tu + 1;

if(arow < M.mu) tp = M.rpos[arow + 1];

else tp = M.tu +1;

for(p = M.rpos[arow]; p < tp; ++p)//把每行与每列相乘

{brow = M.data[p].j;

if(brow < N.mu) t = N.rpos[brow+1];

else t = N.tu + 1;

for(q = N.rpos[brow]; q < t; ++q)

{ccol = N.data[q].j;

ctemp[ccol] += M.data[p].e * N.data[q].e;//值相乘

}

}

for(ccol = 1; ccol <= Q.nu; ++ccol) //把运算后的结果存放到Q中

{ if(ctemp[ccol])

{if(++(Q.tu) > MAXSIZE) return 1;

Q.data[Q.tu].i = arow, Q.data[Q.tu].j = ccol, Q.data[Q.tu].e = ctemp[ccol];

}

}

}

}

return 1;

}//三元组相乘

void ShowTMatrix(TSMatrix M){

for(int col=1;col<=M.mu;col++)//通过双重循环,把稀疏矩阵中不为零的元素的行数、列数和值

for(int p=1;p<=M.tu;p++)

if(M.data[p].i==col)printf("%4d %4d %4d\n",M.data[p].i,M.data[p].j,M.data[p].e);

}//三元组显示

void TurnSMatrix_OL(CrossList &M){

int col,row; //定义循环变量

OLink p,q; //定义OLink结构类型变量

for(col=1;col<=M.mu;col++) //通过循环,把非零元素的行数与列数进行交换,实现转置{ q=p=M.rhead[col];

while(q){

row=p->i;

p->i=p->j;

p->j=row;

q=p->right;

p->right=p->down;

p->down=q;

}

}

}//十字链表转置

int SMatrix_ADD(CrossList *A,CrossList *B){

OLNode *pa,*pb,*pre,*p,*cp[100]; //定义OLNode类型的变量

int i,j,t;

t=A->tu+B->tu;

for(j=1;j<=A->nu;j++)cp[j]=A->chead[j];//将A矩阵的列表头指针赋给cp数组

for(i=1;i<=A->mu;i++){

pa=A->rhead[i];

pb=B->rhead[i];//将A,B矩阵的行表头指针分别赋给pa,pb

pre=NULL;

while(pb){//当pb不等于零

if(pa==NULL||pa->j>pb->j){

p=(OLink)malloc(sizeof(OLNode));//给p动态分配空间

if(!pre)A->rhead[i]=p;

else pre->right=p;

p->right=pa;

pre=p;

p->i=i;p->j=pb->j;p->e=pb->e;

if(!A->chead[p->j]){

A->chead[p->j]=cp[p->j]=p;

p->down=NULL;

}//如果A->chead[p->j]不等于零,则把p赋给它及cp[p->j]

else{

cp[p->j]->down=p;

cp[p->j]=p;

}

pb=pb->right;

}//否则把p赋给cp[p->j]

else if(pa->jj){pre=pa;

pa=pa->right;}

else if(pa->e+pb->e){

t--;

pa->e+=pb->e;

pa=pa->right;

pb=pb->right;}

else { t=t-2;

if(!pre)A->rhead[i]=pa->right;

else pre->right=pa->right;

p=pa;pa=pa->right;

if(A->chead[p->j]==p)A->chead[p->j]=cp[p->j]=p->down;

else cp[p->j]->down=p->down;

free(p);

pb=pb->right;

}

}

}

A->mu=A->mu>B->mu?A->mu:B->mu;

A->nu=A->nu>B->nu?A->nu:B->nu;//A的行与列为A及B当中较大的一个

return 1;

}//十字链表相加

int MultSMatrix_OL(CrossList M, CrossList N, CrossList &Q)

{

int i, j, e; //中间变量

OLink p0, q0, p, pl, pla; //中间变量

if(M.nu != N.mu) //检查稀疏矩阵M的列数和N的行数是否对应相等

{

printf ( "稀疏矩阵A的列数和B的行数不相等,不能相乘。\n" );

return 0;

}

Q.mu = M.mu, Q.nu = N.nu, Q.tu = 0;

if(!(Q.rhead = (OLink *)malloc((Q.mu + 1) * sizeof(OLink)))) exit(-2);

if(!(Q.chead = (OLink *)malloc((Q.nu + 1) * sizeof(OLink)))) exit(-2);

for(i = 1; i <= Q.mu; i++) Q.rhead[i] = NULL;

for(i = 1; i <= Q.nu; i++) Q.chead[i] = NULL;

//相乘

for(i =1; i <= Q.mu; i++)

for(j = 1; j <= Q.nu; j++)

{

p0 = M.rhead[i], q0 = N.chead[j], e = 0;

while(p0&&q0) //M第i行和N第j列有元素

{if( p0->j > q0->i) q0 = q0->down; //M的列大于N的行,则N的列指针后移else if(p0->j < q0->i) p0 = p0->right;//M的列小于N的行,则M的行指针右移

else { //M的行等于N的列

e += p0->e * q0->e; //乘积累加

q0 = q0->down, p0 = p0->right; //移动指针

}

}

if(e) //乘积不为

{if(!(p = (OLink)malloc(sizeof(OLNode)))) exit(-2);

Q.tu++;//非零元素增加

p->i = i, p->j = j, p->e = e, p->right = NULL, p->down = NULL;//赋值,指针后移//将p插入十字链表,行插入

if(Q.rhead[i] == NULL) //若p为该行的第个结点

Q.rhead[i] = pl = p; //p插在该行的表头且pl指向p(该行的最后一个结点)

else pl->right = p, pl = p; //插在pl所指结点之后,pl右移

//列插入

if(Q.chead[j] == NULL) //若p为该列的第一个结点

Q.chead[j] = p; //该列的表头指向p

else {//插在列表尾

pla = Q.chead[j];//pla指向j行的第个结点

while(pla->down) pla = pla->down;//pla指向j行最后一个结点

pla->down = p;

}

}

}

return 1;

}//十字链表相乘

int ShowMAtrix(CrossList *A){

int col;

OLink p;

for(col=1;col<=A->mu;col++)if(A->rhead[col]){p=A->rhead[col];

while(p){printf("%3d%3d%3d\n",p->i,p->j,p->e);p=p->right;}

}

return 1;

}//十字链表显示

void main(){

int n,i;

TSMatrix M,T,S;

CrossList MM,TT,SS;

printf(" ***稀疏矩阵应用***");

printf("\n请你选择创建稀疏矩阵的方法:\n1:用三元组创建稀疏矩阵\n2:用十字链表创建稀疏矩阵\n3:退出程序");

printf("\n");

scanf("%d",&n);

switch(n){

case 1:

CreateSMatrix(M);

printf("您输入的稀疏矩阵为(只列出非零元素):\n 行列大小\n");

ShowTMatrix(M);

printf("已经选择三元组创建稀疏矩阵,请选择操作:\n1:稀疏矩阵转置\n2:稀疏矩阵相加\n3:稀疏矩阵相乘\n4:退出程序\n");

scanf("%d",&i);

switch(i){

case 1:TransposeSMatrix(M,T);

printf("转置后的矩阵为(只列出非零元素):\n 行列大小\n");

ShowTMatrix(T);

break;

case 2:printf("请你输入另一个稀疏矩阵:");

CreateSMatrix(T);

AddTMatix(M,T,S);

printf("相加后的矩阵为(只列出非零元素):\n 行列大小\n");

ShowTMatrix(S);

break;

case 3:printf("请你输入另一个稀疏矩阵:");

CreateSMatrix(T);

MultSMatrix(M,T,S);

printf("相乘后的矩阵为(只列出非零元素):\n 行列大小\n");

ShowTMatrix(S);

break;

case 4:

exit(0);};break;

case 2:{CreateSMatix_OL(MM);

printf("您输入的稀疏矩阵为(只列出非零元素):\n 行列大小\n");

ShowMAtrix(&MM);

printf("已经选择十字链表创建稀疏矩阵,请选择操作:\n1:稀疏矩阵转置\n2:稀疏矩阵相加\n3:稀疏矩阵相乘\n4:退出程序\n");

scanf("%d",&i);

switch(i){

case 1:

TurnSMatrix_OL(MM);

printf("转置后的矩阵为(只列出非零元素):\n 行列大小\n");

ShowMAtrix(&MM);

break;

case 2:

printf("请你输入另一个稀疏矩阵:");

CreateSMatix_OL(TT);

SMatrix_ADD(&MM,&TT);

printf("相加后的矩阵为(只列出非零元素):\n 行列大小\n");

ShowMAtrix(&MM);break;

case 3:printf("请你输入另一个稀疏矩阵:");

CreateSMatix_OL(TT);

MultSMatrix_OL(MM,TT,SS);

printf("相乘后的矩阵为(只列出非零元素):\n 行列大小\n");

ShowMAtrix(&SS);break;

case 4:exit(0);

}};break;

case 3:exit(0);

default :printf("erorr");

}

}

数据结构与算法 特殊矩阵和稀疏矩阵

常熟理工学院 《数据结构与算法》实验指导与报告书 _2017-2018_____学年第__1__ 学期 专业:物联网工程 实验名称:特殊矩阵和稀疏矩阵 实验地点: N6-210 指导教师:聂盼红 计算机科学与工程学院 2017

实验五特殊矩阵和稀疏矩阵 【实验目的】 1、掌握数组的结构类型(静态的内存空间配置);通过数组的引用下标转换成该数据在内存中的地址; 2、掌握对称矩阵的压缩存储表示; 3、掌握稀疏矩阵的压缩存储-三元组表表示,以及稀疏矩阵的转置算法。 【实验学时】 2学时 【实验预习】 回答以下问题: 1、什么是对称矩阵?写出对称矩阵压缩存储sa[k]与aij之间的对应关系。 若n阶矩阵A中的元素满足下述性质:a ij=a ji,则称为n阶对称矩阵。 sa[k]与矩阵元素a ij之间存在着一一对应的关系: 若i>=j,k=i*(i+1)/2+j; 若i=j。 对称矩阵为3,9,1,4,7 9,5,2,5,8 1,2,5,2,4 4,5,2,1,7 7,8,4,7,9

数据结构稀疏矩阵基本运算实验报告

课程设计 课程:数据结构 题目:稀疏矩阵4 三元组单链表结构体(行数、列数、头) 矩阵运算重载运算符优 班级: 姓名: 学号: 设计时间:2010年1月17日——2010年5月XX日 成绩: 指导教师:楼建华

一、题目 二、概要设计 1.存储结构 typedef struct{ int row,col;//行,列 datatype v;//非0数值 }Node; typedef struct{ Node data[max];//稀疏矩阵 int m,n,t;//m 行,n 列,t 非0数个数 … … 2.基本操作 ⑴istream& operator >>(istream& input,Matrix *A)//输入 ⑵ostream& operator <<(ostream& output,Matrix *A){//输出 ⑶Matrix operator ~(Matrix a,Matrix b)//转置 ⑷Matrix operator +(Matrix a,Matrix b)//加法 ⑸Matrix operator -(Matrix a,Matrix b)//减法 ⑹Matrix operator *(Matrix a,Matrix b)//乘法 ⑺Matrix operator !(Matrix a,Matrix b)//求逆 三、详细设计 (1)存储要点 position[col]=position[col-1]+num[col-1]; 三元组表(row ,col ,v) 稀疏矩阵((行数m ,列数n ,非零元素个数t ),三元组,...,三元组) 1 2 3 4 max-1

稀疏矩阵的建立与转置

实验2 稀疏矩阵的建立与转置 一、实验目的 掌握特殊矩阵的存储和操作算法。 二、实验内容及问题描述 实现用三元组保存稀疏矩阵并实现矩阵转置的算法。 三、实验步骤 1. 定义稀疏矩阵的三元组形式的存储结构。 2. 实现三元组矩阵的传统转置算法。 3. 实现三元组矩阵的快速转置算法。 4. 输入矩阵非零元素,测试自己完成的算法。 四、程序流程图

五、概要设计 矩阵是很多的科学与工程计算中研究的数学对象。在此,我们感兴趣的是,从数学结构这门学科着眼,如何存储矩阵的元从而使矩阵的各种运算有效的进行。本来,用二维数组存储矩阵,在逻辑上意义是很明确的,也很容易理解,操作也很容易和方便。但是在数值分析中经常出现一些阶数很高的矩阵,同时,在矩阵中又有很多值相同或者都为零的元素,可以对这种矩阵进行压缩存储:对多个值相同的元素只分配一个存储空间;对零元素不分配空间。稀疏矩阵的定义是一个模糊的定义:即非零元个数较零元个数较少的矩阵。例如下图所示的矩阵 为一个稀疏矩阵。为了实现稀疏矩阵的这种存储结构,引入三元组这种数据结构。三元组的线性表顺存储形式如下图: 六、详细设计 sanyuanzu.h 头文件 #define max 100 typedef struct { int row,col; int e; }Triple;//定义三元组 typedef struct { Triple data[max]; int mu,nu,tu; }TSMatrix;///*定义三元组的稀疏矩阵*/ void creat( TSMatrix &M) ; void fasttrans(TSMatrix A,TSMatrix &B);

数据结构实验稀疏矩阵计算器

‘ 实验报告 题目:稀疏矩阵运算器 班级:14电子商务平台建设班完成日期:2015.11.2 学号:姓名:孙少辉 学号:姓名:杨德龙 学号:姓名:柴益新 一:需求分析 稀疏矩阵是指那些多数元素为零的矩阵。利用“稀疏“特点进行存储和计算可以大大节省存储空间,提高计算效率。实现一个能进行稀疏矩阵基本运算的运算器。 【基本要求】 以“带行逻辑链接信息“的三元组顺序表示稀疏矩阵,实现两个矩阵相加、相减和相乘运算。稀疏矩阵的输入采用三元组表示,而运算结果的矩阵则以通常阵列形式列出。 【项目约束】 1.首先应输入矩阵的行数和列数,并判断给出的两个矩阵 行、列数对于所要求作的运算是否相匹配。可设矩阵的行数和 列数均不超过20。 2.程序可以对三元组的输入顺序加以限制,例如,按行优 先。注意研究教科书5.3.2节中的算法,以便提高计算效率。

3.在用三元组稀疏矩阵时,相加或相减所得结果矩阵应该另生 成,乘积矩阵也可用二维数组存放。 三:详细设计 1:数据结构的定义 元素类型、变量、指针类型 (1)项目数据表: 3.2子函数 3:函数调用关系 无函数调用关系,只有一个主函数 四:调试分析 三元组顺序的输入规则。以0 0 0 作为输入的结束信号。完成实现稀疏矩阵的相加、相减、相乘的运算。 五:用户使用说明 (1)首先运行文件系统 1.首先定义要运算的第一个稀疏矩阵的行列数

定义完成之后输入另一个要运算的稀疏矩阵的行列。 (2)输入信息: 如下图所示输入两个矩阵的元素

所有输入信息以及运算方法输入完成之后。回车直接算出结果(3)输出信息:

六、源代码 /** ***项目名称:稀疏矩阵的运算 ***设计者:杨德龙,柴益新,孙少辉 ***时间:2015.11.02 ***实现目标:实现矩阵的加法,减法,乘法;***/ #include #include int main() { //定义二维数组及用到的各种变量 int a[20][20];

数据结构课程设计之稀疏矩阵实现与应用1

数据结构课程设计报告 题目:十字链表成为存储结构,实现稀疏矩阵的求和运算 学生姓名:张旋 班级:软件三班学号:201213040304 指导教师: 吴小平

一、需求分析 1.问题描述: 要求:十字链表下的稀疏矩阵的加、转、乘的实现。 2.基本功能 实现十字链表下的转置,乘法,加法运算。 3.输入输出 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。 (4)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。 (5)构造函数进行稀疏矩阵的转置,并输出结果。 (6)退出系统。 二、概要设计 1.设计思路: 本实验要求在三元组,十字链表下实现稀疏矩阵的加、转、乘。首先要进行矩阵的初始化操作,定义三元组和十字链表的元素对象。写出转置,加法,乘法的操作函数。通过主函数调用实现在一个程序下进行矩阵的运算操作。 2.数据结构设计: 抽象数据类型稀疏矩阵的定义如下: ADT SparseMatrix{ 数据对象:D={aij | i=1,2,…,m; j=1,2,..,n; aij∈Elemset, m和n分别称为矩阵的行数和列数。} 数据关系:R={Row,Col} Row={ | 1<=i<=m, 1<=j<=n-1} Col= { | 1<=i<=m-1, 1<=j<=n} 基本操作: CreateSMatrix(&M); 操作结果:创建稀疏矩阵M。 DestroySMatrix(&M); 初始条件:稀疏矩阵M存在。操作结果:销毁稀疏矩阵M。 PrintSMatrix(M); 初始条件:稀疏矩阵M存在。操作结果:输出稀疏矩阵M。 AddSMatrix(M,N,&Q); 初始条件:稀疏矩阵M与N的行数和列数对应相等操作结果:求稀疏矩阵的和Q=M+N。 MultSMatrix(M,N,&Q); 初始条件:稀疏矩阵M的列数等于N的行数。操作结果:求稀疏矩阵乘积Q=M*N。 TransposeSMatrix(M,&T); 初始条件:稀疏矩阵M存在。操作结果:求稀疏矩阵M的转置矩阵T。 }ADT SparseMatrix 3.软件结构设计:

矩阵的简单应用1

2.6矩阵的简单应用(1) 学习目标: 1、初步了解高阶矩阵; 2、了解矩阵的简单应用。 活动过程: 活动一:矩阵在数学领域中的简单应用 例1:已知盒子A 中装有3只大小和重量相同的小球,其中2只黑色,1只白色;盒子B 中 装有5只大小和重量相同的小球,其中3只黑色,2只白色。假定A ,B 两个盒子很难分辨,而且可以任取一个,现在要求先取一个盒子,那么从中摸到一只黑色小球的概率有多大? 例2:如图所示的是A ,B ,C 这3个城市间的交通情况,小月想从其中某一个城市出发直 达另一个城市,她可以有几种选择? 小结:网络图,结点,一级路矩阵,二级路矩阵的定义。 例3:已知一级路矩阵???? ??????002001210表示一个网络图,它的结点分别是A ,B ,C ,试画出满足条件的一个网络图。

活动二:矩阵在实际生产、生活中的简单应用 例4:某运动服销售店经销A,B,C,D4种品牌的运动服,其中尺寸分别有S(小号)、M (中号)、L(大号)、XL(特大号)4种,一天内,该店的销售情况如表所示(单位:件): 假设不同品牌的运动服的平均利润是A为20元/件,B为15元/件,C为30元/件,D为25元/件,问:M号的运动服在这天获得的总利润是多少? 活动五:课堂小结与自主检测 1、已知某蛋糕厂生产甲、乙、丙3种蛋糕,其配料用量分别如下表(单位:kg)。已知水 果、奶油、白糖、面粉的单价分别为5,8,2,2.5,(单位:元/kg),试计算甲、乙、丙3

2、写出图示网络表示的一级路矩阵(图(2)的圆圈表示自己到自己有一条路)。 图(1) 3、假设某市的天气分为晴和阴两种状态,若今天晴,则明天晴的概率为43,阴的概率为41 ;若今天阴,则明天晴的概率为31,阴的概率为32 。这些概率可以通过观察某市以往几年 每天天气的变化趋势来确定,通常将用矩阵来表示的这种概率叫做转移概率,对应的矩阵叫做转移矩阵,而将这种以当前状态来预测下一时段状态的概率模型称做马尔可夫链。下面给出的是转移矩阵M 和其对应的马尔可夫变换图。问:如果清晨天气预报报告今天阴的概率为21,那么明天的天气预报会是什么?后天呢? ?? ??? ? = 3 24 13143M 阴 晴阴晴明天今天 (1) (2) 4、现有甲、乙两种细菌,它们会相互突变。每1min ,甲种细菌突变为乙种细菌的概率为0.3,乙种细菌突变为甲种细菌的概率为0.9,而未突变的细菌仍然是原来的细菌。已知开始时有甲种细菌300万个,乙种细菌500万个。 (1)细菌突变的转移矩阵是多少? (2)3min 后,甲种和乙种细菌各是多少? 4 3 32

稀疏矩阵(算法与数据结构课程设计)

稀疏矩阵 一、问题描述 假若在n m ?阶中,有t 个元素不为零,令n m t ?=δ称为矩阵的稀疏因子。通常认为≤δ0.05时称为稀疏矩阵。稀疏矩阵的研究大大的减少了数据在计算机中存储所需的空间,然而,它们的运算却与普通矩阵有所差异。通过本次实验实现稀疏矩阵的转置、加法和乘法等多种运算。 二、基本要求 1、稀疏矩阵采用三元组表示,建立稀疏矩阵,并能按矩阵和三元组方式输出; 2、编写算法,完成稀疏矩阵的转置操作; 3、编写算法,完成对两个具有相同行列数的稀疏矩阵进行求和操作; 4、编写算法,对前一矩阵行数与后一矩阵列数相等的两个矩阵,完成两个稀疏矩阵的相乘操作。 三、测试数据 1、转置操作的测试数据: ??????? ? ?00200013000010020100 2、相加操作的测试数据: ??????? ? ?002000130000100 20100 ??????? ??00200010000210030300 3、相乘操作的测试数据: ?????? ? ??000000030040 0021 ??????? ??001002000021 四、算法思想 1、三元组结构类型为Triple ,用i 表示元素的行,j 表示元素的列,e 表示元素值。稀疏矩阵的结构类型为TSMatrix ,用数组data[]表示三元组,mu 表示行数,nu 表示列数,tu 表示非零元个数。 2、稀疏矩阵转置的算法思想 将需要转置的矩阵a 所有元素存储在三元组表a.data 中,按照矩阵a 的列序来转置。

为了找到a的每一列中所有非零元素,需要对其三元组表a.data扫描一遍,由于a.data 是以a的行需序为主序来存放每个非零元的,由此得到的就是a的转置矩阵的三元组表,将其储存在b.data中。 3、稀疏矩阵相加的算法思想 比较满足条件(行数及列数都相同的两个矩阵)的两个稀疏矩阵中不为0的元素的行数及列数(即i与j),将i与j都相等的前后两个元素值e相加,保持i,j不变储存在新的三元组中,不等的则分别储存在此新三元组中。最后得到的这个新三元组表就是两个矩阵的和矩阵的三元组表。 4、稀疏矩阵相乘的算法思想 两个相乘的矩阵为M与N,对M中每个元素M.data[p](p=1,2,…,M.tu),找到N中所有满足条件M.data[p].j=N.data[q].i的元素N.data[q],求得M.data[p].v和N.data[q].v 的乘积,又T(i,j)=∑M(i,k)×N(k,j),乘积矩阵T中每个元素的值是个累计和,这个乘积M.data[p].v×N.data[q].v只是T[i][j]中的一部分。为便于操作,应对每个元素设一累计和的变量,其初值是零,然后扫描数组M,求得相应元素的乘积并累加到适当的求累计和的变量上。由于T中元素的行号和M中元素的行号一致,又M中元素排列是以M的行序为主序的,由此可对T进行逐行处理,先求得累计求和的中间结果(T的一行),然后再压缩存储到Q.data中去。 五、模块划分 1、Status CreateM(TSMatrix *M, int a[],int row, int col),创立三元组; 2、void PrintM(TSMatrix M),按数组方式输出; 3、void PrintM3(TSMatrix M),按三元组方式输出; 4、Status TransposeSMatrix(TSMatrix M, TSMatrix *T),稀疏矩阵的转置; 5、Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix *Q),稀疏矩阵加法; 6、Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix *Q),稀疏矩阵相乘; 7、main(),主函数。 六、数据结构//(ADT) 1、三元组结构类型 typedef struct { int i,j; ElemType e; } Triple; 2、稀疏矩阵 typedef struct { Triple data[MAXSIZE+1];

稀疏矩阵在迭代求解线性方程组中的运用

稀疏矩阵在迭代求解线性方程组中的运用 学院:自动化院 专业:电力系统及其自动化 姓名:张庆磊 学号:111101112 指导老师:杨伟

摘要:对于稀疏矩阵的稀疏存储技术进行了研究,研究了按行存储的检索方式,以便于迭代计算,分别对雅克比法和高斯—赛特法的算法进行理论研究和程序实现,并且比较了两种方法的优劣。 关键词:系数技术;线性方程;迭代 大型稀疏矩阵线性化方程组的求解问题,在电力系统中有着广泛的的运用。由于电力网本身的结构限制,节点导纳矩阵节点繁多,而仅有少量的非零元,稀疏度很高,若采用传统存储计算方式,会占用大量的存储空间,并且降低运算效率。在迭代计算中,由于无法分辨零元素,也会无谓地浪费运算时间。因此稀疏技术在求解方程组中的运用显得尤为重要。 1.稀疏矢量与稀疏矩阵的存储 稀疏矢量与稀疏矩阵的存储特点是排零存储,即只存储其中的非零元和有关的检索信息.存储的目的是为了在计算中方便的访问和运用,这就要求既节省内存,又便于搜索。论文采用了按行存储格式。 按行顺序依次存储A 中的非零元,同一行元素依次排列在一起,存储格式: V A ——按行存储矩阵A 中的非零元ij a ,共τ个; JA ——按行存储矩阵A 中的非零元的列号,共τ个; IA ——记录A 中每行第一个非零元在V A 中的位置,共n 个。 2.迭代法求解线性方程 设n n n n R b R A ∈∈?,,考虑线性方程组 Ax=b 一般的,先将式1变为同解方程组 X=Bx+f 形成迭代式 f Bx x k k +=+)()1( 式中:B 为迭代矩阵; 若要求迭代式收敛则需满足1B 1)(<<或B ρ,其中?为任意范数 式1中,A 可以分裂为 A=M+N (1)

简单实用的基于Java的矩阵类

简单实用的Java矩阵基本操作。包括新建、打印、加、减、乘、转置、求逆运算。import java.util.Random; public class Matrix { public int row; public int rank; public double[][] mat; public Matrix(int a, int b) { row = a; rank = b; mat = new double[row][rank]; } public void New(){ Random rand=new Random(); for (int i = 0; i < row; i++) for (int j = 0; j < rank; j++) mat[i][j]=rand.nextInt(100); } public void Output() { System.out.println("Matrix=:"); for (int i = 0; i < row; i++) { for (int j = 0; j < rank; j++) System.out.print(mat[i][j] + " "); System.out.println(); } System.out.println(); } public Matrix Plus(Matrix a) { Matrix c=new Matrix(row,rank); if (a.row == row && a.rank == rank) { for (int i = 0; i < row; i++) for (int j = 0; j < rank; j++) c.mat[i][j] = mat[i][j] + a.mat[i][j]; } else { System.out.println("matrixAdd error!"); } return c; } public Matrix Minus(Matrix a) { Matrix c=new Matrix(row,rank); if (a.row == row && a.rank == rank) {

数据结构实验报告稀疏矩阵运算

教学单位计算机科学与技术 学生学号 5 数据结构 课程设计报告书 题目稀疏矩阵运算器 学生豹 专业名称软件工程 指导教师志敏

实验目的:深入研究数组的存储表示和实现技术,熟悉广义表存储结构的特性。 需要分析:稀疏矩阵是指那些多数元素为零的矩阵。利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算效率。实现一个能进行稀疏矩阵基本运算的运算器。要求以带“行逻辑信息”的三元组顺序表存储稀疏矩阵,实现两矩阵的相加、相减、相乘等运算。输入以三元组表示,输出以通常的阵列形式列出。 软件平台:Windows 2000,Visual C++ 6.0或WINTC 概要设计:ADT Array { 数据对象: D = {aij | 0≤i≤b1-1, 0 ≤j≤b2-1} 数据关系: R = { ROW, COL } ROW = {| 0≤i≤b1-2, 0≤j≤b2-1} COL = {| 0≤i≤b1-1, 0≤ j≤b2-2} 基本操作: CreateSMatrix(&M); //操作结果:创建稀疏矩阵M. Print SMatrix(M); //初始化条件: 稀疏矩阵M存在. //操作结果:输出稀疏矩阵M. AddSMatrix(M,N,&Q); //初始化条件: 稀疏矩阵M与N的行数和列数对应相等. //操作结果:求稀疏矩阵的和Q=M+N. SubSMatrix(M,N,&Q); //初始化条件: 稀疏矩阵M与N的行数和列数对应相等. //操作结果:求稀疏矩阵的差Q=M-N. MultSMatrix(M,N,&Q); //初始化条件: 稀疏矩阵M的列数等于N的行数. //操作结果:求稀疏矩阵的乘积Q=M*N. } ADT Array

数据结构课后习题及解

数据结构课后习题及解析第五章

第五章习题 5.1 假设有6行8列的二维数组A,每个元素占用6个字节,存储器按字节编址。已知A的基地址为 1000,计算: 数组A共占用多少字节; 数组A的最后一个元素的地址; 按行存储时元素A 36 的地址; 按列存储时元素A 36 的地址; 5.2 设有三对角矩阵A n×n ,将其三条对角线上的元素逐行地存于数组B(1:3n-2)中,使得B[k]= a ij , 求: (1)用i,j表示k的下标变换公式; (2)用k表示i,j的下标变换公式。 5.3假设稀疏矩阵A和B均以三元组表作为存储结构。试写出矩阵相加的算法,另设三元组表C存放 结果矩阵。 5.4在稀疏矩阵的快速转置算法5.2中,将计算position[col]的方法稍加改动,使算法只占用一个 辅助向量空间。 5.5写一个在十字链表中删除非零元素a ij 的算法。 5.6画出下面广义表的两种存储结构图示: ((((a), b)), ((( ), d), (e, f))) 5.7求下列广义表运算的结果: (1)HEAD[((a,b),(c,d))]; (2)TAIL[((a,b),(c,d))]; (3)TAIL[HEAD[((a,b),(c,d))]]; (4)HEAD[TAIL[HEAD[((a,b),(c,d))]]]; (5)TAIL[HEAD[TAIL[((a,b),(c,d))]]];

实习题 若矩阵A m×n 中的某个元素a ij 是第i行中的最小值,同时又是第j列中的最大值,则称此元素为该 矩阵中的一个马鞍点。假设以二维数组存储矩阵,试编写算法求出矩阵中的所有马鞍点。 第五章答案 5.2设有三对角矩阵A n×n,将其三条对角线上的元素逐行的存于数组B[1..3n-2]中,使得B[k]=a ij,求:(1)用i,j表示k的下标变换公式;(2)用k表示i、j的下标变换公式。 【解答】(1)k=2(i-1)+j (2) i=[k/3]+1, j=[k/3]+k%3 ([ ]取整,%取余) 5.4在稀疏矩阵的快速转置算法5.2中,将计算position[col]的方法稍加改动,使算法只占用一个辅助向量空间。 【解答】算法(一) FastTransposeTSMatrix(TSMartrix A, TSMatrix *B) {/*把矩阵A转置到B所指向的矩阵中去,矩阵用三元组表表示*/ int col,t,p,q; int position[MAXSIZE]; B->len=A.len; B->n=A.m; B->m=A.n; if(B->len>0) { position[1]=1; for(t=1;t<=A.len;t++) position[A.data[t].col+1]++; /*position[col]存放第col-1列非零元素的个数, 即利用pos[col]来记录第col-1列中非零元素的个数*/ /*求col列中第一个非零元素在B.data[ ]的位置,存放在position[col]中*/ for(col=2;col<=A.n;col++) position[col]=position[col]+position[col-1]; for(p=1;p

矩阵分解及其简单应用

矩阵分解是指将一个矩阵表示为结构简单或具有特殊性质若干矩阵之积或之和,大体分为三角分解、分解、满秩分解和奇异值分解.矩阵地分解是很重要地一部分内容,在线性代数中时常用来解决各种复杂地问题,在各个不同地专业领域也有重要地作用.秩亏网平差是测量数据处理中地一个难点,不仅表现在原理方面,更表现在计算方面,而应用矩阵分解来得到未知数地估计数大大简化了求解过程和难度. 矩阵地三角分解 如果方阵可表示为一个下三角矩阵和一个上三角矩阵之积,即,则称可作三角分解.矩阵三角分解是以消去法为根据导出地,因此矩阵可以进行三角分解地条件也与之相同,即矩阵地前个顺序主子式都不为,即.所以在对矩阵进行三角分解地着手地第一步应该是判断是否满足这个前提条件,否则怎么分解都没有意义.矩阵地三角分解不是唯一地,但是在一定地前提下,地分解可以是唯一地,其中是对角矩阵.矩阵还有其他不同地三角分解,比如分解和分解,它们用待定系数法来解求地三角分解,当矩阵阶数较大地时候有其各自地优点,使算法更加简单方便.资料个人收集整理,勿做商业用途 矩阵地三角分解可以用来解线性方程组.由于,所以可以变换成,即有如下方程组:资料个人收集整理,勿做商业用途 先由依次递推求得,,……,,再由方程依次递推求得,,……,. 资料个人收集整理,勿做商业用途 必须指出地是,当可逆矩阵不满足时,应该用置换矩阵左乘以便使地个顺序主子式全不为零,此时有:资料个人收集整理,勿做商业用途 这样,应用矩阵地三角分解,线性方程组地解求就可以简单很多了. 矩阵地分解 矩阵地分解是指,如果实非奇异矩阵可以表示为,其中为正交矩阵,为实非奇异上三角矩阵.分解地实际算法各种各样,有正交方法、方法和方法,而且各有优点和不足.资料个人收集整理,勿做商业用途 .正交方法地分解 正交方法解求分解原理很简单,容易理解.步骤主要有:)把写成个列向量(,,……,),并进行正交化得(,,……,);) 单位化,并令(,,……,),(,,……,),其中;). 这种方法来进行分解,过程相对较为复杂,尤其是计算量大,尤其是阶数逐渐变大时,就显得更加不方便.资料个人收集整理,勿做商业用途 .方法地分解 方法求分解是利用旋转初等矩阵,即矩阵()来得到地,()是正交矩阵,并且(()).()地第行第列 和第行第列为,第行第列和第行第列分别为和,其他地都为.任何阶实非奇异矩阵可通过左连乘()矩阵(乘积为)化为上三角矩阵,另,就有.该方法最主要地是在把矩阵化为列向量地基础上找出和,然后由此把矩阵地一步步向上三角矩阵靠近.方法相对正交方法明显地原理要复杂得多,但是却计算量小得多,矩阵()固有地性质很特别可以使其在很多方面地应用更加灵活.资料个人收集整理,勿做商业用途 .方法地分解 方法分解矩阵是利用反射矩阵,即矩阵,其中是单位列向量,是正交矩阵,.可以证明,两个矩阵地乘积就是矩阵,并且任何实非奇异矩阵可通过连乘矩阵(乘积为)化为上三角矩阵,则.这种方法首要地就是寻找合适地单位列向量去构成矩阵,

数据结构C语言版-稀疏矩阵的三元组顺序表存储表示和实现

typedef int ElemType; // 稀疏矩阵的三元组顺序表存储表示 #define MAXSIZE 100 // 非零元个数的最大值 typedef struct { int i,j; // 行下标,列下标 ElemType e; // 非零元素值 }Triple; typedef struct { Triple data[MAXSIZE+1]; // 非零元三元组表,data[0]未用 int mu,nu,tu; // 矩阵的行数、列数和非零元个数 }TSMatrix; // 创建稀疏矩阵M int CreateSMatrix(TSMatrix *M) { int i,m,n; ElemType e; int k; printf("请输入矩阵的行数,列数,非零元素个数:(逗号)\n"); scanf("%d,%d,%d",&(*M).mu,&(*M).nu,&(*M).tu); (*M).data[0].i=0; // 为以下比较顺序做准备 for(i = 1; i <= (*M).tu; i++) { do { printf("请按行序顺序输入第%d个非零元素所在的行(1~%d)," "列(1~%d),元素值:(逗号)\n", i,(*M).mu,(*M).nu); scanf("%d,%d,%d",&m,&n,&e); k=0; // 行或列超出范围 if(m < 1 || m > (*M).mu || n < 1 || n > (*M).nu) k=1; if(m < (*M).data[i-1].i || m == (*M).data[i-1].i && n <= (*M).data[i-1].j) // 行或列的顺序有错 k=1; }while(k);

数据结构 稀疏矩阵相乘问题

#include #include #define OK 1 #define ERROR 0 #define MAXSIZE 25 //最多非0元素的个数 #define MAXR 5 //rpos所能处理的最大行数 #define MAXC 5 //系数矩阵相乘时,保留临时列结果的数组temp[MAXC] typedef struct NODE{ //定义稀疏矩阵结点 int i; int j; int data; } Node; typedef struct MATRIX{ //定义稀疏矩阵(可以快速访问) int mu, nu, tu; Node matrix[MAXSIZE+1]; int rpos[MAXR+1]; } Matrix; int CreatSMatrix( Matrix* M ); //创建一个矩阵(由用户输入原始矩阵,转化为稀疏矩阵方式储存) int Print( Matrix M ); //打印一个稀疏矩阵 int Mul_SMatrix( Matrix M, Matrix N, Matrix *Q); //两个稀疏矩阵相乘 main(){ printf("计科四班刘辉学号:41012169"); printf("\n"); printf("稀疏矩阵相乘"); printf("\n\n"); Matrix A1, A2, A3; //定义矩阵 CreatSMatrix( &A1 ); CreatSMatrix( &A2 ); if( A1.nu==A2.mu ){ //判断能否相乘 Mul_SMatrix( A1, A2, &A3 ); printf("两矩阵相乘得:\n"); Print(A3); } system("pause"); } //稀疏矩阵相乘 int Mul_SMatrix( Matrix M, Matrix N, Matrix *Q) { int i,Mj;

数据结构三元组表存储结构实现稀疏矩阵应用课程方案实验报告

高二《数系的扩充与复数的概念》说课稿 高二《数系的扩充与复数的概念》说稿 《数系的扩充与复数的概念》是北师大版普通高中程标准数学实验教材选修1-2第四第一节的内容,大纲时安排一时。主要包括数系概念的发展简介,数系的扩充,复数相关概念、分类、相等条,代数表示和几何意义。 复数的引入是中学阶段数系的又一次扩充,引入复数以后,这不仅可以使学生对于数的概念有一个初步的、完整的认识,也为进一步学习数学打下了基础。通过本节学习,要使学生在问题情境中了解数系扩充的过程以及引入复数的必要性,学习复数的一些基本知识,体会人类理性思维在数系扩充中的作用。 在学习了这节以后,学生首先能知道数系是怎么扩充的,并且这种扩充是必要的,虚数单位公开《数系的扩充与复数的概念》说稿在数系扩充过程中的作用,而复数就是一个实数加上一个实数乘以公开《数系的扩充与复数的概念》说稿。学生能清楚的知道一个复数什么时候是虚数,什么时候是纯虚数,两个复数相等的充要条是什么。让学生在经历一系列的活动后,完成对知识的探索,变被动地“接受问题”为主动地“发现问题”,加强学生对知识应用的灵活性,深化学生对复数的认识,从而提高分析问题和解决问题的能力。 教学目标为:1.在问题情境中了解数系的扩充过程。体会实际需求与数学内部的矛盾(数的运算规则、方程求根)在数系扩充过程中的

作用,感受人类理性思维的作用以及数与现实世界的联系。. 2.理解复数的有关概念、数系间的关系、和几何表示。 3.掌握复数的分类和复数相等的条。 4体会类比、转化、数形结合思想在数学发现和解决数学问题中的作用。 教学重点为认识i的意义、复数的有关概念以及复数相等的条. 教学难点为复数相关概念的理解和复数的几何意义的理解 复数的概念是整个复数内容的基础,复数的有关概念都是围绕复数的代数表示形式展开的。虚数单位、实部、虚部的命名,复数想等的充要条,以及虚数、纯虚数等概念的理解,都应促进对复数实质的理解,即复数实际上是一有序实数对。类比实数可以用数轴表示,把复数在直角坐标系中表示出,就得到了复数的几何表示,这就把数和形有机的结合了起。 在学习本节的过程中,复数的概念如果单纯地讲解或介绍会显得较为枯燥无味,学生不易接受,教学时,采用讲解已学过的数集的扩充的历史,让学生体会到数系的扩充是生产实践的需要,也是数学学科自身发展的需要;介绍数的概念的发展过程,使学生对数的形成、发展的历史和规律,各种数集中之间的关系有着比较清晰、完整的认识从而让学生积极主动地建构虚数的概念、复数的概念、复数的分类。由于学生对数系扩充的知识不熟悉,对了解实数系扩充到复数系的过程有困难,也就是对虚数单位公开《数系的扩充与复数的概念》说稿的引入难以理解。另外虚数单位公开《数系的扩充与复数的概念》说

数据结构C语言版-稀疏矩阵三元组的基本操作

数据结构 课程设计实验报告 内容名称:稀疏矩阵的基本操作成员1:09213020-陈东 成员2:09213040-蔡丹 班级:09数31 教师:李晓翠 江苏师范大学 数学科学学院

目录 1.序言 (3) 1.1数据结构背景 (3) 1.2课程设计目的 (3) 1.3 课程名称 (3) 1.4设计要求 (3) 1.5设计说明 (3) 2.课程任务设计说明书 (5) 3.需求分析 (6) 3.1题目名称 (6) 3.2题目内容 (6) 3.3题目分析 (6) 4.概要设计 (7) 4.1稀疏矩阵存储结构 (7) 4.2.稀疏矩阵的基本操作 (7) 4.3各模块设计要求 (8) 4.4总体功能流程图 (9) 4.4.1存储结构流程图 (9) 4.4.2稀疏矩阵基本操作流程图 (10) 5.详细设计 (11) 5.1设计原理 (11) 5.2基本函数实现流程图 (13) 6.主要函数代码 (21) 7.调试与操作说明 (27) 7.1操作说明 (27) 7.2调试结果………………………………………………………………………………. ..28 7.3结果分析 (31) 8.设计体会 (32) 9.参考文献 (32) 10.分工说明 (33)

1.序言 1.1数据结构背景 数据结构是一门理论性强、思维抽象、难度较大的课程,是基础课和专业课之间的桥梁。该课程的先行课程是计算机基础、程序设计语言、离散数学等,后续课程有操作系统、编译原理、数据库原理、软件工程等。通过本门课程的学习,我们应该能透彻地理解各种数据对象的特点,学会数据的组织方法和实现方法,并进一步培养良好的程序设计能力和解决实际问题的能力,而且该课程的研究方法对我们学生在校和离校后的学习和工作,也有着重要的意义。 数据结构是计算机科学与技术专业的一门核心专业基础课程,在该专业的课程体系中起着承上启下的作用,学好数据结构对于提高理论认知水平和实践能力有着极为重要的作用。学习数据结构的最终目的是为了获得求解问题的能力。对于现实世界中的问题,应该能从中抽象出一个适当的数学模型,该数学模型在计算机内部用相应的数据结构来表示,然后设计一个解此数学模型的算法,再进行编程调试,最后获得问题的解答。 基于此原因,我们开设了数据结构课程设计。针对数据结构课程的特点,着眼于培养我们的实践能力。实习课程是为了加强编程能力的培养,鼓励学生使用新兴的编程语言。相信通过数据结构课程实践,无论是理论知识,还是实践动手能力,同学们都会有不同程度上的提高。 1.2课程设计的目的 巩固和深刻理解―数据结构(C语言版)‖课程所讲解的C语言作为数据结构的算法的描述,掌握对数据的存储结构和算法进行描述时,尽量考虑C 语言的特色。培养学生独立工作和创新思维的能力,取得设计与调试的实践经验。提高和加强计算机应用及软件开发能力。通过课程设计题目的练习,强化学生对所学知识的掌握及对问题分析和任务定义的理解,对每到题目作出了相应的逻辑分析和数据结构的选择,通过对任务的分析,为操作对象定义相应的数据结构,以过程化程序设计的思想方法为原则划分各个模块,定

矩阵的简单应用 (5)

1.掌握网络图、一级路矩阵、二级路矩阵的定义. 2.了解矩阵的简单应用. [基础·初探] 1.矩阵的相关知识 (1)矩阵的概念及表示方法. (2)矩阵的计算:二阶矩阵与平面列向量的乘法,两个二阶矩阵之间的乘法. (3)常见的几何变换:恒等、伸压、反射、旋转、投影及切变变换,掌握它们的矩阵表示. (4)二阶矩阵对应的几何变换均是线性变换. (5)矩阵的乘法的几何意义在于对应变换的复合. (6)矩阵的乘法满足结合律,但不满足交换律、消去律. (7)逆矩阵的概念:掌握哪些(变换对应的)矩阵是可逆的,投影变换矩阵是重要的不可逆矩阵的例子. (8)利用逆矩阵公式或者行列式法求逆矩阵;从几何变换上分析二元一次方程组的解. (9)特征值与特征向量的概念、求法及其应用. 2.网络图与路矩阵 (1)在数学中,通常把像如图2-6-1这样表示关系的图形称为网络图,其中的交点A,B,C称为结点.

图2-6-1 (2)网络图所对应的反映从一个结点直达另一个结点的交通情况的矩阵叫做一级路矩阵,而从某个结点出发,先经过一个结点,再到达另外一个结点的交通情况的矩阵称为二级路矩阵. (3)一级路矩阵与二级路矩阵的区别在于从一个结点到另一个结点是直达,还是间接到达. 右图对应的一级路矩阵M =, 二级路矩阵N =. 3.求解矩阵应用题的方法及技巧 对于应用题,我们要读懂题意,如果还没弄清题意就去做题,则很容易出错.应用题主要考查分析能力、转化能力及运算能力.因此,我们要加强这方面能力的培养与训练,在解与矩阵有关的应用题时,要学会寻找分析问题和解决问题的突破口,在解题中提高自己的综合能力. 4.种群问题的数学模型 教材P 78例6种群问题的数学模型. ???? ??a n +1b n +1=M ??????a n b n =?? ????a b c d ???? ?? a n b n ,其中{a n },{b n }表示两个相互影响的种群X ,Y 随时间段变化的数量.若起初的种群数量β=?????? a 1 b 1,则经过n 个时段后的种群数量 为??????a n +1b n +1,且??????a n +1b n +1=M n ?????? a 1 b 1 .若矩阵M 的特征值λ1,λ 2对应的特征向量分别为 α1, α2,且β=m α1+k α2,m ∈R ,k ∈R ,则???? ??a n +1b n +1=M n ??????a 1b 1=M n β=M n (m α1+k α2)=

高中数学学案:矩阵的简单应用

高中数学学案:矩阵的简单应用 基础诊断

1. 设数列{a n },{b n }满足a n +1=3a n +2b n ,b n +1=2b n ,且满足?? ????a n +2b n +2=M ?????? a n b n ,则二阶矩阵M =________. 2. 设某校午餐有A,B 两种便当选择,经统计数据显示,今天订A 便当的人,第二天再订A 便当的概率是35;今天订B 便当的人,第二天再订B 便当的概率为4 5,已知星期一有40%的同学订了A 便当,60%的同学订了B 便当,则星期四时订A 便当同学的概率是多少? 范例导航 考向 例1 自然界生物群的成长受到多种条件因素的影响,比如出生率、死亡率、资源的可利用性与竞争、捕食者的猎杀乃至自然灾害等等.因此,它们和周边环境是一种既相生又相克的生存关系.但是,如果没有任何限制,种群也会泛滥成灾.现假设两个互相影响的种群X,Y 随

时间段变化的数量分别为{a n },{b n },有关系式???a n +1=a n +2b n , b n +1=3a n +2b n ,其中a 1=6,b 1=4,试分析20个时 段后,这两个种群的数量变化趋势. 已知矩阵M =?? ????1102,β=???? ?? 31. (1) 求出矩阵M 的特征值和特征向量; (2) 计算M 4β,M 10β,M 100β; (3) 从第(2)小题的计算中,你发现了什么?

考向 例2 某同学做了一个数字信号模拟传送器,经过10个环节,把由数字0,1构成的数字信号由发生端传到接收端.已知每一个环节会把1错转为0的概率为0.3,把0错转为1的概率为0.2,若发出的数字信号中共有10 000个1,5 000个0.问: (1) 从第1个环节转出的信号中0,1各有多少个? (2) 最终接收端收到的信号中0,1个数各是多少?(精确到十位) (3) 该同学为了完善自己的仪器,决定在接收端前加一个修正器,把得到的1和0分别以一定的概率转换为0和1,则概率分别等于多少时,才能在理论上保证最终接收到的0和1的个数与发出的信号相同. 学校餐厅每天供应1 000名学生用餐,每星期一有A,B 两种菜可供选择,调查资料表明,凡是在本周星期一选A 菜的,下周星期一会有20%改选B 菜,而选B 菜的,下周星期一会有30%改选A 菜,若用A n ,B n 分别表示在第n 个星期一选A,B 菜的人数. (1) 若?? ?? ??A n +1B n +1=M ?????? A n B n ,请写出二阶矩阵M ; (2) 若第一周有300人选择A 菜,700人选择B 菜,试判断其变换趋势.

相关文档
最新文档