版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、2011年C+程序课程设计 姓名: 学号:指导老师:提交日期:程序课程设计 迭代法求解线性方程(级) 第 20 页 共 20 页 目录程序设计原理与功能简介2课程设计要求5源程序分析7新程序设计思路10新增模块源代码与功能介绍11程序设计中遇到的问题与解决方法14程序运行测试结果与分析16程序缺陷与大致优化思路20设计心得与个人体会201 程序设计原理与功能简介迭代法是线性方程的一种常用解法,首先选取适当的初值,然后用同样的计算步骤重复计算,在满足精度的情况下,停止迭代,求得近似解。迭代法简介:也称辗转法,是一种不断用变量的旧值递推新值的过程,跟迭代法相对应的是直接法(或者称为一次解法),即一
2、次性解决问题。迭代法又分为精确迭代和近似迭代。“二分法”和“牛顿迭代法”属于近似迭代法。迭代算法是用计算机解决问题的一种基本方法。它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值。最常见的迭代法是牛顿法。其他还包括最速下降法、共轭迭代法、变尺度迭代法、最小二乘法、线性规划、非线性规划、单纯型法、惩罚函数法、斜率投影法、遗传算法、模拟退火等等。 本程序所用的主要为赛德尔迭代法和简单迭代法,分别进行求解,然后将求解的结果参数列出进行比较。还可以选择不同的松弛因子进行算法上的比较。其中新增
3、的部分主要是文本的输入与输出,仿照源程序编写简单迭代法的部分。赛德尔迭代法:设有线性方程:首先将系数矩阵变换成:形式。设上述线性方程组写成:(1)系数矩阵A可逆且主对角元素均不为零,令 并将A分解成 从而(1)可写成 令:其中M=,即:其中:M=这就是原程序所变换的矩阵。赛德尔迭代法的不同之处在于:每算出一个分量的近似值,立即用到下一个分量的计算中去,即用迭代公式:即:选用松弛因子代入上述线性方程得到松弛的赛德尔公式:通常在(0,2)内选取,当>1,成为超松弛,当<1时,成为亚松弛。松弛因子的恰当选择,可以大大提高收敛速度,(经查资料,可以证明利用赛德尔法计算方程,收敛则方程组有解
4、,且收敛充分条件有多个,在此不一一例举),在实际计算中,往往要靠经验找到最优松弛因子。一般迭代法:由赛德尔迭代法与一般迭代法比较可知,在迭代的每一步计算过程中一般迭代法是用的全部分量来计算的所有分量,显然在计算第i个分量时,已经计算出的最新分量没有被利用,从直观上看,最新计算出的分量可能比旧的分量要好些.因此,对这些最新计算出来的第次近似的分量加以利用,就得到所谓解方程组的高斯塞德(Gauss-Seidel)迭代法.下面就用程序来验证这一点。二课程设计要求1. 重载类的构造函数,可以在定义类的对象时利用函数参数输入方程的各项参数,便于程序调试。2. 增加类的成员函数,可以将一个线性方程用文本文
5、件的编辑器(如记事本)写入一个文件中,然后由新增的成员函数中读取,运行结束后写回文件中。3. 原程序是高斯-赛德尔算法解线性方程,仿照源程序编写简单迭代法求解线性方程的程序,并利用相同方程组与塞德尔算法进行验证比较,分别求出他们的收敛次数。4. 设计并对主程序进行测试:本次测试所选线性方程组为:一般迭代法的大致运算: 0 1 2 3 4 5 600.71.421.7832.03382.182300.81.491.8622.11012.259402.43.183.8764.24624.4948赛德尔迭代法大致运算: 0 1 2 3 4 5 600.71.67261.93372.14162.327
6、101.011.97141.92242.30742.433003.3482.71164.32474.67434.81183 源程序分析源程序首先定义了一个类。在这个类中,先定义了两个友元函数,分别重载输出与输入运算符。后又定义了一些对象,包括矩阵行列数,方程解的个数,存放方程的解,迭代次数,松弛因子。也定义了几个成员函数,包括误差函数,构造函数,输入行列数,变换矩阵函数,主要算法部分,输出最后结果的函数。构造函数的作用是为行列数分配内存空间,是动态生成的。输入行列数要求用户自己输入,来初始化行列数。变换矩阵要求将原矩阵作出的变换是:实对角线上的系数为0,每一行的其他数都是原数除以原每一行第一个
7、数的相反数。然后是进行一轮迭代,参数是松弛因子,求出最新的迭代解,每求出的一个新解都立即用到下一个分量的计算中去,继续迭代,直到满足解的精度才停止迭代,最后输出函数结果。源程序代码:源程序头文件部分# include<iostream.h># include<math.h># include<conio.h># include<iomanip.h>(源程序主要由类和类的声明构成)class Matrix /高斯-赛德尔矩阵乘法类friend void operator<<(ostream &,Matrix &); /重
8、载输出运算符friend void operator>>(istream &,Matrix &); /重载输入运算符protected:int row,column; /矩阵行列数double * * mat; /矩阵int varnum; /方程解的个数double * variable; /存放方程解int itercount; /迭代次数void iteration(double); /迭代算法,参数是松弛因子bool epsilon(double *,double *,int,double); /误差函数public:Matrix(int,int); /构造
9、函数static void initialize(int &,int &); /要求用户输入行列数void rearrange(); /变换矩阵void solve(double); /主要算法部分,参数是松弛因子void show_answer(); /输出最后结果;(动态生成方程系数的数组)Matrix:Matrix(int r=1,int c=1):row(r),column(c) mat=new double * row; /动态生成for(int i=0;i<row;i+) mati=new doublecolumn;(输入行列数,确定线性方程的大小)void
10、Matrix:initialize(int &i,int &j) /*初始化,输入行列(ROWS:线性方程数,COLUNMNS:系数)及常数的个数*/ cout<<"How many ROWS?>"cin>>i;cout<<"How many COLUMNS?>"cin>>j;(将矩阵转化为求解形式)void Matrix:rearrange() /高斯-赛德尔矩阵变换函数,在进行迭代之前需将原矩阵做变换 varnum=column-1; /方程解的个数 variable=new
11、 doublevarnum; /存放方程解 for(int i=0;i<row;i+) double coefficient=matii; /对角线上的系数 for(int j=0;j<column;j+) matij/=coefficient; /实对角线上的系数为1 for(i=0;i<row;i+) for(int j=0;j<column-1;j+) matij*=-1; /变换 matii=0; /对角线上的系数为0 (利用松弛因子进行迭代求解)void Matrix:iteration(double lambda) /进行一轮迭代,参数为松弛因子 doubl
12、e last; /为最新求出的迭代解 for(int i=0;i<varnum;i+) last=variablei; variablei=0; /最新的方程解,i为行次,求xi for(int j=0;j<varnum;j+) variablei+=matij*variablej; /*根据已解出的x0,x1,x2,x(i-1)的最新值求xi*/ variablei+=maticolumn-1; /加上常数项系数 variablei=last+lambda*(variablei-last); /利用松弛因子调整收敛速度 (明示精度要求,进行新解和旧解的转换和保存,如不满足要求返回
13、上一级继续迭代)void Matrix:solve(double lambda)/求解方程 for(int i=0;i<varnum;i+)variablei=0;itercount=0;double criterion=0.0001;/迭代误差double *newest=new doublevarnum;double *last=new doublevarnum;for(i=0;i<varnum;i+)newesti=variablei;dofor(int i=0;i<varnum;i+)lasti=newesti;/保存前一轮的解,计算误差用iteration(lamb
14、da);/一轮迭代for(i=0;i<varnum;i+)newesti=variablei;/保存新一轮的解itercount+;/整个迭代次数加1while(epsilon(newest,last,varnum,criterion);/计算误差/计算迭代误差,看是否满足解得精度,返回0停止迭代,给出最后结果(精度验证,不满足则继续迭代)bool Matrix:epsilon(double*newest,double*last,int size,double criterion)for(int i=0;i<size;i+)if(fabs(newesti-lasti)/newest
15、i)>criterion)/如果不满足精度return 1;/继续迭代return 0;(输出求解结果)void Matrix:show_answer()/输出求解结果函数for(int i=0;i<varnum;i+)cout<<"X"<<(i+1)<<"="<<variablei<<endl;cout<<endl<<endl<<"Number of Iteration="<<itercount<<en
16、dl;void operator<<(ostream&out,Matrix&m) /矩阵输入,输出流重载函数for(int i=0;i<m.row;i+)for(int j=0;j<m.column;j+)out<<m.matij<<setw(10);out<<endl<<endl;void operator>>(istream&in,Matrix&m) for(int i=0;i<m.row;i+)for(int j=0;j<m.column;j+)cout<
17、<"value of indice"<<(i+1)<<""<<(j+1)<<""in>>m.matij;主函数的部分void main()cout<<"This Program Solve linear by the Gauss-Seigel Methoa"<<endl<<"Try to input the Matrix so that there is Diagonal Dominance"&
18、lt;<endl<<endl;int i,j;Matrix:initialize(i,j);Matrix one(i,j);cin>>one;char X;cout<<"Do you want to see the Matrix?:(y/n)>"cin>>X;if(X='y')cout<<one;one.rearrange();double relax_coaf;for(char x='y'x='y'&&x!='n')cou
19、t<<endl<<"Relaxation Coefficient(1=no relaxation):>"cin>>relax_coaf;one.solve(relax_coaf);one.show_answer();cout<<endl<<"try another Relaxation Coafficient?:(y/n)>"cin>>x;cin.ignore(128,'n');cin.ignore(128,'n'); 4 新程序设计思路由
20、于源程序的内容比较详细全面,所以新程序的内容不多,只需在原类中添加两个成员函数,还有将主函数适当修改一下即可。添加的两个类的成员函数的功能分别是读取文本文件中内容和将结果保存在文本文件中。由于文本文件中是线性方程的初始形式,即a11*x+a12*x+a13*x=b的形式。所以要将它们读取出来是比较困难的事情。这也是这个程序的难点之一。首先应将它们以字符的形式读取出来,然后将前面的系数识别出来,送入到原类的矩阵中去,进行矩阵变换。然后将运行结果存入到另一个文本文件中去。这将采用文件的输入与输出功能来解决这个问题。至于主函数的修改,也是一个重点。主函数将采取菜单的模式,让用户选择输入方程组的方式,
21、同一个方程组用两种方法进行计算求解,即定义两个对象(赛德尔迭代法和简单迭代法),分别进行求解,然后将求解的结果参数列出进行比较。如果希望作进一步研究,还可以选择不同的松弛因子进行算法上的比较,得出一个比较完善的结论。5 新增模块源代码与功能介绍新增的模块主要有两个:一个模块的功能是读取一个文本文件。除了读取外,还要将线性方程未知数前面的系数识别出来,然后送入原类的矩阵中去,进行矩阵变换。另一个模块的功能是将运行的结果存入这个文本文件里去。这两个模块如下:算法类中添加两个函数:void Read(int ,int );/新增函数:读取文件中方程组的系数void Write();/新增函数:将计算
22、结果写入文件中两个函数具体函数体内容:读取文件内容函数void matrix:Read(int r,int c)ifstream infile;infile.open("d:线性方程组.txt");/读取文件char a;for(int h=0;h<r;h+)for(int g=0;g<c;g+)mathg=0;char temple1000;/利用中间变量剔除某些字符int t=0;int i=0,j,k=0;while(infile.get(a)/读取方程组系数矩阵templet+=a;if(a>=48&&a<=57&&a
23、mp;templet-2!=120)/当字符是数字且前一个不是“x”时matki*=10;j=a-48;matki+=j;if(templet-2=45)matki=-matki;/读取负数else if(a>=64)i+;else if(a='n')k+;i=0;infile.close();写入文件内容函数void matrix:Write()ofstream outfile;outfile.open("d:赛德尔迭代法的解.txt");for(int i=0;i<varnum;i+)outfile<<"x"&
24、lt;<(i+1)<<"="<<variablei<<endl;outfile.close();多项选择性的设计虽然程序中采用的是从文件中提取线性方程组,即算法中新增的read读入函数,但本程序还设计了另外的方程组系数输入方法,即人工按方程组系数矩阵的排列逐个输入。源代码即在重载输入运算符时添加了选择语句,由用户选择输入方式,源代码如下:void operator>>(istream& in,matrix& m)cout<<"请选择输入线性方程组系数的方式:"<<
25、;endl;cout<<"1、从D盘文本文档中提取系数(注意:文档中的系数为1或-1时要添上)"<<endl;cout<<"2、手动输入系数(注意:按照系数矩阵的顺序输入)"<<endl;int choice;cin>>choice;switch(choice)case 1:for(int i=0;i<m.row;i+)for(int j=0;j<m.column;j+)cout<<"value of indice"<<(i+1)<&
26、lt;""<<(j+1)<<""<<m.matij<<endl;break;case 2:for(int i=0;i<m.row;i+)for(int j=0;j<m.column;j+)cout<<"value of indice"<<(i+1)<<""<<(j+1)<<""in>>m.matij;break;6 程序设计中遇到的问题与解决方法1).最大的困难当属
27、对于如何从文件中将线性方程组的系数与常数读入程序中,这个方面主要是从文件中如何读取字符串,并从字符串中将系数和常数读取出来,然后将字符型转化成数字。从上面的读取文件函数设计中已经知道所用的方法,这主要是查找资料所得:参考程序1:# include<fstream># include<iostream>using namespace std;int main()ofstream ofile;ofile.open("d:my.doc");ofile<<"3x+8y=11"<<'n'<<
28、;"2x+3y=5"<<endl;ofile.close();ifstream ifile;ifile.open("d:my.doc");char a;int s100100;for(int h=0;h<100;h+) for(int g=0;g<100;g+) shg=0;int i=0,j,k=0;while(ifile.get(a)if(a>=48&&a<=57)ski*=10;j=a-48;ski+=j;else if(a>=64) i+;else if(a='n') k+
29、;cout<<s00<<endl<<s10<<endl;ifile.close();return 0;参考程序2:#include <stdio.h>#include <string.h>void main(void) FILE *fp = fopen("D:1.txt", "r"); int nChar; int i = 0; char buf64; float a, b; int n; while (nChar = fgetc(fp) != EOF)/EOF=end of fil
30、e bufi+ = (char)nChar; if (nChar = 'n') bufi = 0; i = 0; sscanf(buf, "第%d点坐标: x=%f y=%f", &n, &a, &b); printf("%ft%fn", a, b); fclose(fp);但第一段程序只针对于正整数,对于负数和系数为1时没有具体的设计,因此有较大的局限性,本想通过第二段程序中的方式将数字读入源程序的,但运行效果不佳,且有许多陌生的程序代码,如FIFE类型的数据处理等,但经过参考此段代码,结合学过的内容,经过个人修
31、改,在源文件中的添加了一些条件,使得程序运行环境更完善,运行效果更好。2).在不断完善程序的过程中,还遇到许多小问题,比如还是线性方程组系数的写入问题,小数问题还没有解决,即如何从文本中将小数的系数或常数读入程序中,于是,在此,提供了两种写入系数的方式,一种即上述的文件写入,另一种即按照系数矩阵的顺序输入系数与常数,这样,只要采用后一种方法,小数的问题也可以解决了。3).在程序不断运行和调试中,还遇到一些小问题,但都在调试中解决了,主要是语法错误。7 程序运行测试结果和分析程序中主要的示例线性方程为:运行结果:1.D盘文件中输入线性方程组:2.赛德尔迭代法:选择赛德尔迭代法,并输入系数矩阵的行数与列数,而后从文本文档中提取系数:将所有系数以矩阵形式展示出
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 成品质量检验准则
- 某汽车零部件厂工艺执行细则
- 通风空调系统调试报告
- 2026滨海银行面试题目及答案
- 2026编制岗位面试题库及答案
- 屋面-找平层技术交底
- 2026年元宇宙经济系统的跨链资产流通方案
- 复变函数与积分变换 第2版5.1孤立奇点
- 2026年中国包装行业发展现状、市场前景、投资方向分析报告(智研咨询发布)
- 2025年海岛生态旅游案例方案
- 江苏省2026中考作文深度预测专版
- 5.中国的农业(2026-2027高中二年级·中国区域地理专题复习讲义)
- 人教版小学五年级数学下册折线统计图《复式折线统计图》示范教学课件
- (2025版)AHA心肺复苏与心血管急救指南解读课件
- 2025内蒙古乌海市国创数字产业发展有限责任公司招聘和考察更正笔试历年参考题库附带答案详解
- 黑龙江哈尔滨市2026届高考第一次模拟考试数学试题+答案
- 2026年安徽省合肥市高三二模英语试题(含答案和音频)
- 2026年传播与策划考试试题及答案答案
- 2026年贵州省毕节市初二地理生物会考真题试卷+解析及答案
- 小学劝返复学工作制度
- 2026年部编版五年级语文下册金句仿写
评论
0/150
提交评论