分享
 
 
 

雅可比(Jacobi)迭代算法的C++实现

王朝c/c++·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

/*

-----------------------------------------------

假设有如下方程组:

Ax=b

用Jacobi迭代法求解方程组的解

方法:将A分裂为A=D-L-U,等价的迭代方程组为x=Bx+f。

有关算法的详细说明,参看http://www.loujing.com/mywork/c++/project/Jacobi.pdf

-----------------------------------------------

*/

#include <iostream.h>

#include <stdlib.h>

#include <math.h>

double* allocMem(int ); //分配内存空间函数

void GaussLineMain(double*,double*,double*,int );//采用高斯列主元素消去法求解x的初始向量值

void Jacobi(double*,double*,double*,double*,int,int);//利用雅可比迭代公式求解x的值

void main()

{

short matrixNum; //矩阵的行数(列数)

double *matrixA; //矩阵A,初始系数矩阵

double *matrixD; //矩阵D为A中的主对角阵

double *matrixL; //矩阵L为A中的下三角阵

double *matrixU; //矩阵U为A中的上三角阵

double *B; //矩阵B为雅可比方法迭代矩阵

double *f; //矩阵f为中间的过渡的矩阵

double *x; //x为一维数组,存放结果

double *xk; //xk为一维数组,用来在迭代中使用

double *b; //b为一维数组,存放方程组右边系数

int i,j,k;

cout<<"<<请输入矩阵的行数(列数与行数一致)>>:";

cin>>matrixNum;

//分别为A、D、L、U、B、f、x、b分配内存空间

matrixA=allocMem(matrixNum*matrixNum);

matrixD=allocMem(matrixNum*matrixNum);

matrixL=allocMem(matrixNum*matrixNum);

matrixU=allocMem(matrixNum*matrixNum);

B=allocMem(matrixNum*matrixNum);

f=allocMem(matrixNum);

x=allocMem(matrixNum);

xk=allocMem(matrixNum);

b=allocMem(matrixNum);

//输入系数矩阵各元素值

cout<<endl<<endl<<endl<<"<<请输入矩阵中各元素值(为 "<<matrixNum<<"*"

<<matrixNum<<",共计 "<<matrixNum*matrixNum<<" 个元素)"<<">>:"<<endl<<endl;

for(i=0;i<matrixNum;i++)

{

cout<<"请输入矩阵中第 "<<i+1<<" 行的 "<<matrixNum<<" 个元素:";

for(j=0;j<matrixNum;j++)

cin>>*(matrixA+i*matrixNum+j);

}

//输入方程组右边系数b的各元素值

cout<<endl<<endl<<endl<<"<<请输入方程组右边系数各元素值,共计 "<<matrixNum<<

" 个"<<">>:"<<endl<<endl;

for(i=0;i<matrixNum;i++)

cin>>*(b+i);

/* 下面将A分裂为A=D-L-U */

//首先将D、L、U做初始化工作

for(i=0;i<matrixNum;i++)

for(j=0;j<matrixNum;j++)

*(matrixD+i*matrixNum+j)=*(matrixL+i*matrixNum+j)=*(matrixU+i*matrixNum+j)=0;

//D、L、U分别得到A的主对角线、下三角和上三角;其中D取逆矩阵、L和U各元素取相反数

for(i=0;i<matrixNum;i++)

for(j=0;j<matrixNum;j++)

if(i==j&&*(matrixA+i*matrixNum+j)) *(matrixD+i*matrixNum+j)=1/(*(matrixA+i*matrixNum+j));

else if(i>j) *(matrixL+i*matrixNum+j)=-*(matrixA+i*matrixNum+j);

else *(matrixU+i*matrixNum+j)=-*(matrixA+i*matrixNum+j);

//求B矩阵中的元素

for(i=0;i<matrixNum;i++)

for(j=0;j<matrixNum;j++)

{

double temp=0;

for(k=0;k<matrixNum;k++)

temp+=*(matrixD+i*matrixNum+k)*(*(matrixL+k*matrixNum+j)+*(matrixU+k*matrixNum+j));

*(B+i*matrixNum+j)=temp;

}

//求f中的元素

for(i=0;i<matrixNum;i++)

{

double temp=0;

for(j=0;j<matrixNum;j++)

temp+=*(matrixD+i*matrixNum+j)*(*(b+j));

*(f+i)=temp;

}

/* 计算x的初始向量值 */

GaussLineMain(matrixA,x,b,matrixNum);

/* 利用雅可比迭代公式求解xk的值 */

int JacobiTime;

cout<<endl<<endl<<endl<<"<<雅可比迭代开始,请输入希望迭代的次数>>:";

cin>>JacobiTime;

while(JacobiTime<=0)

{

cout<<"迭代次数必须大于0,请重新输入:";

cin>>JacobiTime;

}

Jacobi(x,xk,B,f,matrixNum,JacobiTime);

//输出线性方程组的解 */

cout<<endl<<endl<<endl<<"<<方程组运算结果如下>>"<<endl;

cout.precision(20); //设置输出精度,以此比较不同迭代次数的结果

for(i=0;i<matrixNum;i++)

cout<<"x"<<i+1<<" = "<<*(xk+i)<<endl;

cout<<endl<<endl<<"求解过程结束..."<<endl<<endl;

//释放掉所有动态分配的内存

delete [] matrixA;

delete [] matrixD;

delete [] matrixL;

delete [] matrixU;

delete [] B;

delete [] f;

delete [] x;

delete [] xk;

delete [] b;

}

/*

----------------------

分配内存空间函数

----------------------

*/

double* allocMem(int num)

{

double *head;

if((head=new double[num])==NULL)

{

cout<<"内存空间分配失败,程序终止运行!"<<endl;

exit(0);

}

return head;

}

/*

-----------------------------------------------

计算Ax=b中x的初始向量值,采用高斯列主元素消去法

-----------------------------------------------

*/

void GaussLineMain(double* A,double* x,double* b,int num)

{

int i,j,k;

//共处理num-1行

for(i=0;i<num-1;i++)

{

//首先每列选主元,即最大的一个

double lineMax=fabs(*(A+i*num+i));

int lineI=i;

for(j=i;j<num;j++)

if(fabs(*(A+j*num+i))>fabs(lineMax)) lineI=j;

//主元所在行和当前处理行做行交换,右系数b也随之交换

for(j=i;j<num;j++)

{

//A做交换

lineMax=*(A+i*num+j);

*(A+i*num+j)=*(A+lineI*num+j);

*(A+lineI*num+j)=lineMax;

//b中对应元素做交换

lineMax=*(b+i);

*(b+i)=*(b+lineI);

*(b+lineI)=lineMax;

}

if(*(A+i*num+i)==0) continue; //如果当前主元为0,本次循环结束

//将A变为上三角矩阵,同样b也随之变换

for(j=i+1;j<num;j++)

{

double temp=-*(A+j*num+i)/(*(A+i*num+i));

for(k=i;k<num;k++)

{

*(A+j*num+k)+=temp*(*(A+i*num+k));

}

*(b+j)+=temp*(*(b+i));

}

}

/* 验证Ax=b是否有唯一解,就是验证A的行列式是否为0;

如果|A|!=0,说明有唯一解

*/

double determinantA=1;

for(i=0;i<num;i++)

determinantA*=*(A+i*num+i);

if(determinantA==0)

{

cout<<endl<<endl<<"通过计算,矩阵A的行列式为|A|=0,即A没有唯一解。\n程序退出..."<<endl<<endl;

exit(0);

}

/* 从最后一行开始,回代求解x的初始向量值 */

for(i=num-1;i>=0;i--)

{

for(j=num-1;j>i;j--)

*(b+i)-=*(A+i*num+j)*(*(x+j));

*(x+i)=*(b+i)/(*(A+i*num+i));

}

}

/*

--------------------------------------

利用雅可比迭代公式求解x的精确值

迭代公式为:xk=Bx+f

--------------------------------------

*/

void Jacobi(double* x,double* xk,double* B,double* f,int num,int time)

{

int t=1,i,j;

while(t<=time)

{

for(i=0;i<num;i++)

{

double temp=0;

for(j=0;j<num;j++)

temp+=*(B+i*num+j)*(*(x+j));

*(xk+i)=temp+*(f+i);

}

//将xk赋值给x,准备下一次迭代

for(i=0;i<num;i++)

*(x+i)=*(xk+i);

t++;

}

}

//程序编写结束

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有