分析用下列迭代法解线性方程组
4 -1 0 -1 0 0 0
-1 4 -1 0 -1 0 5
0 -1 4 -1 0 -1 -2
-1 0 -1 4 -1 0 5
0 -1 0 -1 4 -1 -2
0 0 -1 0 -1 4 6
的收敛性,并求出使||Xk+1-Xk||2<=0.0001的近似解及相应的迭代次数.
(1) 雅可比迭代法;
(2) 高斯—赛德尔迭代法;
(3) SOR迭代法(w依次取1.334,1.95,0.95)
数值计算方法的作业,要把这三个迭代法用编程实现一下,于是我就照着书上的公式敲了一下,功能基本实现了。
测试数据:
input:
6
4 -1 0 -1 0 0
-1 4 -1 0 -1 0
0 -1 4 -1 0 -1
-1 0 -1 4 -1 0
0 -1 0 -1 4 -1
0 0 -1 0 -1 4
0 5 -2 5 -2 6
x的初值随便赋。
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <iomanip>
using namespace std;
typedef long long LL;
const int INF=0x7fffffff;
const int MAXN=1000;
const double wucha=0.0001;
const int MAX_count=500;
double A[MAXN][MAXN];
double b[MAXN];
double curx[MAXN];
double lastx[MAXN];
int N,Count;
double W;
void init(){
printf("输入未知数个数:");
cin>>N;
printf("输入方程组矩阵A:\n");
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
cin>>A[i][j];
}
}
printf("输入b向量:\n");
for(int i=1;i<=N;i++){
cin>>b[i];
}
cout<<endl;
}
void initx(){
// memset(curx,-1,sizeof(curx));
cout<<"请对x赋初值:"<<endl;
for(int i=1;i<=N;i++){
cin>>curx[i];
}
}
bool judge(){
double sum=0;
for(int i=1;i<=N;i++){
sum+=(curx[i]-lastx[i])*(curx[i]-lastx[i]);
}
sum=sqrt(sum);
if(sum<=wucha)return 1;
else return 0;
}
void shuchux(){
cout<<"迭代次数为:"<<Count<<endl;
cout<<"近似解为:";
for(int i=1;i<=N;i++){
cout<<curx[i]<<" ";
}
cout<<endl<<endl;
}
void Jacobi(){//x初值都设置为0
cout<<"雅可比迭代法:"<<endl;
initx();
int flag=0;
double sum;
for(int k=1;k<MAX_count;k++){
for(int i=1;i<=N;i++){
lastx[i]=curx[i];
}
for(int i=1;i<=N;i++){
sum=0;
for(int j=1;j<=N;j++){
if(i==j)continue;
sum+=A[i][j]*lastx[j];
}
curx[i]=(b[i]-sum)/A[i][i];
}
if(judge()){
flag=1;
Count=k;
shuchux();
break;
}
}
if(flag==0)cout<<"error!"<<endl<<endl;
}
void gaisi_saideer(){
cout<<"高斯—赛德尔迭代法:"<<endl;
initx();
int flag=0;
double sum;
double t;
for(int k=1;k<MAX_count;k++){
double e=0;
for(int i=1;i<=N;i++){
t=curx[i];
sum=0;
for(int j=1;j<=N;j++){
if(i==j)continue;
sum+=A[i][j]*curx[j];
}
curx[i]=(b[i]-sum)/A[i][i];
if(fabs(curx[i]-t)<=e){}
else {
e=fabs(curx[i]-t);
}
}
if(e<wucha){
flag=1;
Count=k;
shuchux();
break;
}
}
if(flag==0)cout<<"error!"<<endl<<endl;
}
void SOR(){
cout<<"逐次超松弛迭代法(SOR):"<<endl;
initx();
cout<<"输入松弛因子W:"<<endl;
cin>>W;
int flag=0;
double sum1,sum2;
for(int k=1;k<MAX_count;k++){
for(int i=1;i<=N;i++){
lastx[i]=curx[i];
if(k==1)curx[i]=0;
}
for(int i=1;i<=N;i++){
sum1=0,sum2=0;
for(int j=1;j<=i-1;j++){
sum1+=A[i][j]*curx[j];
// cout<<curx[j]<<" ";
}
// cout<<endl;
for(int j=i;j<=N;j++){
sum2+=A[i][j]*lastx[j];
}
curx[i]=(b[i]-sum1-sum2)*W/A[i][i]+lastx[i];
}
if(judge()){
flag=1;
Count=k;
shuchux();
break;
}
}
if(flag==0)cout<<"error!"<<endl<<endl;
}
int main(){
while(1){
init();
Jacobi();
gaisi_saideer();
SOR();
SOR();
SOR();
}
return 0;
}