數值計算—高斯賽德爾法解線性方程組(附代碼)

1.高斯賽德爾迭代法的計算過程:

(1).取初始向量:

                                                 x^{(0)}=(x_{1}^{(0)},x_{2}^{(0)},\cdots ,x_{n}^{(0)})^{T}                                       (1)

(2).迭代過程

                           \left\{\begin{matrix} x_{1}^{(k+1)}=\frac{1}{a_{11}}\left ( -a_{12}x_{2}^{(k)}-\cdots -a_{1n}x_{n}^{(k)}+b_{1}\right )\\ x_{2}^{(k+1)}=\frac{1}{a_{22}}\left ( -a_{21}x_{1}^{(k+1)}-\cdots -a_{2n}x_{n}^{(k)}+b_{2}\right )\\ \vdots \\ x_{n}^{(k+1)}=\frac{1}{a_{nn}}\left ( -a_{n1}x_{1}^{(k+1)}-\cdots -a_{nn-1}x_{n-1}^{(k+1)}+b_{n}\right ) \end{matrix}\right.                   (2)

2.求解實例:

                                  \begin{bmatrix} 3 & -1 & & & \\ -1 & 3 & -1 & & \\ & \ddots & \ddots & \ddots & \\ & & -1& 3& -1\\ & & & -1 &3 \end{bmatrix}\begin{bmatrix} x_{1}\\ x_{2} \\ \vdots \\ x_{n-1} \\ x_{n} \end{bmatrix}=\begin{bmatrix} 2\\ 1\\ \vdots \\ 1 \\ 2 \end{bmatrix}                                (3)

用 Gauss-Seidel  方法求解,精確到小數點後 6 位,  給出所需步數及殘差\left \| b-Ax \right \|_{\infty };

3.求解結果:

當n=100時,x1...xn=1,所需步數14,殘差0.00006163

4.C++程序源代碼:

//高斯賽德爾迭代法,解線性方程組,高等數值計算
//開發人員:chenshuai  開發日期:2019.11.5  郵箱:[email protected] 
#include "pch.h"
#include <iostream>
using namespace std;
#include <iomanip> //參數化輸入/輸出 
#include <vector>
#define  n  100    //矩陣大小
#define  epsilon  0.000001   //精度
vector<double> Gauss_seidel(vector<vector<double>>a, vector<double>b, vector<double>x_new);//申明高斯賽德爾迭代方法求解函數
vector<double> Gauss_seidel(vector<vector<double>>a, vector<double>b, vector<double>x_new)
{
	int num = size(b), n_cishu = 0;
	double sum = 0, max_precision = 0;;
	vector<double>x_old(num);
	do
	{
		n_cishu++;
		for (int j = 0; j < num; j++)
		{
			x_old[j] = x_new[j];
		}
		for (int j = 0; j < num; j++)
		{
			sum = 0;
			for (int k = 0; k < num; k++)
			{
				if (j != k)
				{
					sum = sum - a[j][k] * x_old[k];
				}
			}
			x_new[j] = (sum + b[j]) / a[j][j];
			max_precision = 0;   
			for (int i = 0; i < num; i++)
			{
				sum = fabs(x_new[i] - x_old[i]);
				if (sum > max_precision)
				{
					max_precision = sum;
				}
			}
			x_old[j] = x_new[j];
		}
	} while (max_precision > epsilon);
	//殘差計算
	double max_residual = 0;
	for (int i = 0; i < num; i++)
	{
		sum = b[i];
		for (int j = 0; j < num; j++)
		{
			sum = sum - a[i][j] * x_new[j];
		}
		if (sum > max_residual)
		{
			max_residual = sum;
		}
	}
	cout << "所需步數:" << n_cishu << "殘差:" << fixed << setprecision(8) << setw(10) << max_residual << endl;
	return x_new;
}
int main()
{
	vector<vector<double>>a;
	a.resize(n, vector<double>(n));//定義線性方程組係數矩陣A
	vector<double>b(n);  //定義線性方程組右邊列向量B
	vector<double>x(n);  //初始化向量
	a[0][0] = 3, a[0][1] = -1, b[0] = 2;
	for (int i = 1; i < n - 1; i++)
	{
		a[i][i - 1] = -1;
		a[i][i] = 3;
		a[i][i + 1] = -1;
		b[i] = 1;
	}
	a[n - 1][n - 2] = -1; a[n - 1][n - 1] = 3, b[n - 1] = 2;
	x = Gauss_seidel(a, b, x);
	
}

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章